I recently have been playing around with gstreamer and python, seeking (and finding) a way to decode and play HD movie with 10 audio tracks on relatively cheap hardware (being, a linux system with several cheapo 5.1 soundcards).
python, gstreamer and pulseaudio proved a winning combination here;
import sys, os
import pygtk, gtk, gobject
import pygst
pygst.require("0.10")
import gst
class GTK_Main:
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Player")
self.window.connect("destroy", gtk.main_quit, "WM destroy")
vbox = gtk.VBox()
self.window.add(vbox)
self.movie_window = gtk.DrawingArea()
vbox.add(self.movie_window)
self.window.show_all()
self.window.fullscreen()
self.pipeline = gst.parse_launch("filesrc location=fball/final1.mov ! qtdemux name=d \
interleave name=i0 ! \
pulsesink device=\"alsa_output.pci_13f6_111_0_sound_card_0_alsa_playback_0\" sync=true \
interleave name=i1 ! \
pulsesink device=\"alsa_output.pci_13f6_111_1_sound_card_0_alsa_playback_0\" sync=true \
interleave name=i2 ! \
pulsesink device=\"alsa_output.pci_13f6_111_sound_card_0_alsa_playback_0\" sync=true \
d.audio_00 ! queue ! audioresample ! audioconvert ! deinterleave name=di0 \
di0.src0 ! audioresample ! audioconvert ! queue ! i0. \
di0.src1 ! audioresample ! audioconvert ! queue ! i0. \
d.audio_01 ! audioresample ! audioconvert ! queue ! audioresample ! audioconvert ! deinterleave name=di1 \
di1.src0 ! audioresample ! audioconvert ! queue ! i0. \
di1.src1 ! audioresample ! audioconvert ! queue ! i0. \
d.audio_02 ! audioresample ! audioconvert ! queue ! audioresample ! audioconvert ! deinterleave name=di2 \
di2.src0 ! audioresample ! audioconvert ! queue ! i1. \
di2.src1 ! audioresample ! audioconvert ! queue ! i1. \
d.audio_03 ! audioresample ! audioconvert ! queue ! audioresample ! audioconvert ! deinterleave name=di3 \
di3.src0 ! audioresample ! audioconvert ! queue ! i1. \
di3.src1 ! audioresample ! audioconvert ! queue ! i1. \
d.audio_04 ! audioresample ! audioconvert ! queue ! audioresample ! audioconvert ! deinterleave name=di4 \
di4.src0 ! audioresample ! audioconvert ! queue ! i2. \
di4.src1 ! audioresample ! audioconvert ! queue ! i2. \
d.video_00 ! queue ! decodebin ! xvimagesink sync=true")
self.time_format = gst.Format(gst.FORMAT_TIME)
bus = self.pipeline.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect('message', self.on_message)
bus.connect('sync-message::element', self.on_sync_message)
self.pipeline.set_state(gst.STATE_PLAYING)
def on_message(self, bus, message):
t = message.type
if t == gst.MESSAGE_EOS:
self.pipeline.set_state(gst.STATE_PAUSED)
seek_ns = 0
self.pipeline.seek_simple(self.time_format, gst.SEEK_FLAG_FLUSH, seek_ns)
self.pipeline.set_state(gst.STATE_PLAYING)
elif t == gst.MESSAGE_ERROR:
err, debug = message.parse_error()
print "Error: %s" % err, debug
self.pipeline.set_state(gst.STATE_NULL)
def on_sync_message(self, bus, message):
if message.structure is None:
return
message_name = message.structure.get_name()
if message_name == 'prepare-xwindow-id':
imagesink = message.src
imagesink.set_property('force-aspect-ratio', True)
imagesink.set_xwindow_id(self.movie_window.window.xid)
GTK_Main()
gtk.gdk.threads_init()
gtk.main()