Stop videos playing if no VLC.

#633
This commit is contained in:
Tim Bentley 2020-09-23 08:37:57 +00:00
parent 35c56cecdb
commit 09b57c3cd7
5 changed files with 144 additions and 30 deletions

View File

@ -29,6 +29,7 @@ from threading import Lock
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.state import State
from openlp.core.common import SlideLimits
from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.i18n import UiStrings, translate
@ -1469,24 +1470,26 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
def on_media_start(self, item):
"""
Respond to the arrival of a media service item
Respond to the arrival of a media service item but only run if we have media
:param item: The service item to be processed
"""
if self.is_live and self.get_hide_mode() == HideMode.Theme:
self.media_controller.load_video(self.controller_type, item, HideMode.Blank)
self.set_hide_mode(HideMode.Blank)
elif self.is_live or item.is_media():
# avoid loading the video if this is preview and the media is background
self.media_controller.load_video(self.controller_type, item, self.get_hide_mode())
if not self.is_live:
self.preview_display.show()
if State().check_preconditions('media'):
if self.is_live and self.get_hide_mode() == HideMode.Theme:
self.media_controller.load_video(self.controller_type, item, HideMode.Blank)
self.set_hide_mode(HideMode.Blank)
elif self.is_live or item.is_media():
# avoid loading the video if this is preview and the media is background
self.media_controller.load_video(self.controller_type, item, self.get_hide_mode())
if not self.is_live:
self.preview_display.show()
def on_media_close(self):
"""
Respond to a request to close the Video
Respond to a request to close the Video if we have media
"""
self.media_controller.media_reset(self)
if State().check_preconditions('media'):
self.media_controller.media_reset(self)
def _reset_blank(self, no_theme):
"""

View File

@ -23,7 +23,12 @@ This module is a base to be used for Mac OS X presentation modules using applesc
to control presentation application, such as keynote and powerpoint for mac
"""
import logging
import applescript
try:
import applescript
APPLESCRIPT_AVAILABLE = True
except ImportError:
APPLESCRIPT_AVAILABLE = False
from openlp.core.common import is_macosx
from openlp.core.display.screens import ScreenList
@ -55,7 +60,8 @@ class AppleScriptBaseController(PresentationController):
"""
super(AppleScriptBaseController, self).__init__(plugin, name, doc)
# Script expected to be overwritten by subclasses
self.applescript = applescript.AppleScript(DEFAULT_APPLESCRIPT)
if APPLESCRIPT_AVAILABLE:
self.applescript = applescript.AppleScript(DEFAULT_APPLESCRIPT)
def check_available(self):
"""

View File

@ -23,7 +23,11 @@ This module is for controlling keynote.
"""
import logging
import shutil
import applescript
try:
import applescript
APPLESCRIPT_AVAILABLE = True
except ImportError:
APPLESCRIPT_AVAILABLE = False
from openlp.plugins.presentations.lib.applescriptbasecontroller import AppleScriptBaseController,\
AppleScriptBaseDocument
@ -236,13 +240,14 @@ class KeynoteController(AppleScriptBaseController):
"""
log.debug('Initialising')
super(KeynoteController, self).__init__(plugin, 'Keynote', KeynoteDocument)
# Compiled script expected to be set by subclasses
try:
self.applescript = applescript.AppleScript(KEYNOTE_APPLESCRIPT)
except applescript.ScriptError:
log.exception('Compilation of Keynote applescript failed')
self.supports = ['key']
self.also_supports = ['ppt', 'pps', 'pptx', 'ppsx', 'pptm']
if APPLESCRIPT_AVAILABLE:
# Compiled script expected to be set by subclasses
try:
self.applescript = applescript.AppleScript(KEYNOTE_APPLESCRIPT)
except applescript.ScriptError:
log.exception('Compilation of Keynote applescript failed')
self.supports = ['key']
self.also_supports = ['ppt', 'pps', 'pptx', 'ppsx', 'pptm']
def check_available(self):
"""

View File

@ -22,7 +22,11 @@
This module is for controlling keynote.
"""
import logging
import applescript
try:
import applescript
APPLESCRIPT_AVAILABLE = True
except ImportError:
APPLESCRIPT_AVAILABLE = False
try:
import fitz
@ -277,13 +281,14 @@ class PowerPointMacController(AppleScriptBaseController):
"""
log.debug('Initialising')
super(PowerPointMacController, self).__init__(plugin, 'PowerPointMac', PowerPointMacDocument)
# Compiled script expected to be set by subclasses
try:
self.applescript = applescript.AppleScript(POWERPOINT_MAC_APPLESCRIPT)
except applescript.ScriptError:
log.exception('Compilation of Powerpoint applescript failed')
self.supports = ['ppt', 'pps', 'pptx', 'ppsx', 'pptm']
self.also_supports = ['odp']
if APPLESCRIPT_AVAILABLE:
# Compiled script expected to be set by subclasses
try:
self.applescript = applescript.AppleScript(POWERPOINT_MAC_APPLESCRIPT)
except applescript.ScriptError:
log.exception('Compilation of Powerpoint applescript failed')
self.supports = ['ppt', 'pps', 'pptx', 'ppsx', 'pptm']
self.also_supports = ['odp']
def check_available(self):
"""

