3 # Simple media player with GStreamer
5 # Copyright (C) 2013 Antonio Ospite <ospite@studenti.unina.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 gobject.threads_init()
32 # The player window will have a fixed width and height.
33 # This is just to demonstrate the use of capabilities.
38 class CustomVideoBin(gst.Bin):
40 gst.Bin.__init__(self, 'CustomVideoBin')
42 queue = gst.element_factory_make('queue', 'vqueue')
45 caps = gst.Caps("video/x-raw-yuv,format=(fourcc)AYUV,width=%d,height=%d" % (WIDTH, HEIGHT))
46 capsfilter = gst.element_factory_make("capsfilter", "filter")
47 capsfilter.set_property("caps", caps)
50 rescale = gst.element_factory_make("videoscale", "rescale")
53 colorspace = gst.element_factory_make("colorspace", "colorspace")
56 videosink = gst.element_factory_make("autovideosink", "vidoesink")
59 gst.element_link_many(queue, capsfilter, rescale, colorspace, videosink)
60 sink = queue.get_pad('sink')
61 self.add_pad(gst.GhostPad('sink', sink))
64 class CustomAudioBin(gst.Bin):
66 gst.Bin.__init__(self, 'CustomAudioBin')
68 queue = gst.element_factory_make('queue', 'aqueue')
71 audioconvert = gst.element_factory_make("audioconvert", "audioconverter")
72 self.add(audioconvert)
74 audiosink = gst.element_factory_make("autoaudiosink", "audiosink")
77 gst.element_link_many(queue, audioconvert, audiosink)
78 sink = queue.get_pad('sink')
79 self.add_pad(gst.GhostPad('sink', sink))
82 class CustomPlayBin(gst.Pipeline):
84 'source': (gst.Element, "source", "Source element", gobject.PARAM_READABLE)
87 def __init__(self, uri=None):
88 gst.Pipeline.__init__(self, 'CustomPlayBin')
92 self._playbin = gst.element_factory_make("playbin2", "playbin")
93 self.add(self._playbin)
95 self._playbin.set_property("uri", self._uri)
96 self._playbin.set_property("video-sink", CustomVideoBin())
97 self._playbin.set_property("audio-sink", CustomAudioBin())
99 def set_uri(self, uri):
101 self._playbin.set_property("uri", self._uri)
107 # The user can require some action at End Of Stream
110 self.pipeline = CustomPlayBin()
112 bus = self.pipeline.get_bus()
113 bus.add_signal_watch()
114 bus.connect('message::eos', self.on_eos)
115 bus.connect('message::tag', self.on_tag)
116 bus.connect('message::error', self.on_error)
117 bus.connect('message::state-changed', self.on_state_changed)
119 def on_eos(self, bus, msg):
125 def on_tag(self, bus, msg):
127 taglist = msg.parse_tag()
128 for key in taglist.keys():
129 print '\t%s = %s' % (key, taglist[key])
131 def on_error(self, bus, msg):
133 error, debug = msg.parse_error()
134 print "Error: %s" % error, debug
137 def on_state_changed(self, bus, msg):
138 print 'on_state_changed'
139 if msg.src != self.pipeline:
142 old_state, new_state, pending = msg.parse_state_changed()
144 def set_location(self, location):
145 self.pipeline.set_uri(location)
148 self.pipeline.set_state(gst.STATE_PLAYING)
151 self.pipeline.set_state(gst.STATE_PAUSED)
154 self.pipeline.set_state(gst.STATE_NULL)
158 def __init__(self, location):
160 self.player = GstPlayer()
161 self.player.eos_cb = self.quit
163 self.mainloop = gobject.MainLoop()
165 self.player.set_location(location)
168 gobject.io_add_watch(sys.stdin, gobject.IO_IN, self.on_stdin)
172 except KeyboardInterrupt:
175 def on_stdin(self, fd, event):
176 # The user has to send a newline fo this to go on
177 c = os.read(fd.fileno(), 1)
196 sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
202 if not gst.uri_is_valid(args[1]):
203 sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
206 tui = PlayerTUI(args[1])
208 if __name__ == '__main__':
209 sys.exit(main(sys.argv))