I would like to run the following script via command-line and no gui:

import bpy
import os

# switch on nodes
scene = bpy.context.scene
scene.node_tree.nodes.active = scene.node_tree.nodes['Composite']
scene.render.use_compositing = True
tree = bpy.context.scene.node_tree

# assign a color
bg_col = [1.0,0.0,0.0,1.0]

# change value
bpy.data.scenes['Scene'].node_tree.nodes["color-background"].outputs[0].default_value = bg_col
print("new background color set to "+ str(bg_col))

# ----- LOAD IMAGE -----
filepath = bpy.data.filepath
directory = os.path.dirname(filepath)

# Load a new image
mat = bpy.data.materials['LogoMaterial']
nodes = mat.node_tree.nodes
material_output = nodes.get("Material Output")

logo_texture = nodes["logo-texture"]
#load new logo texture
logo_texture.image = bpy.data.images.load(directory+"/tex//logo-2k.png", check_existing=True)
print("new logo texture added")

#create a sequence editor
if not scene.sequence_editor:

#clear the VSE, then add an audio file
my_context = bpy.context.area.type
my_context = 'SEQUENCE_EDITOR'
bpy.ops.sequencer.sound_strip_add(filepath="//audio/0A1.wav", files=[{"name":"0A1.wav", "name":"0A1.wav"}], relative_path=True, frame_start=1, channel=1)
print("loaded new sound")
my_context = 'TEXT_EDITOR'

If it is necessary, how would I go about converting it to only using bpy.data instead of bpy.context and bpy.ops?

Below is a part where I try to replace an audio file in the Video Sequence Editor just using bpy.data, however it only removes the audio datablock, loads a new audio, but does not associate the audio to the audiostrip in the VSE timeline.

if "0A1.wav" in bpy.data.sounds:
    sound = bpy.data.sounds["0A1.wav"]
    print("removing sound ", sound)
    print("loading new sound ", sound)
  • $\begingroup$ So what result does it produce? $\endgroup$ Commented Nov 2, 2017 at 14:52
  • $\begingroup$ I have a feeling that what you want to do is use scene.sequence_editor.sequences.new_sound(name, filpath, channel, frame_start) to add a soundstrip, and to change sound for that strip set scene.sequence_editor.sequences_all['goober.wav'].sound to your newly loaded sound. As it is you are just loading a new sound and not assoc it with a strip. $\endgroup$
    – batFINGER
    Commented Nov 2, 2017 at 15:10
  • $\begingroup$ adding a soundfile with scene.sequence_editor.sequences.new_sound(name, filpath, channel, frame_start) works, but the fundamental question remains if this still works when rendering without gui on the command-line. The second code in my question was an attempt to do the same thing with bpy.data - I did not find anything how to associate the strip with the loaded audio... $\endgroup$
    – anf
    Commented Nov 2, 2017 at 15:36
  • $\begingroup$ @RayMairlot The bpy.data.sounds.remove(sound) of the second code part works, the audio strip gets red stripes - what I don't know is how to associate the loaded audio to the strip without using bpy.context... $\endgroup$
    – anf
    Commented Nov 2, 2017 at 15:46
  • $\begingroup$ .... scene.sequence_editor.sequences_all['some_name'].sound is the sound of the soundstrip "some_name", just need to know its name, or give it a custom prop or look for the one with the sound you want to replace .. eg. [s for s in sequences_all if getattr(s, "sound", None) == sound] Even easier if you still have ref from soundstrip = sequences.new_sound(..,) then you can simply soundstirp.sound = sound. $\endgroup$
    – batFINGER
    Commented Nov 2, 2017 at 16:33

2 Answers 2


bpy.context works perfectly fine from the command line. Here is a set of scripts for doing useful things with Blender from the command line, and a couple of them (render-batch and apply-compositor) make references to bpy.context.

Note also the technique of wrapping the Python code in a shell script, so the user can conveniently invoke the scripts as though they were commands in their own right.


With the help of @batFINGER I finally fixed it!

import bpy
import os

scene = bpy.data.scenes.get("Scene")
if not scene.sequence_editor:

scene.sequence_editor.sequences.new_sound(name='0D.wav', filepath="//audio\\0D.wav", channel=1, frame_start=1)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .