files: """High-level sound and video player."""
  from __future__ import print_function
  from __future__ import division
  from builtins import object
  # ----------------------------------------------------------------------------
  # pyglet
  # Copyright (c) 2006-2008 Alex Holkner
  # All rights reserved.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions
  # are met:
  #
  #  * Redistributions of source code must retain the above copyright
  #    notice, this list of conditions and the following disclaimer.
  #  * Redistributions in binary form must reproduce the above copyright
  #    notice, this list of conditions and the following disclaimer in
  #    the documentation and/or other materials provided with the
  #    distribution.
  #  * Neither the name of pyglet nor the names of its
  #    contributors may be used to endorse or promote products
  #    derived from this software without specific prior written
  #    permission.
  #
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  # POSSIBILITY OF SUCH DAMAGE.
  # ----------------------------------------------------------------------------
  
  from collections import deque
  
  import pyglet
  from pyglet.media import buffered_logger as bl
  from pyglet.media.drivers import get_audio_driver
  from pyglet.media.codecs.base import Source
  
  # import cProfile
  
  _debug = pyglet.options['debug_media']
  
  clock = pyglet.clock.get_default()
  
  
  class MasterClock(object):
      """Master clock object.
  
      This is a simple clock object which tracks the time elapsed. It can be
      paused and reset.
      """
  
      def __init__(self):
          """Initialize the clock with time 0."""
          self._time = 0.0
          self._systime = None
  
      def play(self):
          """Start the clock."""
          self._systime = clock.time()
  
      def pause(self):
          """Pause the clock."""
          self._time = self.get_time()
          self._systime = None
  
      def reset(self):
          """Reset the clock to 0."""
          self._time = 0.0
          if self._systime is not None:
              self._systime = clock.time()
  
      def get_time(self):
          """Current master clock time."""
          if self._systime is None:
              now = self._time
          else:
              now = clock.time() - self._systime + self._time
          return now
  
      def set_time(self, value):
          """
          Set the master clock time.
  
          Args:
              value (float): The new :class:`~pyglet.media.player.MasterClock`
                  time.
          """
          self.reset()
          self._time = value
  
  
  class _PlayerProperty(object):
      """Descriptor for Player attributes to forward to the AudioPlayer.
  
      We want the Player to have attributes like volume, pitch, etc. These are
      actually implemented by the AudioPlayer. So this descriptor will forward
      an assignement to one of the attributes to the AudioPlayer. For example
      `player.volume = 0.5` will call `player._audio_player.set_volume(0.5)`.
  
      The Player class has default values at the class level which are retrieved
      if not found on the instance.
      """
  
      def __init__(self, attribute, doc=None):
          self.attribute = attribute
          self.__doc__ = doc or ''
  
      def __get__(self, obj, objtype=None):
          if obj is None:
              return self
          if '_' + self.attribute in obj.__dict__:
              return obj.__dict
  
  [... the rest is omitted ...]
