3 # Simple media player with GStreamer
5 # Copyright (C) 2013-2014 Antonio Ospite <ao2@ao2.it>
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 # http://pygstdocs.berlios.de/pygst-reference
22 # https://core.fluendo.com/gstreamer/svn/trunk/gst-fluendo-gdlsink/test/ismdplay.py
28 gi.require_version('Gst', '1.0')
29 from gi.repository import Gst
32 from gi.repository import GLib
33 from gi.repository import GObject
35 # The player window will have a fixed width and height.
36 # This is just to demonstrate the use of capabilities.
41 class CustomVideoBin(Gst.Bin):
43 Gst.Bin.__init__(self, 'CustomVideoBin')
45 queue = Gst.ElementFactory.make('queue', 'vqueue')
48 rescale = Gst.ElementFactory.make("videoscale", "rescale")
52 caps = Gst.Caps("video/x-raw,format=(fourcc)AYUV,width=%d,height=%d,pixel-aspect-ratio=1/1" % (WIDTH, HEIGHT))
53 capsfilter = Gst.ElementFactory.make("capsfilter", "filter")
54 capsfilter.set_property("caps", caps)
56 rescale.link(capsfilter)
58 videoconvert = Gst.ElementFactory.make("videoconvert", "videoconvert")
59 self.add(videoconvert)
60 capsfilter.link(videoconvert)
62 videosink = Gst.ElementFactory.make("autovideosink", "vidoesink")
64 videoconvert.link(videosink)
66 sink = queue.get_static_pad('sink')
67 self.add_pad(Gst.GhostPad('sink', sink))
70 class CustomAudioBin(Gst.Bin):
72 Gst.Bin.__init__(self, 'CustomAudioBin')
74 queue = Gst.ElementFactory.make('queue', 'aqueue')
77 audioconvert = Gst.ElementFactory.make("audioconvert", "audioconverter")
78 self.add(audioconvert)
79 queue.link(audioconvert)
81 audiosink = Gst.ElementFactory.make("autoaudiosink", "audiosink")
83 audioconvert.link(audiosink)
85 sink = queue.get_static_pad('sink')
86 self.add_pad(Gst.GhostPad('sink', sink))
89 class CustomPlayBin(Gst.Pipeline):
91 'source': (Gst.Element, "source", "Source element", GObject.ParamFlags.READABLE)
94 def __init__(self, uri=None):
95 Gst.Pipeline.__init__(self, 'CustomPlayBin')
97 self._playbin = Gst.ElementFactory.make("playbin", "playbin")
98 self.add(self._playbin)
100 self._playbin.set_property("video-sink", CustomVideoBin())
101 self._playbin.set_property("audio-sink", CustomAudioBin())
106 def set_uri(self, uri):
108 self._playbin.set_property("uri", self._uri)
114 # The user can require some action at End Of Stream
117 self.pipeline = CustomPlayBin()
119 bus = self.pipeline.get_bus()
120 bus.add_signal_watch()
121 bus.connect('message::eos', self.on_eos)
122 bus.connect('message::tag', self.on_tag)
123 bus.connect('message::error', self.on_error)
124 bus.connect('message::state-changed', self.on_state_changed)
126 def on_eos(self, bus, msg):
132 def on_tag(self, bus, msg):
134 taglist = msg.parse_tag()
135 print('\t', taglist.to_string())
137 def on_error(self, bus, msg):
139 error, debug = msg.parse_error()
140 print("Error: %s" % error, debug)
143 def on_state_changed(self, bus, msg):
144 print('on_state_changed')
145 if msg.src != self.pipeline:
148 old_state, new_state, pending = msg.parse_state_changed()
150 def set_location(self, location):
151 self.pipeline.set_uri(location)
154 self.pipeline.set_state(Gst.State.PLAYING)
157 self.pipeline.set_state(Gst.State.PAUSED)
160 self.pipeline.set_state(Gst.State.NULL)
164 def __init__(self, location):
166 self.player = GstPlayer()
167 self.player.eos_cb = self.quit
169 self.mainloop = GLib.MainLoop()
171 self.player.set_location(location)
174 GLib.io_add_watch(sys.stdin, GLib.IO_IN, self.on_stdin)
178 except KeyboardInterrupt:
181 def on_stdin(self, fd, event):
182 # The user has to send a newline fo this to go on
183 c = os.read(fd.fileno(), 1)
202 sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
208 uri = Gst.filename_to_uri(args[1])
212 if __name__ == '__main__':
213 sys.exit(main(sys.argv))