View File

@ -25,6 +25,7 @@ from unittest.mock import MagicMock, patch, sentinel
from PyQt5 import QtCore, QtGui
from openlp.core.state import State
from openlp.core.common.registry import Registry
from openlp.core.lib import ServiceItemAction
from openlp.core.ui import HideMode
@ -771,7 +772,7 @@ def test_reload_theme(mock_settings):
@patch.object(Registry, 'execute')
def test_process_item(mocked_execute, registry):
def test_process_item(mocked_execute, registry, state_media):
"""
Test that presentation service-items is closed when followed by a media service-item
"""
@ -818,6 +819,100 @@ def test_process_item(mocked_execute, registry):
'The presentation should have been stopped.'
@patch.object(Registry, 'execute')
def test_process_item_song_vlc(mocked_execute, registry, state_media):
"""
Test that media is started if VLC is present.
"""
# GIVEN: A mocked presentation service item, a mocked media service item, a mocked Registry.execute
# and a slide controller with many mocks.
mocked_pres_item = MagicMock()
mocked_pres_item.name = 'mocked_song_item'
mocked_pres_item.is_command.return_value = False
mocked_pres_item.is_media.return_value = True
mocked_pres_item.is_image.return_value = False
mocked_pres_item.from_service = False
mocked_pres_item.get_frames.return_value = []
mocked_media_item = MagicMock()
mocked_media_item.name = 'mocked_media_item'
mocked_media_item.is_command.return_value = True
mocked_media_item.is_media.return_value = True
mocked_media_item.is_image.return_value = False
mocked_media_item.from_service = False
mocked_media_item.get_frames.return_value = []
mocked_main_window = MagicMock()
Registry().register('main_window', mocked_main_window)
Registry().register('media_controller', MagicMock())
Registry().register('application', MagicMock())
slide_controller = SlideController(None)
slide_controller.service_item = mocked_pres_item
slide_controller.is_live = False
slide_controller.preview_widget = MagicMock()
slide_controller.preview_display = MagicMock()
slide_controller.enable_tool_bar = MagicMock()
slide_controller.slide_selected = MagicMock()
slide_controller.on_stop_loop = MagicMock()
slide_controller.info_label = MagicMock()
slide_controller.displays = [MagicMock()]
slide_controller.split = 0
slide_controller.type_prefix = 'test'
# WHEN: _process_item is called
slide_controller._process_item(mocked_media_item, 0)
# THEN: Registry.execute should have been called to stop the presentation
assert 1 == slide_controller.media_controller.load_video.call_count, ' Load_video should have been called 1 times'
assert 2 == slide_controller.preview_display.load_verses.call_count, 'Execute should have been called 2 times'
@patch.object(Registry, 'execute')
def test_process_item_song_no_vlc(mocked_execute, registry, state_media):
"""
Test that media is started if VLC is present.
"""
# GIVEN: A mocked presentation service item, a mocked media service item, a mocked Registry.execute
# and a slide controller with many mocks.
State().update_pre_conditions("media", False)
State().flush_preconditions()
mocked_pres_item = MagicMock()
mocked_pres_item.name = 'mocked_song_item'
mocked_pres_item.is_command.return_value = False
mocked_pres_item.is_media.return_value = True
mocked_pres_item.is_image.return_value = False
mocked_pres_item.from_service = False
mocked_pres_item.get_frames.return_value = []
mocked_media_item = MagicMock()
mocked_media_item.name = 'mocked_media_item'
mocked_media_item.is_command.return_value = True
mocked_media_item.is_media.return_value = True
mocked_media_item.is_image.return_value = False
mocked_media_item.from_service = False
mocked_media_item.get_frames.return_value = []
mocked_main_window = MagicMock()
Registry().register('main_window', mocked_main_window)
Registry().register('media_controller', MagicMock())
Registry().register('application', MagicMock())
slide_controller = SlideController(None)
slide_controller.service_item = mocked_pres_item
slide_controller.is_live = False
slide_controller.preview_widget = MagicMock()
slide_controller.preview_display = MagicMock()
slide_controller.enable_tool_bar = MagicMock()
slide_controller.slide_selected = MagicMock()
slide_controller.on_stop_loop = MagicMock()
slide_controller.info_label = MagicMock()
slide_controller.displays = [MagicMock()]
slide_controller.split = 0
slide_controller.type_prefix = 'test'
# WHEN: _process_item is called
slide_controller._process_item(mocked_media_item, 0)
# THEN: Registry.execute should have been called to stop the presentation
assert 0 == slide_controller.media_controller.load_video.call_count, ' Load_video should have been called 0 times'
assert 2 == slide_controller.preview_display.load_verses.call_count, 'Execute should have been called 2 times'
def test_live_stolen_focus_shortcuts(settings):
"""
Test that all the needed shortcuts are available in scenarios where Live has stolen focus.