bpg: Converted gstplayer.py to GStreamer 1.0

This commit is contained in:
Philipp Beckmann 2016-06-19 22:06:55 +02:00
parent 2669b35945
commit 0917e675d7

View file

@ -21,16 +21,17 @@ from __future__ import division, absolute_import, print_function
import sys
import time
import gobject
import thread
import os
import copy
import urllib
import pygst
pygst.require('0.10')
import gst # noqa
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
GObject.threads_init()
Gst.init(None)
class GstPlayer(object):
"""A music player abstracting GStreamer's Playbin element.
@ -57,8 +58,19 @@ class GstPlayer(object):
# Set up the Gstreamer player. From the pygst tutorial:
# http://pygstdocs.berlios.de/pygst-tutorial/playbin.html
self.player = gst.element_factory_make("playbin2", "player")
fakesink = gst.element_factory_make("fakesink", "fakesink")
####
# Updated to GStreamer 1.0 with:
# https://wiki.ubuntu.com/Novacut/GStreamer1.0
self.player = Gst.ElementFactory.make("playbin", "player")
if self.player == None:
raise RuntimeError("Could not create playbin")
fakesink = Gst.ElementFactory.make("fakesink", "fakesink")
if fakesink == None:
raise RuntimeError("Could not create fakesink")
self.player.set_property("video-sink", fakesink)
bus = self.player.get_bus()
bus.add_signal_watch()
@ -74,21 +86,21 @@ class GstPlayer(object):
"""Returns the current state flag of the playbin."""
# gst's get_state function returns a 3-tuple; we just want the
# status flag in position 1.
return self.player.get_state()[1]
return self.player.get_state(Gst.CLOCK_TIME_NONE)[1]
def _handle_message(self, bus, message):
"""Callback for status updates from GStreamer."""
if message.type == gst.MESSAGE_EOS:
if message.type == Gst.MessageType.EOS:
# file finished playing
self.player.set_state(gst.STATE_NULL)
self.player.set_state(Gst.State.NULL)
self.playing = False
self.cached_time = None
if self.finished_callback:
self.finished_callback()
elif message.type == gst.MESSAGE_ERROR:
elif message.type == Gst.MessageType.ERROR:
# error
self.player.set_state(gst.STATE_NULL)
self.player.set_state(Gst.State.NULL)
err, debug = message.parse_error()
print(u"Error: {0}".format(err))
self.playing = False
@ -109,27 +121,27 @@ class GstPlayer(object):
"""Immediately begin playing the audio file at the given
path.
"""
self.player.set_state(gst.STATE_NULL)
self.player.set_state(Gst.State.NULL)
if isinstance(path, unicode):
path = path.encode('utf8')
uri = 'file://' + urllib.quote(path)
self.player.set_property("uri", uri)
self.player.set_state(gst.STATE_PLAYING)
self.player.set_state(Gst.State.PLAYING)
self.playing = True
def play(self):
"""If paused, resume playback."""
if self._get_state() == gst.STATE_PAUSED:
self.player.set_state(gst.STATE_PLAYING)
if self._get_state() == Gst.State.PAUSED:
self.player.set_state(Gst.State.PLAYING)
self.playing = True
def pause(self):
"""Pause playback."""
self.player.set_state(gst.STATE_PAUSED)
self.player.set_state(Gst.State.PAUSED)
def stop(self):
"""Halt playback."""
self.player.set_state(gst.STATE_NULL)
self.player.set_state(Gst.State.NULL)
self.playing = False
self.cached_time = None
@ -140,10 +152,9 @@ class GstPlayer(object):
play_file() or play().
"""
# If we don't use the MainLoop, messages are never sent.
gobject.threads_init()
def start():
loop = gobject.MainLoop()
loop = GObject.MainLoop()
loop.run()
thread.start_new_thread(start, ())
@ -152,14 +163,14 @@ class GstPlayer(object):
values are integers in seconds. If no stream is available,
returns (0, 0).
"""
fmt = gst.Format(gst.FORMAT_TIME)
fmt = Gst.Format(Gst.Format.TIME)
try:
pos = self.player.query_position(fmt, None)[0] / (10 ** 9)
length = self.player.query_duration(fmt, None)[0] / (10 ** 9)
pos = self.player.query_position(fmt)[1] / (10 ** 9)
length = self.player.query_duration(fmt)[1] / (10 ** 9)
self.cached_time = (pos, length)
return (pos, length)
except gst.QueryError:
except Exception:
# Stream not ready. For small gaps of time, for instance
# after seeking, the time values are unavailable. For this
# reason, we cache recent.
@ -175,9 +186,9 @@ class GstPlayer(object):
self.stop()
return
fmt = gst.Format(gst.FORMAT_TIME)
fmt = Gst.Format(Gst.Format.TIME)
ns = position * 10 ** 9 # convert to nanoseconds
self.player.seek_simple(fmt, gst.SEEK_FLAG_FLUSH, ns)
self.player.seek_simple(fmt, Gst.SeekFlags.FLUSH, ns)
# save new cached time
self.cached_time = (position, cur_len)