files: pyglet/media/player.py
files: """High-level sound and video player."""
  from __future__ import print_function
  from __future__ import division
  from builtins import object
  # ----------------------------------------------------------------------------
  # pyglet
  # Copyright (c) 2006-2008 Alex Holkner
  # All rights reserved.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions
  # are met:
  #
  #  * Redistributions of source code must retain the above copyright
  #    notice, this list of conditions and the following disclaimer.
  #  * Redistributions in binary form must reproduce the above copyright
  #    notice, this list of conditions and the following disclaimer in
  #    the documentation and/or other materials provided with the
  #    distribution.
  #  * Neither the name of pyglet nor the names of its
  #    contributors may be used to endorse or promote products
  #    derived from this software without specific prior written
  #    permission.
  #
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  # POSSIBILITY OF SUCH DAMAGE.
  # ----------------------------------------------------------------------------
  
  from collections import deque
  
  import pyglet
  from pyglet.media import buffered_logger as bl
  from pyglet.media.drivers import get_audio_driver
  from pyglet.media.codecs.base import Source
  
  # import cProfile
  
  _debug = pyglet.options['debug_media']
  
  clock = pyglet.clock.get_default()
  
  
  class MasterClock(object):
      """Master clock object.
  
      This is a simple clock object which tracks the time elapsed. It can be
      paused and reset.
      """
  
      def __init__(self):
          """Initialize the clock with time 0."""
          self._time = 0.0
          self._systime = None
  
      def play(self):
          """Start the clock."""
          self._systime = clock.time()
  
      def pause(self):
          """Pause the clock."""
          self._time = self.get_time()
          self._systime = None
  
      def reset(self):
          """Reset the clock to 0."""
          self._time = 0.0
          if self._systime is not None:
              self._systime = clock.time()
  
      def get_time(self):
          """Current master clock time."""
          if self._systime is None:
              now = self._time
          else:
              now = clock.time() - self._systime + self._time
          return now
  
      def set_time(self, value):
          """
          Set the master clock time.
  
          Args:
              value (float): The new :class:`~pyglet.media.player.MasterClock`
                  time.
          """
          self.reset()
          self._time = value
  
  
  class _PlayerProperty(object):
      """Descriptor for Player attributes to forward to the AudioPlayer.
  
      We want the Player to have attributes like volume, pitch, etc. These are
      actually implemented by the AudioPlayer. So this descriptor will forward
      an assignement to one of the attributes to the AudioPlayer. For example
      `player.volume = 0.5` will call `player._audio_player.set_volume(0.5)`.
  
      The Player class has default values at the class level which are retrieved
      if not found on the instance.
      """
  
      def __init__(self, attribute, doc=None):
          self.attribute = attribute
          self.__doc__ = doc or ''
  
      def __get__(self, obj, objtype=None):
          if obj is None:
              return self
          if '_' + self.attribute in obj.__dict__:
              return obj.__dict
  
  [... the rest is omitted ...]
files: pyglet/media/player.py
files: from __future__ import absolute_import, print_function
  import pyglet
  import pytest
  _debug = False
  
  
  class MockPlayer(object):
      def __init__(self, event_loop):
          self.event_loop = event_loop
          self.events = []
          self.pyclock = pyglet.clock.get_default()
          super(MockPlayer, self).__init__()
  
      def dispatch_event(self, event_type, *args):
          super(MockPlayer, self).dispatch_event(event_type, *args)
          if _debug:
              print('{}: event {} received @ {}'.format(
                  self.__class__.__name__,
                  event_type, self.pyclock.time()
              ))
          self.events.append((event_type, args))
          pyglet.clock.unschedule(self.event_loop.interrupt_event_loop)
          self.event_loop.interrupt_event_loop()
  
      def wait_for_event(self, timeout, *event_types):
          end_time = self.pyclock.time() + timeout
  
          while self.pyclock.time() < end_time:
              if _debug:
                  print('{}: run for {} sec @ {}'.format(self.__class__.__name__,
                        end_time - self.pyclock.time(), self.pyclock.time()))
              self.event_loop.run_event_loop(duration=end_time - self.pyclock.time())
              if not self.events:
                  continue
              event_type, args = self.events.pop()
              if event_type in event_types:
                  return event_type, args
          return None, None
  
      def wait_for_all_events(self, timeout, *expected_events):
          now = self.pyclock.time()
          if _debug:
              print('Wait for events @ {}'.format(now))
          end_time = self.pyclock.time() + timeout
          expected_events = list(expected_events)
          received_events = []
          while expected_events:
              event_type, args = self.wait_for_event(timeout, *expected_events)
              if _debug:
                  print('{}: got event {} @ {}'.format(self.__class__.__name__,
                        event_type, self.pyclock.time()))
              if event_type is None and self.pyclock.time() >= end_time:
                  pytest.fail('Timeout before all events have been received. '
                              'Still waiting for: ' + ','.join(expected_events))
              elif event_type is not None:
                  if event_type in expected_events:
                      expected_events.remove(event_type)
                  received_events.append((event_type, args))
          return received_events
  
      def wait(self, timeout):
          now = self.pyclock.time()
          end_time = now + timeout
          while now - end_time < -0.005:
              duration = max(.01, end_time - now)
              self.event_loop.run_event_loop(duration=duration)
              now = self.pyclock.time()
  
  
  [... the rest is omitted ...]
files: tests/integration/media/mock_player.py
files: from __future__ import absolute_import, print_function
  import pyglet
  _debug = False
  
  
  class MockPlayer(object):
      def __init__(self, event_loop):
          self.event_loop = event_loop
          self.events = []
          self.pyclock = pyglet.clock.get_default()
          super(MockPlayer, self).__init__()
  
      def dispatch_event(self, event_type, *args):
          super(MockPlayer, self).dispatch_event(event_type, *args)
          if _debug:
              print('{}: event {} received @ {}'.format(self.__class__.__name__,
              	event_type, self.pyclock.time()))
          self.events.append((event_type, args))
          pyglet.clock.unschedule(self.event_loop.interrupt_event_loop)
          self.event_loop.interrupt_event_loop()
  
      def wait_for_event(self, timeout, *event_types):
          end_time = self.pyclock.time() + timeout
  
          while self.pyclock.time() < end_time:
              if _debug:
                  print('{}: run for {} sec @ {}'.format(self.__class__.__name__,
                  	end_time-self.pyclock.time(), self.pyclock.time()))
              self.event_loop.run_event_loop(duration=end_time-self.pyclock.time())
              if not self.events:
                  continue
              event_type, args = self.events.pop()
              if event_type in event_types:
                  return event_type, args
          return None, None
  
      def wait_for_all_events(self, timeout, *expected_events):
          now = self.pyclock.time()
          if _debug:
              print('Wait for events @ {}'.format(now))
          end_time = self.pyclock.time() + timeout
          expected_events = list(expected_events)
          received_events = []
          while expected_events:
              event_type, args = self.wait_for_event(timeout, *expected_events)
              if _debug:
                  print('{}: got event {} @ {}'.format(self.__class__.__name__,
                  	event_type, self.pyclock.time()))
              if event_type is None and self.pyclock.time() >= end_time:
                  pytest.fail('Timeout before all events have been received. Still waiting for: '
                          + ','.join(expected_events))
              elif event_type is not None:
                  if event_type in expected_events:
                      expected_events.remove(event_type)
                  received_events.append((event_type, args))
          return received_events
  
      def wait(self, timeout):
          now = self.pyclock.time()
          end_time = now + timeout
          while now - end_time < -0.005:
              duration = max(.01, end_time-now)
              self.event_loop.run_event_loop(duration=duration)
              now = self.pyclock.time()
  
  [... the rest is omitted ...]
