# Add marker to 2D tracking list via clip.stabilize_2d_add() or other means

My goal is to call blender form the command line with a set of arguments to use the built in 2D video stabilization tools.

I have been able to (via the bpy API):

• Get parameters from command line call
• add a marker (to track)
• position the marker
• 'select' the marker/track (not sure if needed)

This is all possible without relying on bpy.ops

Unfortunately now I need to access the following functionality programmatically:

My main question: I can't find a way to get to that (bpy.ops.clip.stabilize_2d_add()). I have no idea what context I would need to switch to to make this a valid python call.

At this point I also notice the transition from doing everything in code to having to hunt through the UI workflow for ways to replicate UI functionality. I am wondering if I shouldn't need to call bpy.ops.clip.stabilize_2d_add() at all and should instead find the underlying functionality?

The part that comes right after this, which is making the stabilized track is completely lost to me as well. Am I going in the wrong direction?

Any help would be greatly appreciated.

• Related: blender.stackexchange.com/a/41747/2843 In this example script I use the context a lot to call bpy.ops.* functions, you need to use this override parameter. – Samoth Mar 2 '17 at 21:28
• @Samoth do you have any tips on a clean way to figure out what screen+region+area this ops control is in? I notice that in one part of your code the override is hardcoded. How did you get the values you hardcode it to? – BorisKourt Mar 2 '17 at 22:45
• As far as I can remember that was a mixture of copying it from somewhere and trial and error to adapt it to my needs. I actually use it in three different areas and in the end I included three more parameters: , 'active_object': bpy.context.object, 'edit_object': bpy.context.object, 'selected_objects': [helper] where I set the helper = bpy.data.objects['Empty'] and then adjusted override['selected_objects'] = [helper] and override['active_object'] = helper... This allowed me to call another bpy.ops.anim.keyframe_insert(override, type='Location') to create a new keyframe via python. – Samoth Mar 2 '17 at 23:04

Each movie clip has a tracking property which has a list of the tracks that have markers.

Every tracking.track is a point in that you are tracking. The markers for each track are keyframes of the tracks location.

import bpy

track_data = bpy.data.movieclips['movie_track'].tracking

for i in range(10):
# this adds a new point to be tracked
trck = track_data.tracks.new()
for f in range(1,100,10):
# this sets the location of the point at frame f
x = (f+i) * 0.1
y = (f+i) * 0.1
trck.markers.insert_frame(f, co=(x,y))

# get track data
for t in track_data.tracks:
for m in t.markers:
print('marker on frame {} at {}'.format(m.frame, m.co))

• Thanks but I have done this as the precursor to this question. What this doesn't answer is adding these tracks to the list of tracks that 2D stabilization uses so that I can then run the automatic stabilization tool. So far I only see operators as the way to do that. – BorisKourt Mar 3 '17 at 9:15
• True - The stabilize_2d_add operator only changes the value of a flag, but as it isn't provided in the py-api we have to use the operator for that one step. So track_data.stabilization.tracks is presented as a list but it is really a dynamic subset of the tracks list based on the flag value, which would be why we can't alter it as a list. – sambler Mar 3 '17 at 16:19

Thanks to kostex on #blenderpython and @Samoth here.

# Make a copy of the current context.
override = bpy.context.copy()

# Find the right area to override
for area in bpy.context.screen.areas:
if area.type == 'CLIP_EDITOR':
break

# Override the area
override['area'] = area

# Proceed with operator