forked from openlp/openlp
Media is now playing again - just
This commit is contained in:
parent
fc579f120a
commit
112fac8baf
@ -23,7 +23,6 @@
|
|||||||
The :mod:`~openlp.core.ui.media.mediacontroller` module contains a base class for media components and other widgets
|
The :mod:`~openlp.core.ui.media.mediacontroller` module contains a base class for media components and other widgets
|
||||||
related to playing media, such as sliders.
|
related to playing media, such as sliders.
|
||||||
"""
|
"""
|
||||||
import datetime
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -33,7 +32,7 @@ except ImportError:
|
|||||||
pymediainfo_available = False
|
pymediainfo_available = False
|
||||||
|
|
||||||
from subprocess import check_output
|
from subprocess import check_output
|
||||||
from PyQt5 import QtCore, QtWidgets
|
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
|
||||||
@ -44,11 +43,9 @@ from openlp.core.common.settings import Settings
|
|||||||
from openlp.core.lib.serviceitem import ItemCapabilities
|
from openlp.core.lib.serviceitem import ItemCapabilities
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.ui import DisplayControllerType
|
from openlp.core.ui import DisplayControllerType
|
||||||
from openlp.core.ui.icons import UiIcons
|
|
||||||
from openlp.core.ui.media import MediaState, ItemMediaInfo, MediaType, parse_optical_path
|
from openlp.core.ui.media import MediaState, ItemMediaInfo, MediaType, parse_optical_path
|
||||||
from openlp.core.ui.media.endpoint import media_endpoint
|
from openlp.core.ui.media.endpoint import media_endpoint
|
||||||
from openlp.core.ui.media.vlcplayer import VlcPlayer, get_vlc
|
from openlp.core.ui.media.vlcplayer import VlcPlayer, get_vlc
|
||||||
from openlp.core.widgets.toolbar import OpenLPToolbar
|
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -56,45 +53,6 @@ log = logging.getLogger(__name__)
|
|||||||
TICK_TIME = 200
|
TICK_TIME = 200
|
||||||
|
|
||||||
|
|
||||||
class MediaSlider(QtWidgets.QSlider):
|
|
||||||
"""
|
|
||||||
Allows the mouse events of a slider to be overridden and extra functionality added
|
|
||||||
"""
|
|
||||||
def __init__(self, direction, manager, controller):
|
|
||||||
"""
|
|
||||||
Constructor
|
|
||||||
"""
|
|
||||||
super(MediaSlider, self).__init__(direction)
|
|
||||||
self.manager = manager
|
|
||||||
self.controller = controller
|
|
||||||
|
|
||||||
def mouseMoveEvent(self, event):
|
|
||||||
"""
|
|
||||||
Override event to allow hover time to be displayed.
|
|
||||||
|
|
||||||
:param event: The triggering event
|
|
||||||
"""
|
|
||||||
time_value = QtWidgets.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
|
|
||||||
self.setToolTip('%s' % datetime.timedelta(seconds=int(time_value / 1000)))
|
|
||||||
QtWidgets.QSlider.mouseMoveEvent(self, event)
|
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
|
||||||
"""
|
|
||||||
Mouse Press event no new functionality
|
|
||||||
:param event: The triggering event
|
|
||||||
"""
|
|
||||||
QtWidgets.QSlider.mousePressEvent(self, event)
|
|
||||||
|
|
||||||
def mouseReleaseEvent(self, event):
|
|
||||||
"""
|
|
||||||
Set the slider position when the mouse is clicked and released on the slider.
|
|
||||||
|
|
||||||
:param event: The triggering event
|
|
||||||
"""
|
|
||||||
self.setValue(QtWidgets.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width()))
|
|
||||||
QtWidgets.QSlider.mouseReleaseEvent(self, event)
|
|
||||||
|
|
||||||
|
|
||||||
class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||||
"""
|
"""
|
||||||
The implementation of the Media Controller. The Media Controller adds an own class for every Player.
|
The implementation of the Media Controller. The Media Controller adds an own class for every Player.
|
||||||
@ -116,7 +74,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.vlc_player = None
|
self.vlc_player = None
|
||||||
self.display_controllers = {}
|
|
||||||
self.current_media_players = {}
|
self.current_media_players = {}
|
||||||
# Timer for video state
|
# Timer for video state
|
||||||
self.live_timer = QtCore.QTimer()
|
self.live_timer = QtCore.QTimer()
|
||||||
@ -176,109 +133,58 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
self._generate_extensions_lists()
|
self._generate_extensions_lists()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def bootstrap_post_set_up(self):
|
||||||
|
"""
|
||||||
|
Set up the controllers.
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self.setup_display(self.live_controller.display, False)
|
||||||
|
self.setup_display(self.preview_controller.preview_display, True)
|
||||||
|
|
||||||
|
def display_controllers(self, controller_type):
|
||||||
|
"""
|
||||||
|
Decides which controller to use.
|
||||||
|
|
||||||
|
:param controller_type: The controller type where a player will be placed
|
||||||
|
"""
|
||||||
|
if controller_type == DisplayControllerType.Live:
|
||||||
|
return self.live_controller
|
||||||
|
else:
|
||||||
|
return self.preview_controller
|
||||||
|
|
||||||
def media_state_live(self):
|
def media_state_live(self):
|
||||||
"""
|
"""
|
||||||
Check if there is a running Live media Player and do updating stuff (e.g. update the UI)
|
Check if there is a running Live media Player and do updating stuff (e.g. update the UI)
|
||||||
"""
|
"""
|
||||||
display = self._define_display(self.display_controllers[DisplayControllerType.Live])
|
display = self._define_display(self.display_controllers(DisplayControllerType.Live))
|
||||||
if DisplayControllerType.Live in self.current_media_players:
|
if DisplayControllerType.Live in self.current_media_players:
|
||||||
self.current_media_players[DisplayControllerType.Live].resize(display)
|
self.current_media_players[DisplayControllerType.Live].resize(display)
|
||||||
self.current_media_players[DisplayControllerType.Live].update_ui(display)
|
self.current_media_players[DisplayControllerType.Live].update_ui(self.live_controller, display)
|
||||||
self.tick(self.display_controllers[DisplayControllerType.Live])
|
self.tick(self.display_controllers(DisplayControllerType.Live))
|
||||||
if self.current_media_players[DisplayControllerType.Live].get_live_state() is not MediaState.Playing:
|
if self.current_media_players[DisplayControllerType.Live].get_live_state() is not MediaState.Playing:
|
||||||
self.live_timer.stop()
|
self.live_timer.stop()
|
||||||
else:
|
else:
|
||||||
self.live_timer.stop()
|
self.live_timer.stop()
|
||||||
self.media_stop(self.display_controllers[DisplayControllerType.Live])
|
self.media_stop(self.display_controllers(DisplayControllerType.Live))
|
||||||
if self.display_controllers[DisplayControllerType.Live].media_info.can_loop_playback:
|
if self.display_controllers(DisplayControllerType.Live).media_info.can_loop_playback:
|
||||||
self.media_play(self.display_controllers[DisplayControllerType.Live], True)
|
self.media_play(self.display_controllers(DisplayControllerType.Live), True)
|
||||||
|
|
||||||
def media_state_preview(self):
|
def media_state_preview(self):
|
||||||
"""
|
"""
|
||||||
Check if there is a running Preview media Player and do updating stuff (e.g. update the UI)
|
Check if there is a running Preview media Player and do updating stuff (e.g. update the UI)
|
||||||
"""
|
"""
|
||||||
display = self._define_display(self.display_controllers[DisplayControllerType.Preview])
|
display = self._define_display(self.display_controllers(DisplayControllerType.Preview))
|
||||||
if DisplayControllerType.Preview in self.current_media_players:
|
if DisplayControllerType.Preview in self.current_media_players:
|
||||||
self.current_media_players[DisplayControllerType.Preview].resize(display)
|
self.current_media_players[DisplayControllerType.Preview].resize(display)
|
||||||
self.current_media_players[DisplayControllerType.Preview].update_ui(display)
|
self.current_media_players[DisplayControllerType.Preview].update_ui(self.preview_controller, display)
|
||||||
self.tick(self.display_controllers[DisplayControllerType.Preview])
|
self.tick(self.display_controllers(DisplayControllerType.Preview))
|
||||||
if self.current_media_players[DisplayControllerType.Preview].get_preview_state() is not MediaState.Playing:
|
if self.current_media_players[DisplayControllerType.Preview].get_preview_state() is not MediaState.Playing:
|
||||||
self.preview_timer.stop()
|
self.preview_timer.stop()
|
||||||
else:
|
else:
|
||||||
self.preview_timer.stop()
|
self.preview_timer.stop()
|
||||||
self.media_stop(self.display_controllers[DisplayControllerType.Preview])
|
self.media_stop(self.display_controllers(DisplayControllerType.Preview))
|
||||||
if self.display_controllers[DisplayControllerType.Preview].media_info.can_loop_playback:
|
if self.display_controllers(DisplayControllerType.Preview).media_info.can_loop_playback:
|
||||||
self.media_play(self.display_controllers[DisplayControllerType.Preview], True)
|
self.media_play(self.display_controllers(DisplayControllerType.Preview), True)
|
||||||
|
|
||||||
def register_controller(self, controller):
|
|
||||||
"""
|
|
||||||
Registers media controls where the players will be placed to run.
|
|
||||||
|
|
||||||
:param controller: The controller where a player will be placed
|
|
||||||
"""
|
|
||||||
self.display_controllers[controller.controller_type] = controller
|
|
||||||
self.setup_generic_controls(controller)
|
|
||||||
|
|
||||||
def setup_generic_controls(self, controller):
|
|
||||||
"""
|
|
||||||
Set up controls on the control_panel for a given controller
|
|
||||||
|
|
||||||
:param controller: First element is the controller which should be used
|
|
||||||
"""
|
|
||||||
controller.media_info = ItemMediaInfo()
|
|
||||||
# Build a Media ToolBar
|
|
||||||
controller.mediabar = OpenLPToolbar(controller)
|
|
||||||
controller.mediabar.add_toolbar_action('playbackPlay', text='media_playback_play',
|
|
||||||
icon=UiIcons().play,
|
|
||||||
tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
|
|
||||||
triggers=controller.send_to_plugins)
|
|
||||||
controller.mediabar.add_toolbar_action('playbackPause', text='media_playback_pause',
|
|
||||||
icon=UiIcons().pause,
|
|
||||||
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
|
|
||||||
triggers=controller.send_to_plugins)
|
|
||||||
controller.mediabar.add_toolbar_action('playbackStop', text='media_playback_stop',
|
|
||||||
icon=UiIcons().stop,
|
|
||||||
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
|
|
||||||
triggers=controller.send_to_plugins)
|
|
||||||
controller.mediabar.add_toolbar_action('playbackLoop', text='media_playback_loop',
|
|
||||||
icon=UiIcons().repeat, checked=False,
|
|
||||||
tooltip=translate('OpenLP.SlideController', 'Loop playing media.'),
|
|
||||||
triggers=controller.send_to_plugins)
|
|
||||||
controller.position_label = QtWidgets.QLabel()
|
|
||||||
controller.position_label.setText(' 00:00 / 00:00')
|
|
||||||
controller.position_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
|
||||||
controller.position_label.setToolTip(translate('OpenLP.SlideController', 'Video timer.'))
|
|
||||||
controller.position_label.setMinimumSize(90, 0)
|
|
||||||
controller.position_label.setObjectName('position_label')
|
|
||||||
controller.mediabar.add_toolbar_widget(controller.position_label)
|
|
||||||
# Build the seek_slider.
|
|
||||||
controller.seek_slider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
|
|
||||||
controller.seek_slider.setMaximum(1000)
|
|
||||||
controller.seek_slider.setTracking(True)
|
|
||||||
controller.seek_slider.setMouseTracking(True)
|
|
||||||
controller.seek_slider.setToolTip(translate('OpenLP.SlideController', 'Video position.'))
|
|
||||||
controller.seek_slider.setGeometry(QtCore.QRect(90, 260, 221, 24))
|
|
||||||
controller.seek_slider.setObjectName('seek_slider')
|
|
||||||
controller.mediabar.add_toolbar_widget(controller.seek_slider)
|
|
||||||
# Build the volume_slider.
|
|
||||||
controller.volume_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
|
|
||||||
controller.volume_slider.setTickInterval(10)
|
|
||||||
controller.volume_slider.setTickPosition(QtWidgets.QSlider.TicksAbove)
|
|
||||||
controller.volume_slider.setMinimum(0)
|
|
||||||
controller.volume_slider.setMaximum(100)
|
|
||||||
controller.volume_slider.setTracking(True)
|
|
||||||
controller.volume_slider.setToolTip(translate('OpenLP.SlideController', 'Audio Volume.'))
|
|
||||||
controller.volume_slider.setValue(controller.media_info.volume)
|
|
||||||
controller.volume_slider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
|
||||||
controller.volume_slider.setObjectName('volume_slider')
|
|
||||||
controller.mediabar.add_toolbar_widget(controller.volume_slider)
|
|
||||||
controller.controller_layout.addWidget(controller.mediabar)
|
|
||||||
controller.mediabar.setVisible(False)
|
|
||||||
if not controller.is_live:
|
|
||||||
controller.volume_slider.setEnabled(False)
|
|
||||||
# Signals
|
|
||||||
controller.seek_slider.valueChanged.connect(controller.send_to_plugins)
|
|
||||||
controller.volume_slider.valueChanged.connect(controller.send_to_plugins)
|
|
||||||
|
|
||||||
def setup_display(self, display, preview):
|
def setup_display(self, display, preview):
|
||||||
"""
|
"""
|
||||||
@ -287,14 +193,13 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
:param display: Display on which the output is to be played
|
:param display: Display on which the output is to be played
|
||||||
:param preview: Whether the display is a main or preview display
|
:param preview: Whether the display is a main or preview display
|
||||||
"""
|
"""
|
||||||
# clean up possible running old media files
|
display.media_info = ItemMediaInfo()
|
||||||
self.finalise()
|
|
||||||
display.has_audio = True
|
display.has_audio = True
|
||||||
if display.is_live and preview:
|
# if display.is_live and preview:
|
||||||
return
|
# return
|
||||||
if preview:
|
if preview:
|
||||||
display.has_audio = False
|
display.has_audio = False
|
||||||
self.vlc_player.setup(display)
|
self.vlc_player.setup(display, preview)
|
||||||
|
|
||||||
def set_controls_visible(self, controller, value):
|
def set_controls_visible(self, controller, value):
|
||||||
"""
|
"""
|
||||||
@ -305,9 +210,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
# Generic controls
|
# Generic controls
|
||||||
controller.mediabar.setVisible(value)
|
controller.mediabar.setVisible(value)
|
||||||
if controller.is_live and controller.display:
|
#if controller.is_live and controller.display:
|
||||||
if self.current_media_players and value:
|
#if self.current_media_players and value:
|
||||||
controller.display.set_transparency(False)
|
# controller.display.set_transparency(False)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def resize(display, player):
|
def resize(display, player):
|
||||||
@ -319,7 +224,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
player.resize(display)
|
player.resize(display)
|
||||||
|
|
||||||
def video(self, source, service_item, hidden=False, video_behind_text=False):
|
def load_video(self, source, service_item, hidden=False, video_behind_text=False):
|
||||||
"""
|
"""
|
||||||
Loads and starts a video to run with the option of sound
|
Loads and starts a video to run with the option of sound
|
||||||
|
|
||||||
@ -329,7 +234,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
:param video_behind_text: Is the video to be played behind text.
|
:param video_behind_text: Is the video to be played behind text.
|
||||||
"""
|
"""
|
||||||
is_valid = True
|
is_valid = True
|
||||||
controller = self.display_controllers[source]
|
controller = self.display_controllers(source)
|
||||||
# stop running videos
|
# stop running videos
|
||||||
self.media_reset(controller)
|
self.media_reset(controller)
|
||||||
controller.media_info = ItemMediaInfo()
|
controller.media_info = ItemMediaInfo()
|
||||||
@ -354,8 +259,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
log.debug('video is not optical and live')
|
log.debug('video is not optical and live')
|
||||||
controller.media_info.length = service_item.media_length
|
controller.media_info.length = service_item.media_length
|
||||||
is_valid = self._check_file_type(controller, display)
|
is_valid = self._check_file_type(controller, display)
|
||||||
display.override['theme'] = ''
|
#display.override['theme'] = ''
|
||||||
display.override['video'] = True
|
#display.override['video'] = True
|
||||||
if controller.media_info.is_background:
|
if controller.media_info.is_background:
|
||||||
# ignore start/end time
|
# ignore start/end time
|
||||||
controller.media_info.start_time = 0
|
controller.media_info.start_time = 0
|
||||||
@ -381,8 +286,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
return False
|
return False
|
||||||
log.debug('video media type: ' + str(controller.media_info.media_type))
|
log.debug('video media type: ' + str(controller.media_info.media_type))
|
||||||
# dont care about actual theme, set a black background
|
# dont care about actual theme, set a black background
|
||||||
if controller.is_live and not controller.media_info.is_background:
|
#if controller.is_live and not controller.media_info.is_background:
|
||||||
display.frame.runJavaScript('show_video("setBackBoard", null, null,"visible");')
|
# display.frame.runJavaScript('show_video("setBackBoard", null, null,"visible");')
|
||||||
# now start playing - Preview is autoplay!
|
# now start playing - Preview is autoplay!
|
||||||
autoplay = False
|
autoplay = False
|
||||||
# Preview requested
|
# Preview requested
|
||||||
@ -471,28 +376,26 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
for file in controller.media_info.file_info:
|
for file in controller.media_info.file_info:
|
||||||
if file.is_file:
|
if file.is_file:
|
||||||
suffix = '*%s' % file.suffix.lower()
|
suffix = '*%s' % file.suffix.lower()
|
||||||
player = self.vlc_player
|
|
||||||
file = str(file)
|
file = str(file)
|
||||||
if suffix in player.video_extensions_list:
|
if suffix in self.vlc_player.video_extensions_list:
|
||||||
if not controller.media_info.is_background or controller.media_info.is_background and \
|
if not controller.media_info.is_background or controller.media_info.is_background and \
|
||||||
player.can_background:
|
self.vlc_player.can_background:
|
||||||
self.resize(display, player)
|
self.resize(display, self.vlc_player)
|
||||||
if player.load(display, file):
|
if self.vlc_player.load(display, file):
|
||||||
self.current_media_players[controller.controller_type] = player
|
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||||
controller.media_info.media_type = MediaType.Video
|
controller.media_info.media_type = MediaType.Video
|
||||||
return True
|
return True
|
||||||
if suffix in player.audio_extensions_list:
|
if suffix in self.vlc_player.audio_extensions_list:
|
||||||
if player.load(display, file):
|
if self.vlc_player.load(display, file):
|
||||||
self.current_media_players[controller.controller_type] = player
|
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||||
controller.media_info.media_type = MediaType.Audio
|
controller.media_info.media_type = MediaType.Audio
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
player = self.vlc_player
|
|
||||||
file = str(file)
|
file = str(file)
|
||||||
if player.can_folder:
|
if self.vlc_player.can_folder:
|
||||||
self.resize(display, player)
|
self.resize(display, self.vlc_player)
|
||||||
if player.load(display, file):
|
if self.vlc_player.load(display, file):
|
||||||
self.current_media_players[controller.controller_type] = player
|
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||||
controller.media_info.media_type = MediaType.Video
|
controller.media_info.media_type = MediaType.Video
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@ -509,8 +412,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
def on_media_play(self):
|
def on_media_play(self):
|
||||||
"""
|
"""
|
||||||
Responds to the request to play a loaded video from the web.
|
Responds to the request to play a loaded video from the web.
|
||||||
|
|
||||||
:param msg: First element is the controller which should be used
|
|
||||||
"""
|
"""
|
||||||
self.media_play(Registry().get('live_controller'), False)
|
self.media_play(Registry().get('live_controller'), False)
|
||||||
|
|
||||||
@ -524,7 +425,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
controller.seek_slider.blockSignals(True)
|
controller.seek_slider.blockSignals(True)
|
||||||
controller.volume_slider.blockSignals(True)
|
controller.volume_slider.blockSignals(True)
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
if not self.current_media_players[controller.controller_type].play(display):
|
if not self.current_media_players[controller.controller_type].play(controller, display):
|
||||||
controller.seek_slider.blockSignals(False)
|
controller.seek_slider.blockSignals(False)
|
||||||
controller.volume_slider.blockSignals(False)
|
controller.volume_slider.blockSignals(False)
|
||||||
return False
|
return False
|
||||||
@ -533,8 +434,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
else:
|
else:
|
||||||
self.media_volume(controller, controller.media_info.volume)
|
self.media_volume(controller, controller.media_info.volume)
|
||||||
if first_time:
|
if first_time:
|
||||||
if not controller.media_info.is_background:
|
#if not controller.media_info.is_background:
|
||||||
display.frame.runJavaScript('show_blank("desktop");')
|
# display.frame.runJavaScript('show_blank("desktop");')
|
||||||
self.current_media_players[controller.controller_type].set_visible(display, True)
|
self.current_media_players[controller.controller_type].set_visible(display, True)
|
||||||
controller.mediabar.actions['playbackPlay'].setVisible(False)
|
controller.mediabar.actions['playbackPlay'].setVisible(False)
|
||||||
controller.mediabar.actions['playbackPause'].setVisible(True)
|
controller.mediabar.actions['playbackPause'].setVisible(True)
|
||||||
@ -591,8 +492,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
def on_media_pause(self):
|
def on_media_pause(self):
|
||||||
"""
|
"""
|
||||||
Responds to the request to pause a loaded video from the web.
|
Responds to the request to pause a loaded video from the web.
|
||||||
|
|
||||||
:param msg: First element is the controller which should be used
|
|
||||||
"""
|
"""
|
||||||
self.media_pause(Registry().get('live_controller'))
|
self.media_pause(Registry().get('live_controller'))
|
||||||
|
|
||||||
@ -639,8 +538,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
def on_media_stop(self):
|
def on_media_stop(self):
|
||||||
"""
|
"""
|
||||||
Responds to the request to stop a loaded video from the web.
|
Responds to the request to stop a loaded video from the web.
|
||||||
|
|
||||||
:param msg: First element is the controller which should be used
|
|
||||||
"""
|
"""
|
||||||
self.media_stop(Registry().get('live_controller'))
|
self.media_stop(Registry().get('live_controller'))
|
||||||
|
|
||||||
@ -653,8 +550,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
if controller.controller_type in self.current_media_players:
|
if controller.controller_type in self.current_media_players:
|
||||||
if not looping_background:
|
#if not looping_background:
|
||||||
display.frame.runJavaScript('show_blank("black");')
|
# display.frame.runJavaScript('show_blank("black");')
|
||||||
self.current_media_players[controller.controller_type].stop(display)
|
self.current_media_players[controller.controller_type].stop(display)
|
||||||
self.current_media_players[controller.controller_type].set_visible(display, False)
|
self.current_media_players[controller.controller_type].set_visible(display, False)
|
||||||
controller.seek_slider.setSliderPosition(0)
|
controller.seek_slider.setSliderPosition(0)
|
||||||
@ -725,7 +622,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
display.override = {}
|
display.override = {}
|
||||||
self.current_media_players[controller.controller_type].reset(display)
|
self.current_media_players[controller.controller_type].reset(display)
|
||||||
self.current_media_players[controller.controller_type].set_visible(display, False)
|
self.current_media_players[controller.controller_type].set_visible(display, False)
|
||||||
display.frame.runJavaScript('show_video("setBackBoard", null, null, "hidden");')
|
# display.frame.runJavaScript('show_video("setBackBoard", null, null, "hidden");')
|
||||||
del self.current_media_players[controller.controller_type]
|
del self.current_media_players[controller.controller_type]
|
||||||
|
|
||||||
def media_hide(self, msg):
|
def media_hide(self, msg):
|
||||||
@ -788,8 +685,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
self.live_timer.stop()
|
self.live_timer.stop()
|
||||||
self.preview_timer.stop()
|
self.preview_timer.stop()
|
||||||
for controller in self.display_controllers:
|
self.media_reset(self.display_controllers(DisplayControllerType.Live))
|
||||||
self.media_reset(self.display_controllers[controller])
|
self.media_reset(self.display_controllers(DisplayControllerType.Preview))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _define_display(controller):
|
def _define_display(controller):
|
||||||
|
@ -52,11 +52,12 @@ class MediaPlayer(RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def setup(self, display):
|
def setup(self, display, live_display):
|
||||||
"""
|
"""
|
||||||
Create the related widgets for the current display
|
Create the related widgets for the current display
|
||||||
|
|
||||||
:param display: The display to be updated.
|
:param display: The display to be updated.
|
||||||
|
:param live_display: Is the display a live one.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -78,10 +79,11 @@ class MediaPlayer(RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def play(self, display):
|
def play(self, controller, display):
|
||||||
"""
|
"""
|
||||||
Starts playing of current Media File
|
Starts playing of current Media File
|
||||||
|
|
||||||
|
:param controller: Which Controller is running the show.
|
||||||
:param display: The display to be updated.
|
:param display: The display to be updated.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
@ -206,7 +208,7 @@ class MediaPlayer(RegistryProperties):
|
|||||||
:param display: Identify the Display type
|
:param display: Identify the Display type
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if display.controller.is_live:
|
if display.is_display:
|
||||||
self.set_live_state(state)
|
self.set_live_state(state)
|
||||||
else:
|
else:
|
||||||
self.set_preview_state(state)
|
self.set_preview_state(state)
|
||||||
|
@ -51,12 +51,12 @@ class MediaTab(SettingsTab):
|
|||||||
player_translated = translate('OpenLP.MediaTab', 'Media')
|
player_translated = translate('OpenLP.MediaTab', 'Media')
|
||||||
super(MediaTab, self).__init__(parent, 'Media', player_translated)
|
super(MediaTab, self).__init__(parent, 'Media', player_translated)
|
||||||
|
|
||||||
def setupUi(self):
|
def setup_ui(self):
|
||||||
"""
|
"""
|
||||||
Set up the UI
|
Set up the UI
|
||||||
"""
|
"""
|
||||||
self.setObjectName('MediaTab')
|
self.setObjectName('MediaTab')
|
||||||
super(MediaTab, self).setupUi()
|
super(MediaTab, self).setup_ui()
|
||||||
self.live_media_group_box = QtWidgets.QGroupBox(self.left_column)
|
self.live_media_group_box = QtWidgets.QGroupBox(self.left_column)
|
||||||
self.live_media_group_box.setObjectName('live_media_group_box')
|
self.live_media_group_box.setObjectName('live_media_group_box')
|
||||||
self.media_layout = QtWidgets.QVBoxLayout(self.live_media_group_box)
|
self.media_layout = QtWidgets.QVBoxLayout(self.live_media_group_box)
|
||||||
|
@ -152,43 +152,44 @@ class VlcPlayer(MediaPlayer):
|
|||||||
self.audio_extensions_list = AUDIO_EXT
|
self.audio_extensions_list = AUDIO_EXT
|
||||||
self.video_extensions_list = VIDEO_EXT
|
self.video_extensions_list = VIDEO_EXT
|
||||||
|
|
||||||
def setup(self, display):
|
def setup(self, output_display, live_display):
|
||||||
"""
|
"""
|
||||||
Set up the media player
|
Set up the media player
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
|
:param live_display: Is the display a live one.
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
vlc = get_vlc()
|
vlc = get_vlc()
|
||||||
display.vlc_widget = QtWidgets.QFrame(display)
|
output_display.vlc_widget = QtWidgets.QFrame(output_display)
|
||||||
display.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame)
|
output_display.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame)
|
||||||
# creating a basic vlc instance
|
# creating a basic vlc instance
|
||||||
command_line_options = '--no-video-title-show'
|
command_line_options = '--no-video-title-show'
|
||||||
if not display.has_audio:
|
if not output_display.has_audio:
|
||||||
command_line_options += ' --no-audio --no-video-title-show'
|
command_line_options += ' --no-audio --no-video-title-show'
|
||||||
if Settings().value('advanced/hide mouse') and display.controller.is_live:
|
if Settings().value('advanced/hide mouse') and live_display:
|
||||||
command_line_options += ' --mouse-hide-timeout=0'
|
command_line_options += ' --mouse-hide-timeout=0'
|
||||||
display.vlc_instance = vlc.Instance(command_line_options)
|
output_display.vlc_instance = vlc.Instance(command_line_options)
|
||||||
# creating an empty vlc media player
|
# creating an empty vlc media player
|
||||||
display.vlc_media_player = display.vlc_instance.media_player_new()
|
output_display.vlc_media_player = output_display.vlc_instance.media_player_new()
|
||||||
display.vlc_widget.resize(display.size())
|
output_display.vlc_widget.resize(output_display.size())
|
||||||
display.vlc_widget.raise_()
|
output_display.vlc_widget.raise_()
|
||||||
display.vlc_widget.hide()
|
output_display.vlc_widget.hide()
|
||||||
# The media player has to be 'connected' to the QFrame.
|
# The media player has to be 'connected' to the QFrame.
|
||||||
# (otherwise a video would be displayed in it's own window)
|
# (otherwise a video would be displayed in it's own window)
|
||||||
# This is platform specific!
|
# This is platform specific!
|
||||||
# You have to give the id of the QFrame (or similar object)
|
# You have to give the id of the QFrame (or similar object)
|
||||||
# to vlc, different platforms have different functions for this.
|
# to vlc, different platforms have different functions for this.
|
||||||
win_id = int(display.vlc_widget.winId())
|
win_id = int(output_display.vlc_widget.winId())
|
||||||
if is_win():
|
if is_win():
|
||||||
display.vlc_media_player.set_hwnd(win_id)
|
output_display.vlc_media_player.set_hwnd(win_id)
|
||||||
elif is_macosx():
|
elif is_macosx():
|
||||||
# We have to use 'set_nsobject' since Qt5 on OSX uses Cocoa
|
# We have to use 'set_nsobject' since Qt5 on OSX uses Cocoa
|
||||||
# framework and not the old Carbon.
|
# framework and not the old Carbon.
|
||||||
display.vlc_media_player.set_nsobject(win_id)
|
output_display.vlc_media_player.set_nsobject(win_id)
|
||||||
else:
|
else:
|
||||||
# for Linux/*BSD using the X Server
|
# for Linux/*BSD using the X Server
|
||||||
display.vlc_media_player.set_xwindow(win_id)
|
output_display.vlc_media_player.set_xwindow(win_id)
|
||||||
self.has_own_widget = True
|
self.has_own_widget = True
|
||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
@ -197,45 +198,45 @@ class VlcPlayer(MediaPlayer):
|
|||||||
"""
|
"""
|
||||||
return get_vlc() is not None
|
return get_vlc() is not None
|
||||||
|
|
||||||
def load(self, display, file):
|
def load(self, output_display, file):
|
||||||
"""
|
"""
|
||||||
Load a video into VLC
|
Load a video into VLC
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
:param file: file to be played
|
:param file: file to be played
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
vlc = get_vlc()
|
vlc = get_vlc()
|
||||||
log.debug('load vid in Vlc Controller')
|
log.debug('load vid in Vlc Controller')
|
||||||
controller = display.controller
|
controller = output_display
|
||||||
volume = controller.media_info.volume
|
volume = controller.media_info.volume
|
||||||
path = os.path.normcase(file)
|
path = os.path.normcase(file)
|
||||||
# create the media
|
# create the media
|
||||||
if controller.media_info.media_type == MediaType.CD:
|
if controller.media_info.media_type == MediaType.CD:
|
||||||
if is_win():
|
if is_win():
|
||||||
path = '/' + path
|
path = '/' + path
|
||||||
display.vlc_media = display.vlc_instance.media_new_location('cdda://' + path)
|
output_display.vlc_media = output_display.vlc_instance.media_new_location('cdda://' + path)
|
||||||
display.vlc_media_player.set_media(display.vlc_media)
|
output_display.vlc_media_player.set_media(output_display.vlc_media)
|
||||||
display.vlc_media_player.play()
|
output_display.vlc_media_player.play()
|
||||||
# Wait for media to start playing. In this case VLC actually returns an error.
|
# Wait for media to start playing. In this case VLC actually returns an error.
|
||||||
self.media_state_wait(display, vlc.State.Playing)
|
self.media_state_wait(output_display, vlc.State.Playing)
|
||||||
# If subitems exists, this is a CD
|
# If subitems exists, this is a CD
|
||||||
audio_cd_tracks = display.vlc_media.subitems()
|
audio_cd_tracks = output_display.vlc_media.subitems()
|
||||||
if not audio_cd_tracks or audio_cd_tracks.count() < 1:
|
if not audio_cd_tracks or audio_cd_tracks.count() < 1:
|
||||||
return False
|
return False
|
||||||
display.vlc_media = audio_cd_tracks.item_at_index(controller.media_info.title_track)
|
output_display.vlc_media = audio_cd_tracks.item_at_index(controller.media_info.title_track)
|
||||||
elif controller.media_info.media_type == MediaType.Stream:
|
elif controller.media_info.media_type == MediaType.Stream:
|
||||||
display.vlc_media = display.vlc_instance.media_new_location("ZZZZZZ")
|
output_display.vlc_media = output_display.vlc_instance.media_new_location("ZZZZZZ")
|
||||||
else:
|
else:
|
||||||
display.vlc_media = display.vlc_instance.media_new_path(path)
|
output_display.vlc_media = output_display.vlc_instance.media_new_path(path)
|
||||||
# put the media in the media player
|
# put the media in the media player
|
||||||
display.vlc_media_player.set_media(display.vlc_media)
|
output_display.vlc_media_player.set_media(output_display.vlc_media)
|
||||||
# parse the metadata of the file
|
# parse the metadata of the file
|
||||||
display.vlc_media.parse()
|
output_display.vlc_media.parse()
|
||||||
self.volume(display, volume)
|
self.volume(output_display, volume)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def media_state_wait(self, display, media_state):
|
def media_state_wait(self, output_display, media_state):
|
||||||
"""
|
"""
|
||||||
Wait for the video to change its state
|
Wait for the video to change its state
|
||||||
Wait no longer than 60 seconds. (loading an iso file needs a long time)
|
Wait no longer than 60 seconds. (loading an iso file needs a long time)
|
||||||
@ -246,171 +247,172 @@ class VlcPlayer(MediaPlayer):
|
|||||||
"""
|
"""
|
||||||
vlc = get_vlc()
|
vlc = get_vlc()
|
||||||
start = datetime.now()
|
start = datetime.now()
|
||||||
while media_state != display.vlc_media.get_state():
|
while media_state != output_display.vlc_media.get_state():
|
||||||
if display.vlc_media.get_state() == vlc.State.Error:
|
if output_display.vlc_media.get_state() == vlc.State.Error:
|
||||||
return False
|
return False
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
if (datetime.now() - start).seconds > 60:
|
if (datetime.now() - start).seconds > 60:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def resize(self, display):
|
def resize(self, output_display):
|
||||||
"""
|
"""
|
||||||
Resize the player
|
Resize the player
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
display.vlc_widget.resize(display.size())
|
# output_display.vlc_widget.resize(output_display.size())
|
||||||
|
pass
|
||||||
|
|
||||||
def play(self, display):
|
def play(self, controller, output_display):
|
||||||
"""
|
"""
|
||||||
Play the current item
|
Play the current item
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param controller: Which Controller is running the show.
|
||||||
|
:param output_display: The display where the media is
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
vlc = get_vlc()
|
vlc = get_vlc()
|
||||||
controller = display.controller
|
|
||||||
start_time = 0
|
start_time = 0
|
||||||
log.debug('vlc play')
|
log.debug('vlc play')
|
||||||
if display.controller.is_live:
|
if output_display.is_display:
|
||||||
if self.get_live_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
if self.get_live_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||||
start_time = controller.media_info.start_time
|
start_time = output_display.media_info.start_time
|
||||||
else:
|
else:
|
||||||
if self.get_preview_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
if self.get_preview_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||||
start_time = controller.media_info.start_time
|
start_time = output_display.media_info.start_time
|
||||||
threading.Thread(target=display.vlc_media_player.play).start()
|
threading.Thread(target=output_display.vlc_media_player.play).start()
|
||||||
if not self.media_state_wait(display, vlc.State.Playing):
|
if not self.media_state_wait(output_display, vlc.State.Playing):
|
||||||
return False
|
return False
|
||||||
if display.controller.is_live:
|
if output_display.is_display:
|
||||||
if self.get_live_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
if self.get_live_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||||
log.debug('vlc play, start time set')
|
log.debug('vlc play, start time set')
|
||||||
start_time = controller.media_info.start_time
|
start_time = output_display.media_info.start_time
|
||||||
else:
|
else:
|
||||||
if self.get_preview_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
if self.get_preview_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||||
log.debug('vlc play, start time set')
|
log.debug('vlc play, start time set')
|
||||||
start_time = controller.media_info.start_time
|
start_time = output_display.media_info.start_time
|
||||||
log.debug('mediatype: ' + str(controller.media_info.media_type))
|
log.debug('mediatype: ' + str(output_display.media_info.media_type))
|
||||||
# Set tracks for the optical device
|
# Set tracks for the optical device
|
||||||
if controller.media_info.media_type == MediaType.DVD and \
|
if output_display.media_info.media_type == MediaType.DVD and \
|
||||||
self.get_live_state() != MediaState.Paused and self.get_preview_state() != MediaState.Paused:
|
self.get_live_state() != MediaState.Paused and self.get_preview_state() != MediaState.Paused:
|
||||||
log.debug('vlc play, playing started')
|
log.debug('vlc play, playing started')
|
||||||
if controller.media_info.title_track > 0:
|
if output_display.media_info.title_track > 0:
|
||||||
log.debug('vlc play, title_track set: ' + str(controller.media_info.title_track))
|
log.debug('vlc play, title_track set: ' + str(output_display.media_info.title_track))
|
||||||
display.vlc_media_player.set_title(controller.media_info.title_track)
|
output_display.vlc_media_player.set_title(output_display.media_info.title_track)
|
||||||
display.vlc_media_player.play()
|
output_display.vlc_media_player.play()
|
||||||
if not self.media_state_wait(display, vlc.State.Playing):
|
if not self.media_state_wait(output_display, vlc.State.Playing):
|
||||||
return False
|
return False
|
||||||
if controller.media_info.audio_track > 0:
|
if output_display.media_info.audio_track > 0:
|
||||||
display.vlc_media_player.audio_set_track(controller.media_info.audio_track)
|
output_display.vlc_media_player.audio_set_track(output_display.media_info.audio_track)
|
||||||
log.debug('vlc play, audio_track set: ' + str(controller.media_info.audio_track))
|
log.debug('vlc play, audio_track set: ' + str(output_display.media_info.audio_track))
|
||||||
if controller.media_info.subtitle_track > 0:
|
if output_display.media_info.subtitle_track > 0:
|
||||||
display.vlc_media_player.video_set_spu(controller.media_info.subtitle_track)
|
output_display.vlc_media_player.video_set_spu(output_display.media_info.subtitle_track)
|
||||||
log.debug('vlc play, subtitle_track set: ' + str(controller.media_info.subtitle_track))
|
log.debug('vlc play, subtitle_track set: ' + str(output_display.media_info.subtitle_track))
|
||||||
if controller.media_info.start_time > 0:
|
if output_display.media_info.start_time > 0:
|
||||||
log.debug('vlc play, starttime set: ' + str(controller.media_info.start_time))
|
log.debug('vlc play, starttime set: ' + str(output_display.media_info.start_time))
|
||||||
start_time = controller.media_info.start_time
|
start_time = output_display.media_info.start_time
|
||||||
controller.media_info.length = controller.media_info.end_time - controller.media_info.start_time
|
output_display.media_info.length = output_display.media_info.end_time - output_display.media_info.start_time
|
||||||
self.volume(display, controller.media_info.volume)
|
self.volume(output_display, output_display.media_info.volume)
|
||||||
if start_time > 0 and display.vlc_media_player.is_seekable():
|
if start_time > 0 and output_display.vlc_media_player.is_seekable():
|
||||||
display.vlc_media_player.set_time(int(start_time))
|
output_display.vlc_media_player.set_time(int(start_time))
|
||||||
controller.seek_slider.setMaximum(controller.media_info.length)
|
controller.seek_slider.setMaximum(output_display.media_info.length)
|
||||||
self.set_state(MediaState.Playing, display)
|
self.set_state(MediaState.Playing, output_display)
|
||||||
display.vlc_widget.raise_()
|
output_display.vlc_widget.raise_()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def pause(self, display):
|
def pause(self, output_display):
|
||||||
"""
|
"""
|
||||||
Pause the current item
|
Pause the current item
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
vlc = get_vlc()
|
vlc = get_vlc()
|
||||||
if display.vlc_media.get_state() != vlc.State.Playing:
|
if output_display.vlc_media.get_state() != vlc.State.Playing:
|
||||||
return
|
return
|
||||||
display.vlc_media_player.pause()
|
output_display.vlc_media_player.pause()
|
||||||
if self.media_state_wait(display, vlc.State.Paused):
|
if self.media_state_wait(output_display, vlc.State.Paused):
|
||||||
self.set_state(MediaState.Paused, display)
|
self.set_state(MediaState.Paused, output_display)
|
||||||
|
|
||||||
def stop(self, display):
|
def stop(self, output_display):
|
||||||
"""
|
"""
|
||||||
Stop the current item
|
Stop the current item
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
threading.Thread(target=display.vlc_media_player.stop).start()
|
threading.Thread(target=output_display.vlc_media_player.stop).start()
|
||||||
self.set_state(MediaState.Stopped, display)
|
self.set_state(MediaState.Stopped, output_display)
|
||||||
|
|
||||||
def volume(self, display, vol):
|
def volume(self, output_display, vol):
|
||||||
"""
|
"""
|
||||||
Set the volume
|
Set the volume
|
||||||
|
|
||||||
:param vol: The volume to be sets
|
:param vol: The volume to be sets
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if display.has_audio:
|
if output_display.has_audio:
|
||||||
display.vlc_media_player.audio_set_volume(vol)
|
output_display.vlc_media_player.audio_set_volume(vol)
|
||||||
|
|
||||||
def seek(self, display, seek_value):
|
def seek(self, output_display, seek_value):
|
||||||
"""
|
"""
|
||||||
Go to a particular position
|
Go to a particular position
|
||||||
|
|
||||||
:param seek_value: The position of where a seek goes to
|
:param seek_value: The position of where a seek goes to
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
"""
|
"""
|
||||||
if display.controller.media_info.media_type == MediaType.CD \
|
if output_display.controller.media_info.media_type == MediaType.CD \
|
||||||
or display.controller.media_info.media_type == MediaType.DVD:
|
or output_display.controller.media_info.media_type == MediaType.DVD:
|
||||||
seek_value += int(display.controller.media_info.start_time)
|
seek_value += int(output_display.controller.media_info.start_time)
|
||||||
if display.vlc_media_player.is_seekable():
|
if output_display.vlc_media_player.is_seekable():
|
||||||
display.vlc_media_player.set_time(seek_value)
|
output_display.vlc_media_player.set_time(seek_value)
|
||||||
|
|
||||||
def reset(self, display):
|
def reset(self, output_display):
|
||||||
"""
|
"""
|
||||||
Reset the player
|
Reset the player
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
"""
|
"""
|
||||||
display.vlc_media_player.stop()
|
output_display.vlc_media_player.stop()
|
||||||
display.vlc_widget.setVisible(False)
|
output_display.vlc_widget.setVisible(False)
|
||||||
self.set_state(MediaState.Off, display)
|
self.set_state(MediaState.Off, output_display)
|
||||||
|
|
||||||
def set_visible(self, display, status):
|
def set_visible(self, output_display, status):
|
||||||
"""
|
"""
|
||||||
Set the visibility
|
Set the visibility
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param output_display: The display where the media is
|
||||||
:param status: The visibility status
|
:param status: The visibility status
|
||||||
"""
|
"""
|
||||||
if self.has_own_widget:
|
if self.has_own_widget:
|
||||||
display.vlc_widget.setVisible(status)
|
output_display.vlc_widget.setVisible(status)
|
||||||
|
|
||||||
def update_ui(self, display):
|
def update_ui(self, controller, output_display):
|
||||||
"""
|
"""
|
||||||
Update the UI
|
Update the UI
|
||||||
|
|
||||||
:param display: The display where the media is
|
:param controller: Which Controller is running the show.
|
||||||
|
:param output_display: The display where the media is
|
||||||
"""
|
"""
|
||||||
vlc = get_vlc()
|
vlc = get_vlc()
|
||||||
# Stop video if playback is finished.
|
# Stop video if playback is finished.
|
||||||
if display.vlc_media.get_state() == vlc.State.Ended:
|
if output_display.vlc_media.get_state() == vlc.State.Ended:
|
||||||
self.stop(display)
|
self.stop(output_display)
|
||||||
controller = display.controller
|
|
||||||
if controller.media_info.end_time > 0:
|
if controller.media_info.end_time > 0:
|
||||||
if display.vlc_media_player.get_time() > controller.media_info.end_time:
|
if output_display.vlc_media_player.get_time() > controller.media_info.end_time:
|
||||||
self.stop(display)
|
self.stop(output_display)
|
||||||
self.set_visible(display, False)
|
self.set_visible(output_display, False)
|
||||||
if not controller.seek_slider.isSliderDown():
|
if not controller.seek_slider.isSliderDown():
|
||||||
controller.seek_slider.blockSignals(True)
|
controller.seek_slider.blockSignals(True)
|
||||||
if display.controller.media_info.media_type == MediaType.CD \
|
if controller.media_info.media_type == MediaType.CD \
|
||||||
or display.controller.media_info.media_type == MediaType.DVD:
|
or controller.media_info.media_type == MediaType.DVD:
|
||||||
controller.seek_slider.setSliderPosition(
|
controller.seek_slider.setSliderPosition(
|
||||||
display.vlc_media_player.get_time() - int(display.controller.media_info.start_time))
|
output_display.vlc_media_player.get_time() - int(output_display.controller.media_info.start_time))
|
||||||
else:
|
else:
|
||||||
controller.seek_slider.setSliderPosition(display.vlc_media_player.get_time())
|
controller.seek_slider.setSliderPosition(output_display.vlc_media_player.get_time())
|
||||||
controller.seek_slider.blockSignals(False)
|
controller.seek_slider.blockSignals(False)
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
|
@ -62,7 +62,6 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
|
|||||||
self.themes_tab = None
|
self.themes_tab = None
|
||||||
self.projector_tab = None
|
self.projector_tab = None
|
||||||
self.advanced_tab = None
|
self.advanced_tab = None
|
||||||
self.player_tab = None
|
|
||||||
self.api_tab = None
|
self.api_tab = None
|
||||||
|
|
||||||
def exec(self):
|
def exec(self):
|
||||||
@ -156,18 +155,16 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
Run any post-setup code for the tabs on the form
|
Run any post-setup code for the tabs on the form
|
||||||
"""
|
"""
|
||||||
# General tab
|
try:
|
||||||
self.general_tab = GeneralTab(self)
|
self.general_tab = GeneralTab(self)
|
||||||
# Themes tab
|
|
||||||
self.themes_tab = ThemesTab(self)
|
self.themes_tab = ThemesTab(self)
|
||||||
# Projector Tab
|
|
||||||
self.projector_tab = ProjectorTab(self)
|
self.projector_tab = ProjectorTab(self)
|
||||||
# Advanced tab
|
|
||||||
self.advanced_tab = AdvancedTab(self)
|
self.advanced_tab = AdvancedTab(self)
|
||||||
# Advanced tab
|
|
||||||
self.player_tab = MediaTab(self)
|
self.player_tab = MediaTab(self)
|
||||||
# Api tab
|
|
||||||
self.api_tab = ApiTab(self)
|
self.api_tab = ApiTab(self)
|
||||||
|
self.screens_tab = ScreensTab(self)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
self.general_tab.post_set_up()
|
self.general_tab.post_set_up()
|
||||||
self.themes_tab.post_set_up()
|
self.themes_tab.post_set_up()
|
||||||
self.advanced_tab.post_set_up()
|
self.advanced_tab.post_set_up()
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
The :mod:`slidecontroller` module contains the most important part of OpenLP - the slide controller
|
The :mod:`slidecontroller` module contains the most important part of OpenLP - the slide controller
|
||||||
"""
|
"""
|
||||||
import copy
|
import copy
|
||||||
|
import datetime
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
@ -70,6 +71,45 @@ NON_TEXT_MENU = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class MediaSlider(QtWidgets.QSlider):
|
||||||
|
"""
|
||||||
|
Allows the mouse events of a slider to be overridden and extra functionality added
|
||||||
|
"""
|
||||||
|
def __init__(self, direction, manager, controller):
|
||||||
|
"""
|
||||||
|
Constructor
|
||||||
|
"""
|
||||||
|
super(MediaSlider, self).__init__(direction)
|
||||||
|
self.manager = manager
|
||||||
|
self.controller = controller
|
||||||
|
|
||||||
|
def mouseMoveEvent(self, event):
|
||||||
|
"""
|
||||||
|
Override event to allow hover time to be displayed.
|
||||||
|
|
||||||
|
:param event: The triggering event
|
||||||
|
"""
|
||||||
|
time_value = QtWidgets.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
|
||||||
|
self.setToolTip('%s' % datetime.timedelta(seconds=int(time_value / 1000)))
|
||||||
|
QtWidgets.QSlider.mouseMoveEvent(self, event)
|
||||||
|
|
||||||
|
def mousePressEvent(self, event):
|
||||||
|
"""
|
||||||
|
Mouse Press event no new functionality
|
||||||
|
:param event: The triggering event
|
||||||
|
"""
|
||||||
|
QtWidgets.QSlider.mousePressEvent(self, event)
|
||||||
|
|
||||||
|
def mouseReleaseEvent(self, event):
|
||||||
|
"""
|
||||||
|
Set the slider position when the mouse is clicked and released on the slider.
|
||||||
|
|
||||||
|
:param event: The triggering event
|
||||||
|
"""
|
||||||
|
self.setValue(QtWidgets.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width()))
|
||||||
|
QtWidgets.QSlider.mouseReleaseEvent(self, event)
|
||||||
|
|
||||||
|
|
||||||
class InfoLabel(QtWidgets.QLabel):
|
class InfoLabel(QtWidgets.QLabel):
|
||||||
"""
|
"""
|
||||||
InfoLabel is a subclassed QLabel. Created to provide the ablilty to add a ellipsis if the text is cut off. Original
|
InfoLabel is a subclassed QLabel. Created to provide the ablilty to add a ellipsis if the text is cut off. Original
|
||||||
@ -316,8 +356,59 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
'Clear'),
|
'Clear'),
|
||||||
triggers=self.on_clear)
|
triggers=self.on_clear)
|
||||||
self.controller_layout.addWidget(self.toolbar)
|
self.controller_layout.addWidget(self.toolbar)
|
||||||
# Build the Media Toolbar
|
# Build a Media ToolBar
|
||||||
self.media_controller.register_controller(self)
|
self.mediabar = OpenLPToolbar(self)
|
||||||
|
self.mediabar.add_toolbar_action('playbackPlay', text='media_playback_play',
|
||||||
|
icon=UiIcons().play,
|
||||||
|
tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
|
||||||
|
triggers=self.send_to_plugins)
|
||||||
|
self.mediabar.add_toolbar_action('playbackPause', text='media_playback_pause',
|
||||||
|
icon=UiIcons().pause,
|
||||||
|
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
|
||||||
|
triggers=self.send_to_plugins)
|
||||||
|
self.mediabar.add_toolbar_action('playbackStop', text='media_playback_stop',
|
||||||
|
icon=UiIcons().stop,
|
||||||
|
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
|
||||||
|
triggers=self.send_to_plugins)
|
||||||
|
self.mediabar.add_toolbar_action('playbackLoop', text='media_playback_loop',
|
||||||
|
icon=UiIcons().repeat, checked=False,
|
||||||
|
tooltip=translate('OpenLP.SlideController', 'Loop playing media.'),
|
||||||
|
triggers=self.send_to_plugins)
|
||||||
|
self.position_label = QtWidgets.QLabel()
|
||||||
|
self.position_label.setText(' 00:00 / 00:00')
|
||||||
|
self.position_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||||
|
self.position_label.setToolTip(translate('OpenLP.SlideController', 'Video timer.'))
|
||||||
|
self.position_label.setMinimumSize(90, 0)
|
||||||
|
self.position_label.setObjectName('position_label')
|
||||||
|
self.mediabar.add_toolbar_widget(self.position_label)
|
||||||
|
# Build the seek_slider.
|
||||||
|
self.seek_slider = MediaSlider(QtCore.Qt.Horizontal, self, self)
|
||||||
|
self.seek_slider.setMaximum(1000)
|
||||||
|
self.seek_slider.setTracking(True)
|
||||||
|
self.seek_slider.setMouseTracking(True)
|
||||||
|
self.seek_slider.setToolTip(translate('OpenLP.SlideController', 'Video position.'))
|
||||||
|
self.seek_slider.setGeometry(QtCore.QRect(90, 260, 221, 24))
|
||||||
|
self.seek_slider.setObjectName('seek_slider')
|
||||||
|
self.mediabar.add_toolbar_widget(self.seek_slider)
|
||||||
|
# Build the volume_slider.
|
||||||
|
self.volume_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
|
||||||
|
self.volume_slider.setTickInterval(10)
|
||||||
|
self.volume_slider.setTickPosition(QtWidgets.QSlider.TicksAbove)
|
||||||
|
self.volume_slider.setMinimum(0)
|
||||||
|
self.volume_slider.setMaximum(100)
|
||||||
|
self.volume_slider.setTracking(True)
|
||||||
|
self.volume_slider.setToolTip(translate('OpenLP.SlideController', 'Audio Volume.'))
|
||||||
|
# self.volume_slider.setValue(self.media_info.volume)
|
||||||
|
self.volume_slider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
||||||
|
self.volume_slider.setObjectName('volume_slider')
|
||||||
|
self.mediabar.add_toolbar_widget(self.volume_slider)
|
||||||
|
self.controller_layout.addWidget(self.mediabar)
|
||||||
|
self.mediabar.setVisible(False)
|
||||||
|
if not self.is_live:
|
||||||
|
self.volume_slider.setEnabled(False)
|
||||||
|
# Signals
|
||||||
|
self.seek_slider.valueChanged.connect(self.send_to_plugins)
|
||||||
|
self.volume_slider.valueChanged.connect(self.send_to_plugins)
|
||||||
if self.is_live:
|
if self.is_live:
|
||||||
# Build the Song Toolbar
|
# Build the Song Toolbar
|
||||||
self.song_menu = QtWidgets.QToolButton(self.toolbar)
|
self.song_menu = QtWidgets.QToolButton(self.toolbar)
|
||||||
@ -556,8 +647,6 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
# self.__add_actions_to_widget(self.display)
|
# self.__add_actions_to_widget(self.display)
|
||||||
# The SlidePreview's ratio.
|
# The SlidePreview's ratio.
|
||||||
|
|
||||||
# TODO: Need to basically update everything
|
|
||||||
|
|
||||||
def __add_actions_to_widget(self, widget):
|
def __add_actions_to_widget(self, widget):
|
||||||
"""
|
"""
|
||||||
Add actions to the widget specified by `widget`
|
Add actions to the widget specified by `widget`
|
||||||
@ -1398,10 +1487,10 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
:param item: The service item to be processed
|
:param item: The service item to be processed
|
||||||
"""
|
"""
|
||||||
if self.is_live and self.hide_mode() == HideMode.Theme:
|
if self.is_live and self.hide_mode() == HideMode.Theme:
|
||||||
self.media_controller.video(self.controller_type, item, HideMode.Blank)
|
self.media_controller.load_video(self.controller_type, item, HideMode.Blank)
|
||||||
self.on_blank_display(True)
|
self.on_blank_display(True)
|
||||||
else:
|
else:
|
||||||
self.media_controller.video(self.controller_type, item, self.hide_mode())
|
self.media_controller.load_video(self.controller_type, item, self.hide_mode())
|
||||||
if not self.is_live:
|
if not self.is_live:
|
||||||
self.preview_display.show()
|
self.preview_display.show()
|
||||||
|
|
||||||
@ -1491,7 +1580,7 @@ class PreviewController(RegistryBase, SlideController):
|
|||||||
self.type_prefix = 'preview'
|
self.type_prefix = 'preview'
|
||||||
self.category = 'Preview Toolbar'
|
self.category = 'Preview Toolbar'
|
||||||
|
|
||||||
def bootstrap_post_set_up(self):
|
def bootstrap_initialise(self):
|
||||||
"""
|
"""
|
||||||
process the bootstrap post setup request
|
process the bootstrap post setup request
|
||||||
"""
|
"""
|
||||||
@ -1523,7 +1612,7 @@ class LiveController(RegistryBase, SlideController):
|
|||||||
self.category = UiStrings().LiveToolbar
|
self.category = UiStrings().LiveToolbar
|
||||||
ActionList.get_instance().add_category(str(self.category), CategoryOrder.standard_toolbar)
|
ActionList.get_instance().add_category(str(self.category), CategoryOrder.standard_toolbar)
|
||||||
|
|
||||||
def bootstrap_post_set_up(self):
|
def bootstrap_initialise(self):
|
||||||
"""
|
"""
|
||||||
process the bootstrap post setup request
|
process the bootstrap post setup request
|
||||||
"""
|
"""
|
||||||
|
@ -202,6 +202,9 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
|||||||
if self.service_item.is_command():
|
if self.service_item.is_command():
|
||||||
if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
|
if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
|
||||||
pixmap = QtGui.QPixmap(remove_url_prefix(slide['thumbnail']))
|
pixmap = QtGui.QPixmap(remove_url_prefix(slide['thumbnail']))
|
||||||
|
else:
|
||||||
|
if isinstance(slide['image'], QtGui.QIcon):
|
||||||
|
pixmap = slide['image'].pixmap(QtCore.QSize(32, 32))
|
||||||
else:
|
else:
|
||||||
pixmap = QtGui.QPixmap(remove_url_prefix(slide['image']))
|
pixmap = QtGui.QPixmap(remove_url_prefix(slide['image']))
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user