I need to cleanup my rushes/footages directories, so I'd like to be able to list, in command line, all the files referenced in a .blend file. I need to be able to, for every file found in a given directory, check if it is used in a particular .blend file.
2 Answers
Here is Python which examines the files in the Visual Sequence Editor VSE of Blender.
import bpy
import datetime
def time_stamp():
print("-" * 88)
print(datetime.datetime.now())
print("-" * 88)
def inspect_v_strips(simple_sleek):
filtername = "ring"
for s in bpy.data.scenes:
#if (isinstance(s.sequence_editor, bpy.types.SequenceEditor) and hasattr(s.sequence_editor,'sequences')):
if hasattr(s.sequence_editor,'sequences') and (s.name.find(filtername) > 0):
print("Using filtername[", filtername, "] .... Remove or adjust the filter in python above")
print("Scene", s.name, "-" * 88)
#for m in bpy.context.sequences:
for m in s.sequence_editor.sequences:
if isinstance(m, bpy.types.MovieSequence):
print(m.name, m.filepath, m.type)
elif isinstance(m, bpy.types.ImageSequence):
print(m.name, m.directory, m.elements[0].filename, "Length:" + str(len(m.elements)), m.type)
else:
print(m.type, "More software to be written for other types")
def test333():
time_stamp()
inspect_v_strips(False)
time_stamp()
test333()
The output in the console window was filtered to make it smaller and more readable for your question. In the python above the software inspects scenes which have the names which contain a string "ring". Of course you can delete that part of the test. You may delete ......
[and (s.name.find(filtername) > 0)]
You could use http://web.purplefrog.com/~thoth/blender/python-cookbook/list-referenced-files.html as a starting point:
import bpy
import os
def debug_print(msg):
print(msg)
def list_referenced_images():
rval = set()
for img in bpy.data.images:
if img.filepath is not None:
debug_print ("IMAGE %s"%img.filepath)
rval.add(bpy.path.abspath(img.filepath))
return rval
def paths_for_vse_strip(strip):
if hasattr(strip, "filepath"):
return [ strip.filepath ]
if hasattr(strip, "directory"):
return [ strip.directory+elt.filename for elt in strip.elements ]
return []
def list_vse_references():
rval = set()
for scn in bpy.data.scenes:
if scn.sequence_editor is not None:
for strip in scn.sequence_editor.sequences_all:
for path in paths_for_vse_strip(strip):
debug_print("VSE %s"%path)
rval.add(bpy.path.abspath(path))
return rval
def file_is_used(f, used):
if f in used:
return True
# OMG, windows. WTF?
for f2 in used:
if os.path.samefile(f2, f):
return True
return False
def mission1():
used = set()
used.update( list_referenced_images() )
used.update( list_vse_references() )
dir = "/var/tmp/blender"
for f in sorted(os.listdir(dir)):
f2 = os.path.join(dir, f)
if file_is_used(f2, used):
print("USED\t%s"%f2)
else:
print("UNUSED\t%s"%f2)
mission1()
There is a good chance there are other external references somewhere in the data model, but those were the two that popped into my head (images and VSE).
-
$\begingroup$ Fantastic, truly. Paste it in the text editor, hit Alt+P, then look in the console, it's all there, thanks! $\endgroup$– yPhilCommented Jun 16, 2016 at 18:42
-
$\begingroup$ Aaarg, I just deleted a referenced file. The script listed it as UNUSED, when it clearly was. All false negatives were lowersase-named mkv files. Sorry, I have to un-accept the answer. $\endgroup$– yPhilCommented Jun 17, 2016 at 13:52
-
1$\begingroup$ Crud,. I'm used to Unix where file names are case sensitive. I'm posting an untested variant that might solve the problem. (I can't test it because I don't have a suitable Windows environment). $\endgroup$ Commented Jun 17, 2016 at 15:38
-
$\begingroup$ but... I' am using Linux (what else? :p) This is what I have now gist.github.com/xaccrocheur/943477953fc27e80b84eddb3c58f1a0d I'm sure we'll figure it out :) $\endgroup$– yPhilCommented Jun 17, 2016 at 18:42
-
$\begingroup$ That is different enough from my code sample that I have no idea what could be going wrong. And it REALLY confuses me that blender running on linux would accept a file name that did not match the one in the filesystem. $\endgroup$ Commented Jun 17, 2016 at 20:21