files: tests/integration/media/mock_player.py
files: from __future__ import print_function
  from future import standard_library
  standard_library.install_aliases()
  
  import pytest
  from tests import mock
  import time
  
  import pyglet
  _debug = False
  pyglet.options['debug_media'] = _debug
  pyglet.options['debug_media_buffers'] = _debug
  
  from pyglet.media import Player
  from pyglet.media.synthesis import Silence
  from .mock_player import MockPlayer
  
  
  class PlayerTest(MockPlayer, Player):
      pass
  
  
  @pytest.fixture
  def player(event_loop):
      return PlayerTest(event_loop)
  
  
  class SilentTestSource(Silence):
      def __init__(self, duration, sample_rate=44800, sample_size=16):
          super(Silence, self).__init__(duration, sample_rate, sample_size)
          self.bytes_read = 0
  
      def get_audio_data(self, nbytes, compensation_time=0.0):
          data = super(Silence, self).get_audio_data(nbytes, compensation_time)
          if data is not None:
              self.bytes_read += data.length
          return data
  
      def has_fully_played(self):
          return self.bytes_read == self._max_offset
  
  
  def test_player_play(player):
      source = SilentTestSource(.1)
      player.queue(source)
  
      player.play()
      player.wait_for_all_events(
          1.,
          'on_eos',
          'on_player_eos'
      )
      assert source.has_fully_played(), 'Source not fully played'
  
  
  def test_player_play_multiple(player):
      sources = (SilentTestSource(.1), SilentTestSource(.1))
      for source in sources:
          player.queue(source)
  
      player.play()
      player.wait_for_all_events(
          1.,
          'on_eos',
          'on_player_next_source',
          'on_eos',
          'on_player_eos'
      )
      for source in sources:
          assert source.has_fully_played(), 'Source not fully played'
  
  
  def test_multiple_fire_and_forget_players():
      """
      Test an issue where the driver crashed when starting multiple players, but not
      keeping a reference to these players.
      """
      for _ in range(10):
          Silence(1).play()
      time.sleep(1)
  
  
  def test_player_silent_audio_driver(player):
      with mock.patch('pyglet.media.player.get_audio_driver') as get_audio_driver_mock:
          get_audio_driver_mock.return_value = None
          source = SilentTestSource(.1)
          player.queue(source)
          player.play()
  
          player.wait_for_all_events(
              1.,
              'on_eos',
              'on_player_eos')
  
  
  [... the rest is omitted ...]
files: tests/integration/media/test_player.py
files: from __future__ import print_function
  from future import standard_library
  standard_library.install_aliases()
  
  import gc
  import pytest
  from tests import mock
  import time
  import unittest
  
  import pyglet
  _debug = False
  pyglet.options['debug_media'] = _debug
  pyglet.options['debug_media_buffers'] = _debug
  
  from pyglet.media import Player
  from pyglet.media.synthesis import Silence
  from .mock_player import MockPlayer
  
  
  class PlayerTest(MockPlayer, Player):
      pass
  
  
  @pytest.fixture
  def player(event_loop):
      return PlayerTest(event_loop)
  
  class SilentTestSource(Silence):
      def __init__(self, duration, sample_rate=44800, sample_size=16):
          super(Silence, self).__init__(duration, sample_rate, sample_size)
          self.bytes_read = 0
  
      def get_audio_data(self, nbytes, compensation_time=0.0):
          data = super(Silence, self).get_audio_data(nbytes, compensation_time)
          if data is not None:
              self.bytes_read += data.length
          return data
  
      def has_fully_played(self):
          return self.bytes_read == self._max_offset
  
  
  
  def test_player_play(player):
      source = SilentTestSource(.1)
      player.queue(source)
  
      player.play()
      player.wait_for_all_events(1., 
          'on_eos', 'on_player_eos')
      assert source.has_fully_played(), 'Source not fully played'
  
  
  def test_player_play_multiple(player):
      sources = (SilentTestSource(.1), SilentTestSource(.1))
      for source in sources:
          player.queue(source)
  
      player.play()
      player.wait_for_all_events(1., 
          'on_eos', 'on_player_next_source', 'on_eos', 'on_player_eos')
      for source in sources:
          assert source.has_fully_played(), 'Source not fully played'
  
  
  def test_multiple_fire_and_forget_players():
      """
      Test an issue where the driver crashed when starting multiple players, but not keeping a
      reference to these players.
      """
      for _ in range(10):
          Silence(1).play()
      time.sleep(1)
  
  
  [... the rest is omitted ...]
files: tests/integration/media/test_player.py
files: from __future__ import division
  from builtins import range
  from tests import mock
  import random
  from tests.base.future_test import FutureTestCase
  
  from pyglet.media.player import Player, PlayerGroup
  from pyglet.media.codecs.base import AudioFormat, VideoFormat, Source
  
  # pyglet.options['debug_media'] = True
  
  
  class PlayerTestCase(FutureTestCase):
      # Default values to use
      audio_format_1 = AudioFormat(1, 8, 11025)
      audio_format_2 = AudioFormat(2, 8, 11025)
      audio_format_3 = AudioFormat(2, 16, 44100)
      video_format_1 = VideoFormat(800, 600)
      video_format_2 = VideoFormat(1920, 1280)
      video_format_2.frame_rate = 25
  
      def setUp(self):
          self.player = Player()
  
          self._get_audio_driver_patcher = mock.patch('pyglet.media.player.get_audio_driver')
          self.mock_get_audio_driver = self._get_audio_driver_patcher.start()
          self.mock_audio_driver = self.mock_get_audio_driver.return_value
          self.mock_audio_driver_player = self.mock_audio_driver.create_audio_player.return_value
  
          self._clock_patcher = mock.patch('pyglet.clock')
          self.mock_clock = self._clock_patcher.start()
  
          self._texture_patcher = mock.patch('pyglet.image.Texture.create')
          self.mock_texture_create = self._texture_patcher.start()
          self.mock_texture = self.mock_texture_create.return_value
          # Need to do this as side_effect instead of return_value, or reset_mock will recurse
          self.mock_texture.get_transform.side_effect = lambda flip_y: self.mock_texture
  
      def tearDown(self):
          self._get_audio_driver_patcher.stop()
          self._clock_patcher.stop()
          self._texture_patcher.stop()
  
      def reset_mocks(self):
          # These mocks will recursively reset their children
          self.mock_get_audio_driver.reset_mock()
          self.mock_clock.reset_mock()
          self.mock_texture_create.reset_mock()
  
      def create_mock_source(self, audio_format, video_format):
          mock_source = mock.MagicMock(spec=Source)
          type(mock_source).audio_format = mock.PropertyMock(return_value=audio_format)
          type(mock_source).video_format = mock.PropertyMock(return_value=video_format)
          type(mock_source._get_queue_source.return_value).audio_format = mock.PropertyMock(return_value=audio_format)
          type(mock_source._get_queue_source.return_value).video_format = mock.PropertyMock(return_value=video_format)
          if video_format:
              mock_source.video_format.frame_rate = 30
          return mock_source
  
      def set_video_data_for_mock_source(self, mock_source, timestamp_data_pairs):
          """Make the given mock source return video data. Video data is given in pairs of
          timestamp and data to return."""
          def _get_frame():
              if timestamp_data_pairs:
                  current_frame = timestamp_data_pairs.pop(0)
                  return current_frame[1]
  
          def _get_timestamp():
              if timestamp_data_pairs:
                  return timestamp_data_pairs[0][0]
          queue_source = mock_source._get_queue_source.return_value
          queue_source.get_next_video_timestamp.side_effect = _get_timestamp
          queue_source.get_next_video_frame.side_effect = _get_frame
  
      def assert_not_playing_yet(self, current_source=None):
          """Assert the the player did not start playing yet."""
          self.assertFalse(self.mock_get_audio_driver.called, msg='No audio driver required yet')
          self.assertAlmostEqual(self.player.time, 0.)
          self.assert_not_playing(current_source)
  
      def assert_not_playing(self, current_source=None):
          self._assert_playing(False, current_source)
  
      def assert_now_playing(self, current_source):
          self._assert_playing(True, current_source)
  
      def _assert_playing(self, playing, current_source=None):
          self.assertEqual(self.player.playing, playing)
          queued_source = (current_source._get_queue_source.return_value
                           if current_source is not None
                           else None)
          self.assertIs(self.player.source, queued_source)
  
      def assert_driver_player_created_for(self, source):
          """Assert that a driver specific audio player is created to play
  
  [... the rest is omitted ...]
files: tests/unit/media/test_player.py
files: from __future__ import division
  from builtins import range
  import ctypes
  from tests import mock
  import os
  import random
  from collections import deque
  from itertools import product
  from tests.base.future_test import FutureTestCase
  
  import pytest
  
  import pyglet
  from pyglet.media.player import Player, PlayerGroup
  from pyglet.media.codecs.base import *
  
  #pyglet.options['debug_media'] = True
  
  
  class PlayerTestCase(FutureTestCase):
      # Default values to use
      audio_format_1 = AudioFormat(1, 8, 11025)
      audio_format_2 = AudioFormat(2, 8, 11025)
      audio_format_3 = AudioFormat(2, 16, 44100)
      video_format_1 = VideoFormat(800, 600)
      video_format_2 = VideoFormat(1920, 1280)
      video_format_2.frame_rate = 25
  
      def setUp(self):
          self.player = Player()
  
          self._get_audio_driver_patcher = mock.patch('pyglet.media.player.get_audio_driver')
          self.mock_get_audio_driver = self._get_audio_driver_patcher.start()
          self.mock_audio_driver = self.mock_get_audio_driver.return_value
          self.mock_audio_driver_player = self.mock_audio_driver.create_audio_player.return_value
  
          self._clock_patcher = mock.patch('pyglet.clock')
          self.mock_clock = self._clock_patcher.start()
  
          self._texture_patcher = mock.patch('pyglet.image.Texture.create')
          self.mock_texture_create = self._texture_patcher.start()
          self.mock_texture = self.mock_texture_create.return_value
          # Need to do this as side_effect instead of return_value, or reset_mock will recurse
          self.mock_texture.get_transform.side_effect = lambda flip_y: self.mock_texture
  
      def tearDown(self):
          self._get_audio_driver_patcher.stop()
          self._clock_patcher.stop()
          self._texture_patcher.stop()
  
      def reset_mocks(self):
          # These mocks will recursively reset their children
          self.mock_get_audio_driver.reset_mock()
          self.mock_clock.reset_mock()
          self.mock_texture_create.reset_mock()
  
      def create_mock_source(self, audio_format, video_format):
          mock_source = mock.MagicMock(spec=Source)
          type(mock_source).audio_format = mock.PropertyMock(return_value=audio_format)
          type(mock_source).video_format = mock.PropertyMock(return_value=video_format)
          type(mock_source._get_queue_source.return_value).audio_format = mock.PropertyMock(return_value=audio_format)
          type(mock_source._get_queue_source.return_value).video_format = mock.PropertyMock(return_value=video_format)
          if video_format:
              mock_source.video_format.frame_rate = 30
          return mock_source
  
      def set_video_data_for_mock_source(self, mock_source, timestamp_data_pairs):
          """Make the given mock source return video data. Video data is given in pairs of timestamp
          and data to return."""
          def _get_frame():
              if timestamp_data_pairs:
                  current_frame = timestamp_data_pairs.pop(0)
                  return current_frame[1]
          def _get_timestamp():
              if timestamp_data_pairs:
                  return timestamp_data_pairs[0][0]
          queue_source = mock_source._get_queue_source.return_value
          queue_source.get_next_video_timestamp.side_effect = _get_timestamp
          queue_source.get_next_video_frame.side_effect = _get_frame
  
      def assert_not_playing_yet(self, current_source=None):
          """Assert the the player did not start playing yet."""
          self.assertFalse(self.mock_get_audio_driver.called, msg='No audio driver required yet')
          self.assertAlmostEqual(self.player.time, 0.)
          self.assert_not_playing(current_source)
  
      def assert_not_playing(self, current_source=None):
          self._assert_playing(False, current_source)
  
      def assert_now_playing(self, current_source):
          self._assert_playing(True, current_source)
  
      def _assert_playing(self, playing, current_source=None):
          self.assertEqual(self.player.playing, playing)
          queued_source = (current_source._get_queue_source.return_value
                           if current_source is not None
                           else None)
          self.assertIs(self.player.source, queued_source)
  
      def assert_driver_player_created
  
  [... the rest is omitted ...]
files: tests/unit/media/test_player.py