forked from openlp/openlp
Stop media crashing
This commit is contained in:
parent
26a9b2430d
commit
0694d1b3d0
@ -616,6 +616,10 @@ class ServiceItem(RegistryProperties):
|
||||
path_from = frame['path']
|
||||
else:
|
||||
path_from = os.path.join(frame['path'], frame['title'])
|
||||
if isinstance(path_from, str):
|
||||
# Handle service files prior to OpenLP 3.0
|
||||
# Windows can handle both forward and backward slashes, so we use ntpath to get the basename
|
||||
path_from = Path(path_from)
|
||||
return path_from
|
||||
|
||||
def remove_frame(self, frame):
|
||||
|
@ -24,7 +24,7 @@ The :mod:`~openlp.core.loader` module provides a bootstrap for the singleton cla
|
||||
"""
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.ui.media import MediaController
|
||||
from openlp.core.ui.media.mediacontroller import MediaController
|
||||
from openlp.core.lib.pluginmanager import PluginManager
|
||||
from openlp.core.display.renderer import Renderer
|
||||
from openlp.core.lib.imagemanager import ImageManager
|
||||
|
@ -33,7 +33,7 @@ except ImportError:
|
||||
pymediainfo_available = False
|
||||
|
||||
from subprocess import check_output
|
||||
|
||||
from pathlib import Path
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.state import State
|
||||
@ -81,7 +81,6 @@ class MediaSlider(QtWidgets.QSlider):
|
||||
def mousePressEvent(self, event):
|
||||
"""
|
||||
Mouse Press event no new functionality
|
||||
|
||||
:param event: The triggering event
|
||||
"""
|
||||
QtWidgets.QSlider.mousePressEvent(self, event)
|
||||
@ -385,7 +384,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
:param hidden: The player which is doing the playing
|
||||
:param video_behind_text: Is the video to be played behind text.
|
||||
"""
|
||||
is_valid = False
|
||||
is_valid = True
|
||||
controller = self.display_controllers[source]
|
||||
# stop running videos
|
||||
self.media_reset(controller)
|
||||
@ -397,7 +396,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
if service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
controller.media_info.file_info = service_item.background_audio
|
||||
else:
|
||||
controller.media_info.file_info = [QtCore.QFileInfo(service_item.get_frame_path())]
|
||||
controller.media_info.file_info = [service_item.get_frame_path()]
|
||||
display = self._define_display(controller)
|
||||
if controller.is_live:
|
||||
# if this is an optical device use special handling
|
||||
@ -465,18 +464,14 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
"""
|
||||
Uses Media Info to obtain the media length
|
||||
|
||||
:param service_item: The ServiceItem containing the details to be played.
|
||||
:param media_path: The file path to be checked..
|
||||
"""
|
||||
media_info = MediaInfo()
|
||||
media_info.volume = 0
|
||||
media_info.file_info = media_path
|
||||
filename = media_path
|
||||
if pymediainfo.MediaInfo.can_parse():
|
||||
media_data = pymediainfo.MediaInfo.parse(filename)
|
||||
media_data = pymediainfo.MediaInfo.parse(media_path)
|
||||
else:
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', filename])
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', media_path])
|
||||
if not xml.startswith(b'<?xml'):
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', filename])
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', media_path])
|
||||
media_data = pymediainfo.MediaInfo(xml.decode("utf-8"))
|
||||
# duration returns in milli seconds
|
||||
return media_data.tracks[0].duration
|
||||
@ -550,30 +545,33 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
:param display: Which display to use
|
||||
:param service_item: The ServiceItem containing the details to be played.
|
||||
"""
|
||||
if controller.media_info.file_info.isFile():
|
||||
suffix = '*.%s' % controller.media_info.file_info.suffix().lower()
|
||||
player = self.media_players
|
||||
if suffix in player.video_extensions_list:
|
||||
if not controller.media_info.is_background or controller.media_info.is_background and \
|
||||
player.can_background:
|
||||
for file in controller.media_info.file_info:
|
||||
if file.is_file:
|
||||
suffix = '*%s' % file.suffix.lower()
|
||||
player = self.media_players
|
||||
file = str(file)
|
||||
if suffix in player.video_extensions_list:
|
||||
if not controller.media_info.is_background or controller.media_info.is_background and \
|
||||
player.can_background:
|
||||
self.resize(display, player)
|
||||
if player.load(display, file):
|
||||
self.current_media_players[controller.controller_type] = player
|
||||
controller.media_info.media_type = MediaType.Video
|
||||
return True
|
||||
if suffix in player.audio_extensions_list:
|
||||
if player.load(display, file):
|
||||
self.current_media_players[controller.controller_type] = player
|
||||
controller.media_info.media_type = MediaType.Audio
|
||||
return True
|
||||
else:
|
||||
player = self.media_players
|
||||
file = str(file)
|
||||
if player.can_folder:
|
||||
self.resize(display, player)
|
||||
if player.load(display):
|
||||
if player.load(display, file):
|
||||
self.current_media_players[controller.controller_type] = player
|
||||
controller.media_info.media_type = MediaType.Video
|
||||
return True
|
||||
if suffix in player.audio_extensions_list:
|
||||
if player.load(display):
|
||||
self.current_media_players[controller.controller_type] = player
|
||||
controller.media_info.media_type = MediaType.Audio
|
||||
return True
|
||||
else:
|
||||
player = self.media_players
|
||||
if player.can_folder:
|
||||
self.resize(display, player)
|
||||
if player.load(display):
|
||||
self.current_media_players[controller.controller_type] = player
|
||||
controller.media_info.media_type = MediaType.Video
|
||||
return True
|
||||
# no valid player found
|
||||
return False
|
||||
|
||||
|
@ -196,19 +196,19 @@ class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
return get_vlc() is not None
|
||||
|
||||
def load(self, display):
|
||||
def load(self, display, file):
|
||||
"""
|
||||
Load a video into VLC
|
||||
|
||||
:param display: The display where the media is
|
||||
:param file: file to be played
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
log.debug('load vid in Vlc Controller')
|
||||
controller = display.controller
|
||||
volume = controller.media_info.volume
|
||||
file_path = str(controller.media_info.file_info.absoluteFilePath())
|
||||
path = os.path.normcase(file_path)
|
||||
path = os.path.normcase(file)
|
||||
# create the media
|
||||
if controller.media_info.media_type == MediaType.CD:
|
||||
if is_win():
|
||||
|
@ -48,13 +48,13 @@ from openlp.core.widgets.views import ListPreviewWidget
|
||||
|
||||
# Threshold which has to be trespassed to toggle.
|
||||
HIDE_MENU_THRESHOLD = 27
|
||||
AUDIO_TIME_LABEL_STYLESHEET = 'background-color: palette(background); ' \
|
||||
'border-top-color: palette(shadow); ' \
|
||||
'border-left-color: palette(shadow); ' \
|
||||
'border-bottom-color: palette(light); ' \
|
||||
'border-right-color: palette(light); ' \
|
||||
'border-radius: 3px; border-style: inset; ' \
|
||||
'border-width: 1; font-family: monospace; margin: 2px;'
|
||||
# AUDIO_TIME_LABEL_STYLESHEET = 'background-color: palette(background); ' \
|
||||
# 'border-top-color: palette(shadow); ' \
|
||||
# 'border-left-color: palette(shadow); ' \
|
||||
# 'border-bottom-color: palette(light); ' \
|
||||
# 'border-right-color: palette(light); ' \
|
||||
# 'border-radius: 3px; border-style: inset; ' \
|
||||
# 'border-width: 1; font-family: monospace; margin: 2px;'
|
||||
|
||||
NARROW_MENU = [
|
||||
'hide_menu'
|
||||
@ -64,10 +64,10 @@ LOOP_LIST = [
|
||||
'loop_separator',
|
||||
'delay_spin_box'
|
||||
]
|
||||
AUDIO_LIST = [
|
||||
'audioPauseItem',
|
||||
'audio_time_label'
|
||||
]
|
||||
# AUDIO_LIST = [
|
||||
# 'audioPauseItem',
|
||||
# 'audio_time_label'
|
||||
# ]
|
||||
WIDE_MENU = [
|
||||
'blank_screen_button',
|
||||
'theme_screen_button',
|
||||
@ -84,6 +84,7 @@ class DisplayController(QtWidgets.QWidget):
|
||||
"""
|
||||
Controller is a general display controller widget.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Set up the general Controller.
|
||||
@ -140,6 +141,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
SlideController is the slide controller widget. This widget is what the
|
||||
user uses to control the displaying of verses/slides/etc on the screen.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Set up the Slide Controller.
|
||||
@ -371,7 +373,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
self.preview_frame.setMinimumHeight(100)
|
||||
self.preview_frame.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored,
|
||||
QtWidgets.QSizePolicy.Ignored,
|
||||
QtWidgets.QSizePolicy.Label))
|
||||
QtWidgets.QSizePolicy.Label))
|
||||
self.preview_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.preview_frame.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.preview_frame.setObjectName('preview_frame')
|
||||
@ -409,7 +411,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
{'key': 'C', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
|
||||
{'key': 'B', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Bridge"')},
|
||||
{'key': 'P', 'configurable': True,
|
||||
'text': translate('OpenLP.SlideController', 'Go to "Pre-Chorus"')},
|
||||
'text': translate('OpenLP.SlideController', 'Go to "Pre-Chorus"')},
|
||||
{'key': 'I', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Intro"')},
|
||||
{'key': 'E', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Ending"')},
|
||||
{'key': 'O', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Other"')}
|
||||
@ -475,6 +477,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
This empty class is mostly just to satisfy Python, PEP8 and PyCharm
|
||||
"""
|
||||
pass
|
||||
|
||||
is_songs_plugin_available = False
|
||||
sender_name = self.sender().objectName()
|
||||
verse_type = sender_name[15:] if sender_name[:15] == 'shortcutAction_' else ''
|
||||
@ -597,8 +600,8 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
self.display.setup()
|
||||
if self.is_live:
|
||||
self.__add_actions_to_widget(self.display)
|
||||
if self.display.audio_player:
|
||||
self.display.audio_player.position_changed.connect(self.on_audio_time_remaining)
|
||||
# if self.display.audio_player:
|
||||
# self.display.audio_player.position_changed.connect(self.on_audio_time_remaining)
|
||||
# The SlidePreview's ratio.
|
||||
try:
|
||||
self.ratio = self.screens.current['size'].width() / self.screens.current['size'].height()
|
||||
@ -610,7 +613,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
self.preview_display.setup()
|
||||
service_item = ServiceItem()
|
||||
self.preview_display.web_view.setHtml(build_html(service_item, self.preview_display.screen, None, self.is_live,
|
||||
plugins=self.plugin_manager.plugins))
|
||||
plugins=self.plugin_manager.plugins))
|
||||
self.media_controller.setup_display(self.preview_display, True)
|
||||
if self.service_item:
|
||||
self.refresh_service_item()
|
||||
@ -871,29 +874,29 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
self.slide_list = {}
|
||||
if self.is_live:
|
||||
self.song_menu.menu().clear()
|
||||
if self.display.audio_player:
|
||||
self.display.audio_player.reset()
|
||||
self.set_audio_items_visibility(False)
|
||||
# self.audio_pause_item.setChecked(False)
|
||||
# If the current item has background audio
|
||||
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
self.on_media_start(service_item)
|
||||
#self.log_debug('Starting to play...')
|
||||
#self.display.audio_player.add_to_playlist(self.service_item.background_audio)
|
||||
#self.track_menu.clear()
|
||||
#for counter in range(len(self.service_item.background_audio)):
|
||||
# action = self.track_menu.addAction(
|
||||
# os.path.basename(str(self.service_item.background_audio[counter])))
|
||||
# action.setData(counter)
|
||||
# action.triggered.connect(self.on_track_triggered)
|
||||
#self.display.audio_player.repeat = \
|
||||
# Settings().value(self.main_window.general_settings_section + '/audio repeat list')
|
||||
#if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
|
||||
# self.audio_pause_item.setChecked(True)
|
||||
# self.display.audio_player.pause()
|
||||
#else:
|
||||
# self.display.audio_player.play()
|
||||
self.set_audio_items_visibility(True)
|
||||
# if self.display.audio_player:
|
||||
# self.display.audio_player.reset()
|
||||
# self.set_audio_items_visibility(False)
|
||||
# self.audio_pause_item.setChecked(False)
|
||||
# If the current item has background audio
|
||||
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
self.on_media_start(service_item)
|
||||
# self.log_debug('Starting to play...')
|
||||
# self.display.audio_player.add_to_playlist(self.service_item.background_audio)
|
||||
# self.track_menu.clear()
|
||||
# for counter in range(len(self.service_item.background_audio)):
|
||||
# action = self.track_menu.addAction(
|
||||
# os.path.basename(str(self.service_item.background_audio[counter])))
|
||||
# action.setData(counter)
|
||||
# action.triggered.connect(self.on_track_triggered)
|
||||
# self.display.audio_player.repeat = \
|
||||
# Settings().value(self.main_window.general_settings_section + '/audio repeat list')
|
||||
# if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
|
||||
# self.audio_pause_item.setChecked(True)
|
||||
# self.display.audio_player.pause()
|
||||
# else:
|
||||
# self.display.audio_player.play()
|
||||
# self.set_audio_items_visibility(True)
|
||||
row = 0
|
||||
width = self.main_window.control_splitter.sizes()[self.split]
|
||||
for frame_number, frame in enumerate(self.service_item.get_frames()):
|
||||
@ -1355,24 +1358,24 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
||||
self.on_toggle_loop()
|
||||
|
||||
def set_audio_items_visibility(self, visible):
|
||||
"""
|
||||
Set the visibility of the audio stuff
|
||||
"""
|
||||
self.toolbar.set_widget_visible(AUDIO_LIST, visible)
|
||||
# def set_audio_items_visibility(self, visible):
|
||||
# """
|
||||
# Set the visibility of the audio stuff
|
||||
# """
|
||||
# self.toolbar.set_widget_visible(AUDIO_LIST, visible)
|
||||
|
||||
def set_audio_pause_clicked(self, checked):
|
||||
"""
|
||||
Pause the audio player
|
||||
# def set_audio_pause_clicked(self, checked):
|
||||
# """
|
||||
# Pause the audio player
|
||||
|
||||
:param checked: is the check box checked.
|
||||
"""
|
||||
if not self.audio_pause_item.isVisible():
|
||||
return
|
||||
if checked:
|
||||
self.display.audio_player.pause()
|
||||
else:
|
||||
self.display.audio_player.play()
|
||||
# :param checked: is the check box checked.
|
||||
# """
|
||||
# if not self.audio_pause_item.isVisible():
|
||||
# return
|
||||
# if checked:
|
||||
# self.display.audio_player.pause()
|
||||
# else:
|
||||
# self.display.audio_player.play()
|
||||
|
||||
def timerEvent(self, event):
|
||||
"""
|
||||
@ -1509,29 +1512,29 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
else:
|
||||
return None
|
||||
|
||||
def on_next_track_clicked(self):
|
||||
"""
|
||||
Go to the next track when next is clicked
|
||||
"""
|
||||
self.display.audio_player.next()
|
||||
|
||||
def on_audio_time_remaining(self, time):
|
||||
"""
|
||||
Update how much time is remaining
|
||||
|
||||
:param time: the time remaining
|
||||
"""
|
||||
seconds = (self.display.audio_player.player.duration() - self.display.audio_player.player.position()) // 1000
|
||||
minutes = seconds // 60
|
||||
seconds %= 60
|
||||
self.audio_time_label.setText(' %02d:%02d ' % (minutes, seconds))
|
||||
|
||||
def on_track_triggered(self, field=None):
|
||||
"""
|
||||
Start playing a track
|
||||
"""
|
||||
action = self.sender()
|
||||
self.display.audio_player.go_to(action.data())
|
||||
# def on_next_track_clicked(self):
|
||||
# """
|
||||
# Go to the next track when next is clicked
|
||||
# """
|
||||
# self.display.audio_player.next()
|
||||
#
|
||||
# def on_audio_time_remaining(self, time):
|
||||
# """
|
||||
# Update how much time is remaining
|
||||
#
|
||||
# :param time: the time remaining
|
||||
# """
|
||||
# seconds = (self.display.audio_player.player.duration() - self.display.audio_player.player.position()) // 1000
|
||||
# minutes = seconds // 60
|
||||
# seconds %= 60
|
||||
# self.audio_time_label.setText(' %02d:%02d ' % (minutes, seconds))
|
||||
#
|
||||
# def on_track_triggered(self, field=None):
|
||||
# """
|
||||
# Start playing a track
|
||||
# """
|
||||
# action = self.sender()
|
||||
# self.display.audio_player.go_to(action.data())
|
||||
|
||||
|
||||
class PreviewController(RegistryBase, SlideController):
|
||||
|
@ -179,8 +179,6 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
:param remote: Triggered from remote
|
||||
:param context: Why is it being generated
|
||||
"""
|
||||
if State().check_active_dependency():
|
||||
a=1
|
||||
if item is None:
|
||||
item = self.list_view.currentItem()
|
||||
if item is None:
|
||||
@ -197,7 +195,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
translate('MediaPlugin.MediaItem',
|
||||
'The optical disc {name} is no longer available.').format(name=name))
|
||||
return False
|
||||
service_item.processor = self.display_type_combo_box.currentText()
|
||||
service_item.processor = 'vlc'
|
||||
service_item.add_from_command(filename, name, CLAPPERBOARD)
|
||||
service_item.title = clip_name
|
||||
# Set the length
|
||||
@ -218,8 +216,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
service_item.processor = 'vlc'
|
||||
service_item.add_from_command(path, name, CLAPPERBOARD)
|
||||
# Only get start and end times if going to a service
|
||||
if not self.media_controller.media_length(service_item):
|
||||
return False
|
||||
service_item.set_media_length(self.media_controller.media_length(filename))
|
||||
service_item.add_capability(ItemCapabilities.CanAutoStartForLive)
|
||||
service_item.add_capability(ItemCapabilities.CanEditTitle)
|
||||
service_item.add_capability(ItemCapabilities.RequiresMedia)
|
||||
|
Loading…
Reference in New Issue
Block a user