diff --git a/openlp/core/ui/media/__init__.py b/openlp/core/ui/media/__init__.py index 68f2084c0..0a575d035 100644 --- a/openlp/core/ui/media/__init__.py +++ b/openlp/core/ui/media/__init__.py @@ -50,6 +50,21 @@ class MediaState(object): Stopped = 4 +class VlCState(object): + """ + A copy of the VLC States to allow for readable code + From https://www.olivieraubert.net/vlc/python-ctypes/doc/vlc.State-class.html + """ + NothingSpecial = 0 + Opening = 1 + Buffering = 2 + Playing = 3 + Paused = 4 + Stopped = 5 + Ended = 6 + Error = 7 + + class MediaType(object): """ An enumeration of possible Media Types diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index faf0ff6ad..3ea8c87df 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -35,7 +35,7 @@ from openlp.core.common.i18n import translate from openlp.core.common.platform import is_linux, is_macosx, is_win from openlp.core.display.screens import ScreenList from openlp.core.lib.ui import critical_error_message_box -from openlp.core.ui.media import MediaState, MediaType +from openlp.core.ui.media import MediaState, MediaType, VlCState from openlp.core.ui.media.mediaplayer import MediaPlayer log = logging.getLogger(__name__) @@ -43,6 +43,9 @@ log = logging.getLogger(__name__) # Audio and video extensions copied from 'include/vlc_interface.h' from vlc 2.2.0 source +STATE_WAIT_TIME = 60 + + def get_vlc(): """ In order to make this module more testable, we have to wrap the VLC import inside a method. We do this so that we @@ -171,7 +174,6 @@ class VlcPlayer(MediaPlayer): """ if not controller.vlc_instance: return False - vlc = get_vlc() log.debug('load video in VLC Controller') path = None if file and not controller.media_info.media_type == MediaType.Stream: @@ -184,7 +186,7 @@ class VlcPlayer(MediaPlayer): controller.vlc_media_player.set_media(controller.vlc_media) controller.vlc_media_player.play() # Wait for media to start playing. In this case VLC actually returns an error. - self.media_state_wait(controller, vlc.State.Playing) + self.media_state_wait(controller, VlCState.Playing) # If subitems exists, this is a CD audio_cd_tracks = controller.vlc_media.subitems() if not audio_cd_tracks or audio_cd_tracks.count() < 1: @@ -207,7 +209,7 @@ class VlcPlayer(MediaPlayer): controller.vlc_media_player.set_media(controller.vlc_media) controller.vlc_media_player.play() # Wait for media to start playing. In this case VLC returns an error. - self.media_state_wait(controller, vlc.State.Playing) + self.media_state_wait(controller, VlCState.Playing) if controller.media_info.audio_track > 0: res = controller.vlc_media_player.audio_set_track(controller.media_info.audio_track) log.debug('vlc play, audio_track set: ' + str(controller.media_info.audio_track) + ' ' + str(res)) @@ -239,14 +241,13 @@ class VlcPlayer(MediaPlayer): :param controller: The controller where the media is :return: """ - vlc = get_vlc() start = datetime.now() while media_state != controller.vlc_media.get_state(): sleep(0.1) - if controller.vlc_media.get_state() == vlc.State.Error: + if controller.vlc_media.get_state() == VlCState.Error: return False self.application.process_events() - if (datetime.now() - start).seconds > 60: + if (datetime.now() - start).seconds > STATE_WAIT_TIME: return False return True @@ -270,10 +271,9 @@ class VlcPlayer(MediaPlayer): :param output_display: The display where the media is :return: """ - vlc = get_vlc() log.debug('vlc play, mediatype: ' + str(controller.media_info.media_type)) threading.Thread(target=controller.vlc_media_player.play).start() - if not self.media_state_wait(controller, vlc.State.Playing): + if not self.media_state_wait(controller, VlCState.Playing): return False self.volume(controller, controller.media_info.volume) self.set_state(MediaState.Playing, controller) @@ -286,11 +286,10 @@ class VlcPlayer(MediaPlayer): :param controller: The controller which is managing the display :return: """ - vlc = get_vlc() - if controller.vlc_media.get_state() != vlc.State.Playing: + if controller.vlc_media.get_state() != VlCState.Playing: return controller.vlc_media_player.pause() - if self.media_state_wait(controller, vlc.State.Paused): + if self.media_state_wait(controller, VlCState.Paused): self.set_state(MediaState.Paused, controller) def stop(self, controller): diff --git a/tests/openlp_core/ui/media/test_vlcplayer.py b/tests/openlp_core/ui/media/test_vlcplayer.py index 078389226..0774eed9b 100644 --- a/tests/openlp_core/ui/media/test_vlcplayer.py +++ b/tests/openlp_core/ui/media/test_vlcplayer.py @@ -29,7 +29,7 @@ from unittest.mock import MagicMock, call, patch, ANY import pytest from openlp.core.common.registry import Registry -from openlp.core.ui.media import ItemMediaInfo, MediaState, MediaType +from openlp.core.ui.media import ItemMediaInfo, MediaState, MediaType, VlCState from openlp.core.ui.media.vlcplayer import VlcPlayer from tests.helpers import MockDateTime @@ -523,14 +523,14 @@ def test_media_state_wait(mocked_get_vlc): mocked_vlc.State.Error = 1 mocked_get_vlc.return_value = mocked_vlc mocked_controller = MagicMock() - mocked_controller.vlc_media.get_state.return_value = 2 + mocked_controller.vlc_media.get_state.return_value = VlCState.Buffering Registry.create() mocked_application = MagicMock() Registry().register('application', mocked_application) vlc_player = VlcPlayer(None) # WHEN: media_state_wait() is called - result = vlc_player.media_state_wait(mocked_controller, 2) + result = vlc_player.media_state_wait(mocked_controller, VlCState.Buffering) # THEN: The results should be True assert result is True @@ -547,14 +547,14 @@ def test_media_state_wait_error(mocked_get_vlc, vlc_env): mocked_vlc.State.Error = 1 mocked_get_vlc.return_value = mocked_vlc mocked_controller = MagicMock() - mocked_controller.vlc_media.get_state.return_value = 1 + mocked_controller.vlc_media.get_state.return_value = VlCState.Error Registry.create() mocked_application = MagicMock() Registry().register('application', mocked_application) vlc_player = VlcPlayer(None) # WHEN: media_state_wait() is called - result = vlc_player.media_state_wait(mocked_controller, 2) + result = vlc_player.media_state_wait(mocked_controller, VlCState.Buffering) # THEN: The results should be True assert result is False @@ -573,14 +573,14 @@ def test_media_state_wait_times_out(mocked_get_vlc, vlc_env): mocked_vlc.State.Error = 1 mocked_get_vlc.return_value = mocked_vlc mocked_controller = MagicMock() - mocked_controller.vlc_media.get_state.return_value = 2 + mocked_controller.vlc_media.get_state.return_value = VlCState.Buffering Registry.create() mocked_application = MagicMock() Registry().register('application', mocked_application) vlc_player = VlcPlayer(None) # WHEN: media_state_wait() is called - result = vlc_player.media_state_wait(mocked_controller, 3) + result = vlc_player.media_state_wait(mocked_controller, VlCState.Playing) # THEN: The results should be True assert result is False @@ -672,11 +672,11 @@ def test_pause(mocked_get_vlc): """ # GIVEN: A mocked out get_vlc method mocked_vlc = MagicMock() - mocked_vlc.State.Playing = 1 - mocked_vlc.State.Paused = 2 + mocked_vlc.State.Playing = VlCState.Playing + mocked_vlc.State.Paused = VlCState.Paused mocked_get_vlc.return_value = mocked_vlc mocked_display = MagicMock() - mocked_display.vlc_media.get_state.return_value = 1 + mocked_display.vlc_media.get_state.return_value = VlCState.Playing vlc_player = VlcPlayer(None) # WHEN: The media is paused @@ -687,7 +687,7 @@ def test_pause(mocked_get_vlc): # THEN: The pause method should exit early mocked_display.vlc_media.get_state.assert_called_with() mocked_display.vlc_media_player.pause.assert_called_with() - mocked_media_state_wait.assert_called_with(mocked_display, 2) + mocked_media_state_wait.assert_called_with(mocked_display, VlCState.Paused) assert MediaState.Paused == vlc_player.get_live_state() @@ -701,7 +701,7 @@ def test_pause_not_playing(mocked_get_vlc): mocked_vlc.State.Playing = 1 mocked_get_vlc.return_value = mocked_vlc mocked_display = MagicMock() - mocked_display.vlc_media.get_state.return_value = 2 + mocked_display.vlc_media.get_state.return_value = VlCState.Paused vlc_player = VlcPlayer(None) # WHEN: The media is paused @@ -723,7 +723,7 @@ def test_pause_fail(mocked_get_vlc): mocked_vlc.State.Paused = 2 mocked_get_vlc.return_value = mocked_vlc mocked_display = MagicMock() - mocked_display.vlc_media.get_state.return_value = 1 + mocked_display.vlc_media.get_state.return_value = VlCState.Playing vlc_player = VlcPlayer(None) # WHEN: The media is paused @@ -734,7 +734,7 @@ def test_pause_fail(mocked_get_vlc): # THEN: The pause method should exit early mocked_display.vlc_media.get_state.assert_called_with() mocked_display.vlc_media_player.pause.assert_called_with() - mocked_media_state_wait.assert_called_with(mocked_display, 2) + mocked_media_state_wait.assert_called_with(mocked_display, VlCState.Paused) assert MediaState.Paused is not vlc_player.state