Advertisement
Guest User

Untitled

a guest
Apr 11th, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.99 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. import gi
  5. import signal
  6. import random
  7. import argparse
  8. import logging
  9. import threading
  10.  
  11. gi.require_version('Gst', '1.0')
  12. from gi.repository import Gst, GObject, GLib
  13.  
  14. # init GObject & Co. before importing local classes
  15. GObject.threads_init()
  16. Gst.init([])
  17.  
  18. BASEPATH = "/tmp/"
  19. exiting = False
  20.  
  21.  
  22. def get_random(ls):
  23.     ret = "file://" + os.path.join(BASEPATH, random.choice(ls))
  24.     print(ret)
  25.     return ret
  26.  
  27.  
  28. def control(src):
  29.     print("Running")
  30.     while not exiting:
  31.         input()
  32.         # src.seek(3)
  33.         src.next_track()
  34.  
  35.  
  36. class LoopSource(object):
  37.     def __init__(self, uris):
  38.         self.log = logging.getLogger('LoopSource')
  39.         self.uris = uris
  40.  
  41.         pipeline = """
  42.            urisourcebin name=dec !
  43.            qtdemux name=join ! queue ! avdec_h264 !
  44.            videoconvert !
  45.            autovideosink join. ! queue ! faad !
  46.            audioconvert !
  47.            volume volume=0.1 !
  48.            autoaudiosink
  49.  
  50.        """
  51.  
  52.         # Parsing Pipeline
  53.         self.log.debug('creating pipeline\n%s', pipeline)
  54.         self.pipeline = Gst.parse_launch(pipeline)
  55.  
  56.         # Selecting inital URI
  57.         inital_uri = get_random(uris)
  58.         self.log.info('initial track %s', inital_uri)
  59.  
  60.         # Create decoder-element
  61.         self.src = self.pipeline.get_by_name('dec')
  62.         self.src.set_property('uri', inital_uri)
  63.         self.src.connect('pad-added', self.on_pad_added)
  64.  
  65.         # Save pad on the Join-Element
  66.         self.joinpad = self.pipeline.get_by_name('join').get_static_pad('sink')
  67.  
  68.         # Binding End-of-Stream-Signal on Source-Pipeline
  69.         self.pipeline.bus.add_signal_watch()
  70.         self.pipeline.bus.connect("message::eos", self.on_eos)
  71.         self.pipeline.bus.connect("message::error", self.on_error)
  72.  
  73.         self.log.debug('setting pipeline to playing')
  74.         self.pipeline.set_state(Gst.State.PLAYING)
  75.  
  76.     def seek(self, seconds):
  77.          # FIXME: breaks on seconds > duration
  78.         self.src.seek_simple(Gst.Format.TIME,
  79.                              Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT,
  80.                              seconds * Gst.SECOND)
  81.  
  82.     def on_pad_added(self, src, pad):
  83.         self.log.debug('new pad on decoder, setting pad-probe')
  84.         pad.add_probe(
  85.             Gst.PadProbeType.EVENT_DOWNSTREAM | Gst.PadProbeType.BLOCK,
  86.             self.on_pad_event
  87.         )
  88.         if self.joinpad.is_linked():
  89.             self.log.debug('unlinking with joinpad')
  90.             self.joinpad.unlink(self.joinpad.get_peer())
  91.  
  92.         clock = self.pipeline.get_clock()
  93.         if clock:
  94.             runtime = clock.get_time() - self.pipeline.get_base_time()
  95.             self.log.debug('setting pad offset to pipeline runtime: %sns',
  96.                            runtime)
  97.             pad.set_offset(runtime)
  98.  
  99.         self.log.debug('linking with joinpad')
  100.         pad.link(self.joinpad)
  101.  
  102.     def on_pad_event(self, pad, info):
  103.         event = info.get_event()
  104.         self.log.debug('event %s on pad %s', event.type, pad)
  105.  
  106.         if event.type == Gst.EventType.EOS:
  107.             self.log.debug('scheduling next track and dropping EOS-Event')
  108.             GObject.idle_add(self.next_track)
  109.             return Gst.PadProbeReturn.DROP
  110.  
  111.         return Gst.PadProbeReturn.PASS
  112.  
  113.     def next_track(self):
  114.         next_uri = get_random(self.uris)
  115.         self.log.info('next track %s', next_uri)
  116.  
  117.         self.src.set_state(Gst.State.READY)
  118.         self.src.set_property('uri', next_uri)
  119.         self.src.set_state(Gst.State.PLAYING)
  120.         return False
  121.  
  122.     def on_eos(self, bus, message):
  123.         self.log.info('received EOS-Event on bus, exiting')
  124.         sys.exit(1)
  125.  
  126.     def on_error(self, bus, message):
  127.         self.log.warning('received Error-Event on bus, exiting')
  128.         (error, debug) = message.parse_error()
  129.         self.log.warning('Error-Details: #%u: %s', error.code, debug)
  130.         sys.exit(1)
  131.  
  132.  
  133. def main():
  134.     global exiting
  135.     signal.signal(signal.SIGINT, signal.SIG_DFL)
  136.  
  137.     parser = argparse.ArgumentParser(description='Voctocore Music-Source')
  138.  
  139.     parser.add_argument('-v|-vv', '--verbose', action='count', default=0,
  140.                         help="Also print INFO and DEBUG messages.")
  141.  
  142.     args = parser.parse_args()
  143.  
  144.     if args.verbose >= 2:
  145.         level = logging.DEBUG
  146.     elif args.verbose == 1:
  147.         level = logging.INFO
  148.     else:
  149.         level = logging.WARNING
  150.  
  151.     logging.basicConfig(
  152.         level=level,
  153.         format='%(levelname)8s %(name)s: %(message)s'
  154.     )
  155.  
  156.     files = ["file1_cropped.mp4", "file2_cropped.mp4"]
  157.  
  158.     src = LoopSource(files)
  159.  
  160.     mainloop = GObject.MainLoop()
  161.     try:
  162.         t1 = threading.Thread(target=control, args=(src,))
  163.         t1.start()
  164.         mainloop.run()
  165.     except KeyboardInterrupt:
  166.         exiting = True
  167.         print('Terminated via Ctrl-C')
  168.     finally:
  169.         print("Joining T1")
  170.         t1.join()
  171.  
  172.  
  173. if __name__ == '__main__':
  174.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement