Skip to content

Instantly share code, notes, and snippets.

@cfoch
Last active June 29, 2020 02:15
Show Gist options
  • Save cfoch/a314d30d0d8d1090ae8f9031927b872b to your computer and use it in GitHub Desktop.
Save cfoch/a314d30d0d8d1090ae8f9031927b872b to your computer and use it in GitHub Desktop.
dvd.py
import argparse
import pathlib
import pickle
import signal
import gi
gi.require_version("Gtk", "3.0")
gi.require_version("GES", "1.0")
gi.require_version("GstController", "1.0")
from gi.repository import Gtk
from gi.repository import GES
from gi.repository import Gst
from gi.repository import GObject
from gi.repository import GstController
DEFAULT_DURATION = 10 * Gst.SECOND
def handle_sigint(sig, frame):
Gtk.main_quit()
def bus_message_cb(bus, message):
if message.type == Gst.MessageType.EOS:
Gtk.main_quit()
def effect_control_binding_added_cb(effect, binding, timed_data):
control_source = binding.props.control_source
for frame in sorted(timed_data.keys()):
p1, p2 = timed_data[frame]
if binding.name == "posx":
value = p1[0]
elif binding.name == "posy":
value = p1[1]
elif binding.name == "width":
value = p2[0] - p1[0]
else:
value = p2[1] - p1[1]
control_source.set(frame * Gst.SECOND // 30, value)
def bg_clip_child_added_cb(clip, track_element, timed_data):
if not isinstance(track_element, GES.Effect):
return
track_element.connect("control-binding-added",
effect_control_binding_added_cb, timed_data)
props = (
"posx",
"posy",
"width",
"height",
)
for prop in props:
control_source = GstController.InterpolationControlSource()
control_source.props.mode = GstController.InterpolationMode.NONE
track_element.set_control_source(control_source, prop,
"direct-absolute")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--video", type=str, required=True)
parser.add_argument("-p", "--pickle", type=argparse.FileType("rb"),
required=True)
args = parser.parse_args()
timed_data = pickle.load(args.pickle)
Gst.init(None)
GES.init()
timeline = GES.Timeline()
track = GES.VideoTrack.new()
timeline.add_track(track)
layer = timeline.append_layer()
asset = GES.UriClipAsset.request_sync(pathlib.Path(args.video).as_uri())
bg_clip = layer.add_asset(asset, 0, 0, DEFAULT_DURATION,
GES.TrackType.VIDEO)
bg_clip.connect("child-added", bg_clip_child_added_cb, timed_data)
effect = GES.Effect.new(
"videotestsrc ! framepositioner name=positioner ! gescompositor")
bg_clip.add_top_effect(effect, -1)
pipeline = GES.Pipeline()
sink = Gst.ElementFactory.make("xvimagesink", None)
pipeline.preview_set_video_sink(sink)
pipeline.set_timeline(timeline)
bus = pipeline.get_bus()
bus.connect("message", bus_message_cb)
bus.add_signal_watch()
pipeline.set_state(Gst.State.PLAYING)
signal.signal(signal.SIGINT, handle_sigint)
Gtk.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment