Ajout script python GST
This commit is contained in:
parent
7437fac740
commit
4bae84ee23
1 changed files with 157 additions and 0 deletions
157
tools/gstlaunchdynamic.py
Normal file
157
tools/gstlaunchdynamic.py
Normal 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()
|
||||
Loading…
Reference in a new issue