Merge branch 'fedora-vlc-instructions' into 'master'

Display more detailed instructions when VLC and pymediainfo are missing

See merge request openlp/openlp!96
This commit is contained in:
Tim Bentley 2019-12-07 11:41:30 +00:00
commit 72bd9999eb
3 changed files with 149 additions and 21 deletions

View File

@ -385,17 +385,12 @@ def main():
application.setApplicationName('OpenLP') application.setApplicationName('OpenLP')
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir)) set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
# Set the libvlc environment variable if we're frozen # Set the libvlc environment variable if we're frozen
if getattr(sys, 'frozen', False): if getattr(sys, 'frozen', False) and is_win():
if is_macosx(): # Path to libvlc and the plugins
vlc_lib = 'libvlc.dylib' os.environ['PYTHON_VLC_LIB_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc' / 'libvlc.dll')
elif is_win():
vlc_lib = 'libvlc.dll'
# Path to libvlc
os.environ['PYTHON_VLC_LIB_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc' / vlc_lib)
log.debug('VLC Path: {}'.format(os.environ['PYTHON_VLC_LIB_PATH']))
# Path to VLC directory containing VLC's "plugins" directory
os.environ['PYTHON_VLC_MODULE_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc') os.environ['PYTHON_VLC_MODULE_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc')
log.debug('VLC Path: {}'.format(os.environ['PYTHON_VLC_LIB_PATH'])) log.debug('VLC Path: {}'.format(os.environ['PYTHON_VLC_LIB_PATH']))
log.debug('VLC Plugins Path: {}'.format(os.environ['PYTHON_VLC_MODULE_PATH']))
# Initialise the Registry # Initialise the Registry
Registry.create() Registry.create()
Registry().register('application', application) Registry().register('application', application)

View File

@ -34,6 +34,7 @@ from PyQt5 import QtCore
from openlp.core.state import State from openlp.core.state import State
from openlp.core.api.http import register_endpoint from openlp.core.api.http import register_endpoint
from openlp.core.common import is_linux, is_macosx
from openlp.core.common.i18n import translate from openlp.core.common.i18n import translate
from openlp.core.common.mixins import LogMixin, RegistryProperties from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.registry import Registry, RegistryBase from openlp.core.common.registry import Registry, RegistryBase
@ -89,23 +90,35 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
self.vlc_player = VlcPlayer(self) self.vlc_player = VlcPlayer(self)
State().add_service('mediacontroller', 0) State().add_service('mediacontroller', 0)
State().add_service('media_live', 0) State().add_service('media_live', 0)
getvlc = get_vlc() has_vlc = get_vlc()
if getvlc and pymediainfo_available: if has_vlc and pymediainfo_available:
State().update_pre_conditions('mediacontroller', True) State().update_pre_conditions('mediacontroller', True)
State().update_pre_conditions('media_live', True) State().update_pre_conditions('media_live', True)
else: else:
if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible(): if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible():
self.main_window.splash.hide() self.main_window.splash.hide()
text_vlc = translate('OpenLP.MediaController', generic_message = translate('OpenLP.MediaController',
'The media integration library is missing (python - vlc is not installed)') 'OpenLP requires the following libraries in order to show videos and other '
text_info = translate('OpenLP.MediaController', 'media, but they are not installed. Please install these libraries to enable '
'The media integration library is missing (python - pymediainfo is not installed)') 'media playback in OpenLP.')
if not getvlc and not pymediainfo_available: fedora_rpmfusion = translate('OpenLP.MediaController',
State().missing_text('media_live', "{text}\n{base}".format(text=text_vlc, base=text_info)) 'To install these libraries, you will need to enable the RPMFusion '
if getvlc and not pymediainfo_available: 'repository: https://rpmfusion.org/')
State().missing_text('media_live', "{text}".format(text=text_info)) message = ''
if not getvlc and pymediainfo_available: if is_macosx():
State().missing_text('media_live', "{text}".format(text=text_vlc)) message = translate('OpenLP.MediaController',
'macOS is missing VLC. Please download and install from the VLC web site: '
'https://www.videolan.org/vlc/')
else:
packages = []
if not has_vlc:
packages.append('python3-vlc')
if not pymediainfo_available:
packages.append('python3-pymediainfo')
message = generic_message + '\n\n' + ', '.join(packages)
if not has_vlc and is_linux(distro='fedora'):
message += '\n\n' + fedora_rpmfusion
State().missing_text('media_live', message)
return True return True
def bootstrap_post_set_up(self): def bootstrap_post_set_up(self):

View File

@ -25,6 +25,7 @@ from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.ui import DisplayControllerType
from openlp.core.ui.media.mediacontroller import MediaController from openlp.core.ui.media.mediacontroller import MediaController
from openlp.core.ui.media import ItemMediaInfo from openlp.core.ui.media import ItemMediaInfo
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
@ -202,3 +203,122 @@ class TestMediaController(TestCase, TestMixin):
# THEN you can determine the run time # THEN you can determine the run time
assert results == test_data[1], 'The correct duration is returned for ' + test_data[0] assert results == test_data[1], 'The correct duration is returned for ' + test_data[0]
def test_on_media_play(self):
"""
Test the on_media_play method
"""
# GIVEN: A mocked live controller and a mocked media_play() method
mocked_live_controller = MagicMock()
Registry().register('live_controller', mocked_live_controller)
media_controller = MediaController()
media_controller.media_play = MagicMock()
# WHEN: the on_media_play() method is called
media_controller.on_media_play()
# The mocked live controller should be called
media_controller.media_play.assert_called_once_with(mocked_live_controller, False)
def test_on_media_pause(self):
"""
Test the on_media_pause method
"""
# GIVEN: A mocked live controller and a mocked media_pause() method
mocked_live_controller = MagicMock()
Registry().register('live_controller', mocked_live_controller)
media_controller = MediaController()
media_controller.media_pause = MagicMock()
# WHEN: the on_media_pause() method is called
media_controller.on_media_pause()
# The mocked live controller should be called
media_controller.media_pause.assert_called_once_with(mocked_live_controller)
def test_on_media_stop(self):
"""
Test the on_media_stop method
"""
# GIVEN: A mocked live controller and a mocked media_stop() method
mocked_live_controller = MagicMock()
Registry().register('live_controller', mocked_live_controller)
media_controller = MediaController()
media_controller.media_stop = MagicMock()
# WHEN: the on_media_stop() method is called
media_controller.on_media_stop()
# The mocked live controller should be called
media_controller.media_stop.assert_called_once_with(mocked_live_controller)
def test_display_controllers_live(self):
"""
Test that the display_controllers() method returns the live controller when requested
"""
# GIVEN: A mocked live controller
media_controller = MediaController()
mocked_live_controller = MagicMock()
mocked_preview_controller = MagicMock()
Registry().register('live_controller', mocked_live_controller)
Registry().register('preview_controller', mocked_preview_controller)
# WHEN: display_controllers() is called with DisplayControllerType.Live
controller = media_controller.display_controllers(DisplayControllerType.Live)
# THEN: the controller should be the live controller
assert controller is mocked_live_controller
def test_display_controllers_preview(self):
"""
Test that the display_controllers() method returns the preview controller when requested
"""
# GIVEN: A mocked live controller
media_controller = MediaController()
mocked_live_controller = MagicMock()
mocked_preview_controller = MagicMock()
Registry().register('live_controller', mocked_live_controller)
Registry().register('preview_controller', mocked_preview_controller)
# WHEN: display_controllers() is called with DisplayControllerType.Preview
controller = media_controller.display_controllers(DisplayControllerType.Preview)
# THEN: the controller should be the live controller
assert controller is mocked_preview_controller
def test_set_controls_visible(self):
"""
Test that "set_controls_visible" sets the media controls on the controller to be visible or not
"""
# GIVEN: A mocked controller
mocked_controller = MagicMock()
# WHEN: Set to visible
MediaController.set_controls_visible(mocked_controller, True)
# THEN: The media controls should have been set to visible
mocked_controller.mediabar.setVisible.assert_called_once_with(True)
@patch('openlp.core.ui.media.mediacontroller.ItemMediaInfo')
def test_setup_display(self, MockItemMediaInfo):
"""
Test that the display/controllers are set up correctly
"""
# GIVEN: A media controller object and some mocks
mocked_media_info = MagicMock()
MockItemMediaInfo.return_value = mocked_media_info
media_controller = MediaController()
media_controller.vlc_player = MagicMock()
mocked_display = MagicMock()
media_controller._define_display = MagicMock(return_value=mocked_display)
media_controller.vlc_player = MagicMock()
controller = MagicMock()
# WHEN: setup_display() is called
media_controller.setup_display(controller, True)
# THEN: The right calls should have been made
assert controller.media_info == mocked_media_info
assert controller.has_audio is False
media_controller._define_display.assert_called_once_with(controller)
media_controller.vlc_player.setup(controller, mocked_display, False)