# sound_bake in command line script

I'm making an audio visualizer which I want to render from the command line. Unfortunately the bpy.ops.graph.sound_bake() function seems only to work from the GUI.

I've found various tutorials, but they all use the gui to create the animation. They always require this fix

bpy.context.area.type = 'GRAPH_EDITOR'


to set the correct context for bpy.ops.graph.sound_bake() to work. This works for scripts run from the gui, but when a script is started from he command line bpy.context.area is undefined.

For materials I already found that instead of bpy.ops.material.new() I should use mat = bpy.data.materials.new("") to avoid problems with the context. I have not been able how to work out how to do something similar with sounds.

It seems in scripting, using bpy.ops.* can easily give problems with the context, as these function might check the mouse position for some reason, etc. and there would/should be alternative functions. I have no clue on how to find those alternatives. So far I found them by chance, but I have not been able to find an alternative for bpy.ops.graph.sound_bake()

How can I bake an mp3 to an fcurve and apply that curve to an object, in a script?

For Sound Drivers Addon I do a lot of sound baking, so I thought I'd check out how it would perform running in background mode (this has led to another q re running modal timer operators in bg mode). Anyhow using context override the following bakes in bg mode using command

blender -b ./Desktop/baketest.blend --python-text bake.py


using the following as a text block named bake.py.

import bpy
#from sound_drivers.utils import get_context_area
def get_context_area(context, context_dict, area_type='GRAPH_EDITOR',
context_screen=False):
'''
context : the current context
context_dict : a context dictionary. Will update area, screen, scene,
area, region
area_type: the type of area to search for
context_screen: Boolean. If true only search in the context screen.
'''
if not context_screen:  # default
screens = bpy.data.screens
else:
screens = [context.screen]
for screen in screens:
for area_index, area in screen.areas.items():
if area.type == area_type:
for region in area.regions:
if region.type == 'WINDOW':
context_dict["area"] = area
context_dict["screen"] = screen
context_dict["scene"] = context.scene
context_dict["window"] = context.window
context_dict["region"] = region
return area
return None

c = bpy.context.copy()
get_context_area(bpy.context, c)
obj = bpy.data.objects["Cube"]
obj["y"] = 0.0
obj.keyframe_insert('["y"]', frame=1)

speaker = bpy.data.speakers["Speaker"]
bpy.ops.graph.sound_bake(c, filepath=speaker.sound.filepath)
bpy.ops.wm.save_mainfile()


Note for convenience sake I grabbed the filepath from a speaker's sound. This successfully baked the sound file onto the "y" custom property of the Cube in bg mode.

Use something like How to pass command line arguments to a Blender Python script? to extend functionality,.

NB: Example of creating a simple sound visualiser using sound_drivers.

• You sir are my hero for the day. May good things come your way. Jun 17 '18 at 20:15
• There is trouble with selecting only channel ["y"] in the graph editor. So at the start it somehow have to deselect all channels, groups, objects > then select only obj["y"] and then bpy.ops.graph.sound_bake. But with the blender background deselecting is somehow tricky, I don't know how to do that properly trough bpy.data.. because data.actions[].groups[].select ... is not setable trough text editor.
– MRL
Oct 12 at 15:14