Ajout script python GST

This commit is contained in:
arnaud.houdelette 2018-10-05 17:14:19 +02:00
parent 7437fac740
commit 4bae84ee23

157
tools/gstlaunchdynamic.py Normal file
View file

@ -0,0 +1,157 @@
#!/usr/bin/env python
import sys
import gi
from gi.repository import GLib
gi.require_version('Gst', '1.0')
from gi.repository import Gst
import fcntl
import os
import ast
import re
# for the moment...
gst_eval = ast.literal_eval
class Parser(object):
def __init__(self, pipeline):
self.pipeline = pipeline
self.expressions = [
('^(\w+)\.(\w+) = (.+)$', self.set_property),
('^(\w+)(?:\.(\w+))? ([-x])> (\w+)(?:\.(\w+))?$', self.link_pads),
('^\+ (\w+)(?: (.*))?$', self.add_element),
('^- (\w+)$', self.remove_element),
('^(stop|play|pause)$', self.set_state),
('^seekto ([0-9.]+)$', self.seek),
]
self.expressions = [
(re.compile(regex), fn)
for regex, fn in self.expressions
]
def parse_line(self, line):
for regex, fn in self.expressions:
m = regex.match(line)
if m:
try:
fn(*m.groups())
except Exception:
import traceback
traceback.print_exc()
break
else:
print 'Error: could not parse line.'
def set_property(self, target, attr, value):
el = self.pipeline.get_by_name(target)
value = gst_eval(value)
el.set_property(attr, value)
def link_pads(self, src, src_pad, char, dst, dst_pad):
src_el = self.pipeline.get_by_name(src)
dst_el = self.pipeline.get_by_name(dst)
print src_el, src_pad, char, dst_el, dst_pad
if char == '-':
success = src_el.link_pads(src_pad, dst_el, dst_pad)
if not success:
print 'Could not link pads.'
elif char == 'x':
success = src_el.unlink_pads(src_pad, dst_el, dst_pad)
if not success:
print 'Could not unlink pads.'
def set_state(self, state):
state = {
'stop': Gst.State.READY,
'play': Gst.State.PLAYING,
'pause': Gst.State.PAUSED,
}[state]
self.pipeline.set_state(state)
def seek(self, to):
to=int(float(to)*1000000000)
print to
pipeline.seek_simple(
Gst.Format.TIME,
Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT,
to
)
def add_element(self, kind, properties):
# TODO: write a proper parser, and don't have this here
properties = dict(
pair.split('=', 1)
for pair in properties.split(' ')
)
# create the element
name = properties.pop('name', None)
element = Gst.ElementFactory.make(kind, name)
# set the properties
for key, value in properties:
value = gst_eval(value)
element.set_property(key, value)
self.pipeline.add(element)
def remove_element(self, name):
element = self.pipeline.get_by_name(name)
self.pipeline.remove(element)
def setup_non_blocking_read(f, on_line):
fd = f.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
buf = ['']
def on_data_available(fd, condition):
data = f.read()
buf[0] += data
lines = buf[0].split('\n')
buf[0] = lines.pop()
for line in lines:
on_line(line)
return True
GLib.io_add_watch(
fd,
GLib.IOCondition.IN,
on_data_available,
)
# init gstreamer, parse args
args = sys.argv[:]
Gst.init(args)
desc = ' '.join(args[1:])
# load gstreamer pipeline, press play
pipeline = Gst.parse_launch(desc)
pipeline.set_state(Gst.State.PLAYING)
# make stdin non-blocking
# when a line of input is recieved, parse it
# the parser has most of the logic
parser = Parser(pipeline)
setup_non_blocking_read(sys.stdin, parser.parse_line)
# run glib main loop
loop = GLib.MainLoop()
loop.run()