Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import os
- import sys
- import gi
- import signal
- import random
- import argparse
- import logging
- import threading
- gi.require_version('Gst', '1.0')
- from gi.repository import Gst, GObject, GLib
- # init GObject & Co. before importing local classes
- GObject.threads_init()
- Gst.init([])
- BASEPATH = "/tmp/"
- exiting = False
- def get_random(ls):
- ret = "file://" + os.path.join(BASEPATH, random.choice(ls))
- print(ret)
- return ret
- def control(src):
- print("Running")
- while not exiting:
- input()
- # src.seek(3)
- src.next_track()
- class LoopSource(object):
- def __init__(self, uris):
- self.log = logging.getLogger('LoopSource')
- self.uris = uris
- pipeline = """
- urisourcebin name=dec !
- qtdemux name=join ! queue ! avdec_h264 !
- videoconvert !
- autovideosink join. ! queue ! faad !
- audioconvert !
- volume volume=0.1 !
- autoaudiosink
- """
- # Parsing Pipeline
- self.log.debug('creating pipeline\n%s', pipeline)
- self.pipeline = Gst.parse_launch(pipeline)
- # Selecting inital URI
- inital_uri = get_random(uris)
- self.log.info('initial track %s', inital_uri)
- # Create decoder-element
- self.src = self.pipeline.get_by_name('dec')
- self.src.set_property('uri', inital_uri)
- self.src.connect('pad-added', self.on_pad_added)
- # Save pad on the Join-Element
- self.joinpad = self.pipeline.get_by_name('join').get_static_pad('sink')
- # Binding End-of-Stream-Signal on Source-Pipeline
- self.pipeline.bus.add_signal_watch()
- self.pipeline.bus.connect("message::eos", self.on_eos)
- self.pipeline.bus.connect("message::error", self.on_error)
- self.log.debug('setting pipeline to playing')
- self.pipeline.set_state(Gst.State.PLAYING)
- def seek(self, seconds):
- # FIXME: breaks on seconds > duration
- self.src.seek_simple(Gst.Format.TIME,
- Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT,
- seconds * Gst.SECOND)
- def on_pad_added(self, src, pad):
- self.log.debug('new pad on decoder, setting pad-probe')
- pad.add_probe(
- Gst.PadProbeType.EVENT_DOWNSTREAM | Gst.PadProbeType.BLOCK,
- self.on_pad_event
- )
- if self.joinpad.is_linked():
- self.log.debug('unlinking with joinpad')
- self.joinpad.unlink(self.joinpad.get_peer())
- clock = self.pipeline.get_clock()
- if clock:
- runtime = clock.get_time() - self.pipeline.get_base_time()
- self.log.debug('setting pad offset to pipeline runtime: %sns',
- runtime)
- pad.set_offset(runtime)
- self.log.debug('linking with joinpad')
- pad.link(self.joinpad)
- def on_pad_event(self, pad, info):
- event = info.get_event()
- self.log.debug('event %s on pad %s', event.type, pad)
- if event.type == Gst.EventType.EOS:
- self.log.debug('scheduling next track and dropping EOS-Event')
- GObject.idle_add(self.next_track)
- return Gst.PadProbeReturn.DROP
- return Gst.PadProbeReturn.PASS
- def next_track(self):
- next_uri = get_random(self.uris)
- self.log.info('next track %s', next_uri)
- self.src.set_state(Gst.State.READY)
- self.src.set_property('uri', next_uri)
- self.src.set_state(Gst.State.PLAYING)
- return False
- def on_eos(self, bus, message):
- self.log.info('received EOS-Event on bus, exiting')
- sys.exit(1)
- def on_error(self, bus, message):
- self.log.warning('received Error-Event on bus, exiting')
- (error, debug) = message.parse_error()
- self.log.warning('Error-Details: #%u: %s', error.code, debug)
- sys.exit(1)
- def main():
- global exiting
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- parser = argparse.ArgumentParser(description='Voctocore Music-Source')
- parser.add_argument('-v|-vv', '--verbose', action='count', default=0,
- help="Also print INFO and DEBUG messages.")
- args = parser.parse_args()
- if args.verbose >= 2:
- level = logging.DEBUG
- elif args.verbose == 1:
- level = logging.INFO
- else:
- level = logging.WARNING
- logging.basicConfig(
- level=level,
- format='%(levelname)8s %(name)s: %(message)s'
- )
- files = ["file1_cropped.mp4", "file2_cropped.mp4"]
- src = LoopSource(files)
- mainloop = GObject.MainLoop()
- try:
- t1 = threading.Thread(target=control, args=(src,))
- t1.start()
- mainloop.run()
- except KeyboardInterrupt:
- exiting = True
- print('Terminated via Ctrl-C')
- finally:
- print("Joining T1")
- t1.join()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement