Merge pull request #715 from geigerzaehler/gst-buffer

Pause gstreamer when buffering
This commit is contained in:
Thomas Adamcik 2014-05-08 22:07:13 +02:00
commit 56b9724ffc
2 changed files with 42 additions and 0 deletions

View File

@ -50,6 +50,7 @@ class Audio(pykka.ThreadingActor):
#: The GStreamer state mapped to :class:`mopidy.audio.PlaybackState`
state = PlaybackState.STOPPED
_target_state = gst.STATE_NULL
def __init__(self, config):
super(Audio, self).__init__()
@ -101,6 +102,9 @@ class Audio(pykka.ThreadingActor):
playbin = gst.element_factory_make('playbin2')
playbin.set_property('flags', PLAYBIN_FLAGS)
playbin.set_property('buffer-size', 2*1024*1024)
playbin.set_property('buffer-duration', 2*gst.SECOND)
self._connect(playbin, 'about-to-finish', self._on_about_to_finish)
self._connect(playbin, 'notify::source', self._on_new_source)
@ -279,6 +283,10 @@ class Audio(pykka.ThreadingActor):
self._on_playbin_state_changed(old_state, new_state, pending_state)
elif message.type == gst.MESSAGE_BUFFERING:
percent = message.parse_buffering()
if percent < 10:
self._playbin.set_state(gst.STATE_PAUSED)
if percent == 100 and self._target_state == gst.STATE_PLAYING:
self._playbin.set_state(gst.STATE_PLAYING)
logger.debug('Buffer %d%% full', percent)
elif message.type == gst.MESSAGE_EOS:
self._on_end_of_stream()
@ -471,6 +479,7 @@ class Audio(pykka.ThreadingActor):
:type state: :class:`gst.State`
:rtype: :class:`True` if successfull, else :class:`False`
"""
self._target_state = state
result = self._playbin.set_state(state)
if result == gst.STATE_CHANGE_FAILURE:
logger.warning(

View File

@ -1,5 +1,6 @@
from __future__ import unicode_literals
from mock import Mock
import unittest
import gobject
@ -158,3 +159,35 @@ class AudioStateTest(unittest.TestCase):
# gst.STATE_READY, gst.STATE_NULL, gst.STATE_VOID_PENDING)
self.assertEqual(audio.PlaybackState.STOPPED, self.audio.state)
class AudioBufferingTest(unittest.TestCase):
def setUp(self):
self.audio = audio.Audio(config=None)
self.audio._playbin = Mock(spec=['set_state'])
self.buffer_full_message = Mock()
self.buffer_full_message.type = gst.MESSAGE_BUFFERING
self.buffer_full_message.parse_buffering = Mock(return_value=100)
self.buffer_empty_message = Mock()
self.buffer_empty_message.type = gst.MESSAGE_BUFFERING
self.buffer_empty_message.parse_buffering = Mock(return_value=0)
def test_pause_when_buffer_empty(self):
playbin = self.audio._playbin
self.audio.start_playback()
playbin.set_state.assert_called_with(gst.STATE_PLAYING)
playbin.set_state.reset_mock()
self.audio._on_message(None, self.buffer_empty_message)
playbin.set_state.assert_called_with(gst.STATE_PAUSED)
def test_stay_paused_when_buffering_finished(self):
playbin = self.audio._playbin
self.audio.pause_playback()
playbin.set_state.assert_called_with(gst.STATE_PAUSED)
playbin.set_state.reset_mock()
self.audio._on_message(None, self.buffer_full_message)
self.assertEqual(playbin.set_state.call_count, 0)