Make media play again and VLC arguments

bzr-revno: 2866
This commit is contained in:
Tim Bentley 2019-05-07 17:55:51 +01:00
commit 398200d5b4
13 changed files with 99 additions and 137 deletions

View File

@ -180,15 +180,13 @@ class Settings(QtCore.QSettings):
'api/thumbnails': True, 'api/thumbnails': True,
'crashreport/last directory': None, 'crashreport/last directory': None,
'formattingTags/html_tags': '', 'formattingTags/html_tags': '',
'core/audio repeat list': False,
'core/auto open': False, 'core/auto open': False,
'core/auto preview': False, 'core/auto preview': False,
'core/audio start paused': True,
'core/auto unblank': False, 'core/auto unblank': False,
'core/click live slide to unblank': False, 'core/click live slide to unblank': False,
'core/blank warning': False, 'core/blank warning': False,
'core/ccli number': '', 'core/ccli number': '',
'core/experimental': False, 'advanced/experimental': False,
'core/has run wizard': False, 'core/has run wizard': False,
'core/language': '[en]', 'core/language': '[en]',
'core/last version test': '', 'core/last version test': '',
@ -213,6 +211,7 @@ class Settings(QtCore.QSettings):
'images/background color': '#000000', 'images/background color': '#000000',
'media/media auto start': QtCore.Qt.Unchecked, 'media/media auto start': QtCore.Qt.Unchecked,
'media/stream command': '', 'media/stream command': '',
'media/vlc arguments': '',
'remotes/download version': '0.0', 'remotes/download version': '0.0',
'players/background color': '#000000', 'players/background color': '#000000',
'servicemanager/last directory': None, 'servicemanager/last directory': None,
@ -317,7 +316,9 @@ class Settings(QtCore.QSettings):
('bibles/proxy username', '', []), ('bibles/proxy username', '', []),
('bibles/proxy password', '', []), ('bibles/proxy password', '', []),
('media/players', '', []), ('media/players', '', []),
('media/override player', '', []) ('media/override player', '', []),
('core/audio start paused', '', []),
('core/audio repeat list', '', [])
] ]
@staticmethod @staticmethod

View File

@ -93,4 +93,4 @@ class SingleColumnTableWidget(QtWidgets.QTableWidget):
self.resizeRowsToContents() self.resizeRowsToContents()
__all__ = ['SingleColumnTableWidget'] __all__ = ['SingleColumnTableWidget', 'DisplayControllerType']

View File

@ -117,6 +117,9 @@ class AdvancedTab(SettingsTab):
self.enable_auto_close_check_box = QtWidgets.QCheckBox(self.ui_group_box) self.enable_auto_close_check_box = QtWidgets.QCheckBox(self.ui_group_box)
self.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box') self.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box')
self.ui_layout.addRow(self.enable_auto_close_check_box) self.ui_layout.addRow(self.enable_auto_close_check_box)
self.experimental_check_box = QtWidgets.QCheckBox(self.ui_group_box)
self.experimental_check_box.setObjectName('experimental_check_box')
self.ui_layout.addRow(self.experimental_check_box)
self.left_layout.addWidget(self.ui_group_box) self.left_layout.addWidget(self.ui_group_box)
if HAS_DARK_STYLE: if HAS_DARK_STYLE:
self.use_dark_style_checkbox = QtWidgets.QCheckBox(self.ui_group_box) self.use_dark_style_checkbox = QtWidgets.QCheckBox(self.ui_group_box)
@ -291,6 +294,8 @@ class AdvancedTab(SettingsTab):
'Auto-scroll the next slide to bottom')) 'Auto-scroll the next slide to bottom'))
self.enable_auto_close_check_box.setText(translate('OpenLP.AdvancedTab', self.enable_auto_close_check_box.setText(translate('OpenLP.AdvancedTab',
'Enable application exit confirmation')) 'Enable application exit confirmation'))
self.experimental_check_box.setText(translate('OpenLP.GeneralTab',
'Experimental features (use at your own risk)'))
if HAS_DARK_STYLE: if HAS_DARK_STYLE:
self.use_dark_style_checkbox.setText(translate('OpenLP.AdvancedTab', 'Use dark style (needs restart)')) self.use_dark_style_checkbox.setText(translate('OpenLP.AdvancedTab', 'Use dark style (needs restart)'))
self.service_name_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Default Service Name')) self.service_name_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Default Service Name'))
@ -360,6 +365,7 @@ class AdvancedTab(SettingsTab):
if self.autoscroll_map[i] == autoscroll_value and i < self.autoscroll_combo_box.count(): if self.autoscroll_map[i] == autoscroll_value and i < self.autoscroll_combo_box.count():
self.autoscroll_combo_box.setCurrentIndex(i) self.autoscroll_combo_box.setCurrentIndex(i)
self.enable_auto_close_check_box.setChecked(settings.value('enable exit confirmation')) self.enable_auto_close_check_box.setChecked(settings.value('enable exit confirmation'))
self.experimental_check_box.setChecked(settings.value('experimental'))
if HAS_DARK_STYLE: if HAS_DARK_STYLE:
self.use_dark_style_checkbox.setChecked(settings.value('use_dark_style')) self.use_dark_style_checkbox.setChecked(settings.value('use_dark_style'))
self.hide_mouse_check_box.setChecked(settings.value('hide mouse')) self.hide_mouse_check_box.setChecked(settings.value('hide mouse'))
@ -423,6 +429,7 @@ class AdvancedTab(SettingsTab):
slide_max_height_value = self.slide_max_height_combo_box.itemData(slide_max_height_index) slide_max_height_value = self.slide_max_height_combo_box.itemData(slide_max_height_index)
settings.setValue('slide max height', slide_max_height_value) settings.setValue('slide max height', slide_max_height_value)
settings.setValue('autoscrolling', self.autoscroll_map[self.autoscroll_combo_box.currentIndex()]) settings.setValue('autoscrolling', self.autoscroll_map[self.autoscroll_combo_box.currentIndex()])
settings.setValue('experimental', self.experimental_check_box.isChecked())
settings.setValue('enable exit confirmation', self.enable_auto_close_check_box.isChecked()) settings.setValue('enable exit confirmation', self.enable_auto_close_check_box.isChecked())
settings.setValue('hide mouse', self.hide_mouse_check_box.isChecked()) settings.setValue('hide mouse', self.hide_mouse_check_box.isChecked())
settings.setValue('alternate rows', self.alternate_rows_check_box.isChecked()) settings.setValue('alternate rows', self.alternate_rows_check_box.isChecked())

View File

@ -83,18 +83,6 @@ class GeneralTab(SettingsTab):
self.password_edit.setObjectName('password_edit') self.password_edit.setObjectName('password_edit')
self.ccli_layout.addRow(self.password_label, self.password_edit) self.ccli_layout.addRow(self.password_label, self.password_edit)
self.left_layout.addWidget(self.ccli_group_box) self.left_layout.addWidget(self.ccli_group_box)
# Background audio
self.audio_group_box = QtWidgets.QGroupBox(self.left_column)
self.audio_group_box.setObjectName('audio_group_box')
self.audio_layout = QtWidgets.QVBoxLayout(self.audio_group_box)
self.audio_layout.setObjectName('audio_layout')
self.start_paused_check_box = QtWidgets.QCheckBox(self.audio_group_box)
self.start_paused_check_box.setObjectName('start_paused_check_box')
self.audio_layout.addWidget(self.start_paused_check_box)
self.repeat_list_check_box = QtWidgets.QCheckBox(self.audio_group_box)
self.repeat_list_check_box.setObjectName('repeat_list_check_box')
self.audio_layout.addWidget(self.repeat_list_check_box)
self.left_layout.addWidget(self.audio_group_box)
self.left_layout.addStretch() self.left_layout.addStretch()
# Application Startup # Application Startup
self.startup_group_box = QtWidgets.QGroupBox(self.right_column) self.startup_group_box = QtWidgets.QGroupBox(self.right_column)
@ -195,9 +183,7 @@ class GeneralTab(SettingsTab):
self.number_label.setText(UiStrings().CCLINumberLabel) self.number_label.setText(UiStrings().CCLINumberLabel)
self.username_label.setText(translate('OpenLP.GeneralTab', 'SongSelect username:')) self.username_label.setText(translate('OpenLP.GeneralTab', 'SongSelect username:'))
self.password_label.setText(translate('OpenLP.GeneralTab', 'SongSelect password:')) self.password_label.setText(translate('OpenLP.GeneralTab', 'SongSelect password:'))
self.audio_group_box.setTitle(translate('OpenLP.GeneralTab', 'Background Audio')) self.logo_file_path_edit.dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File')
self.start_paused_check_box.setText(translate('OpenLP.GeneralTab', 'Start background audio paused'))
self.repeat_list_check_box.setText(translate('OpenLP.GeneralTab', 'Repeat track list'))
self.logo_file_path_edit.dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File') self.logo_file_path_edit.dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File')
self.logo_file_path_edit.filters = '{text};;{names} (*)'.format( self.logo_file_path_edit.filters = '{text};;{names} (*)'.format(
text=get_images_filter(), names=UiStrings().AllFiles) text=get_images_filter(), names=UiStrings().AllFiles)
@ -224,8 +210,6 @@ class GeneralTab(SettingsTab):
self.check_for_updates_check_box.setChecked(settings.value('update check')) self.check_for_updates_check_box.setChecked(settings.value('update check'))
self.auto_preview_check_box.setChecked(settings.value('auto preview')) self.auto_preview_check_box.setChecked(settings.value('auto preview'))
self.timeout_spin_box.setValue(settings.value('loop delay')) self.timeout_spin_box.setValue(settings.value('loop delay'))
self.start_paused_check_box.setChecked(settings.value('audio start paused'))
self.repeat_list_check_box.setChecked(settings.value('audio repeat list'))
settings.endGroup() settings.endGroup()
def save(self): def save(self):
@ -249,8 +233,6 @@ class GeneralTab(SettingsTab):
settings.setValue('ccli number', self.number_edit.displayText()) settings.setValue('ccli number', self.number_edit.displayText())
settings.setValue('songselect username', self.username_edit.displayText()) settings.setValue('songselect username', self.username_edit.displayText())
settings.setValue('songselect password', self.password_edit.displayText()) settings.setValue('songselect password', self.password_edit.displayText())
settings.setValue('audio start paused', self.start_paused_check_box.isChecked())
settings.setValue('audio repeat list', self.repeat_list_check_box.isChecked())
settings.endGroup() settings.endGroup()
self.post_set_up() self.post_set_up()

View File

@ -20,8 +20,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # # along with this program. If not, see <https://www.gnu.org/licenses/>. #
########################################################################## ##########################################################################
""" """
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 is the control module for all media playing.
related to playing media, such as sliders.
""" """
import logging import logging
@ -124,14 +123,14 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
""" """
self.setup() self.setup()
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, requires="mediacontroller") State().add_service('media_live', 0)
if get_vlc() and pymediainfo_available: if get_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:
State().missing_text("mediacontroller", translate('OpenLP.SlideController', State().missing_text('media_live', translate('OpenLP.SlideController',
"VLC or pymediainfo are missing, so you are unable to play any media")) 'VLC or pymediainfo are missing, so you are unable to play any media'))
self._generate_extensions_lists() self._generate_extensions_lists()
return True return True
@ -140,11 +139,14 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
Set up the controllers. Set up the controllers.
:return: :return:
""" """
try: if State().check_preconditions('mediacontroller'):
self.setup_display(self.live_controller.display, False) try:
except AttributeError: self.setup_display(self.live_controller.display, False)
State().update_pre_conditions('media_live', False) except AttributeError:
self.setup_display(self.preview_controller.preview_display, True) State().update_pre_conditions('media_live', False)
State().missing_text('media_live', translate('OpenLP.SlideController',
'No Displays configure so Live Media has been disabled'))
self.setup_display(self.preview_controller.preview_display, True)
def display_controllers(self, controller_type): def display_controllers(self, controller_type):
""" """
@ -215,9 +217,6 @@ 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 self.current_media_players and value:
# controller.display.set_transparency(False)
@staticmethod @staticmethod
def resize(display, player): def resize(display, player):
@ -563,8 +562,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
total_seconds = controller.media_info.length // 1000 total_seconds = controller.media_info.length // 1000
total_minutes = total_seconds // 60 total_minutes = total_seconds // 60
total_seconds %= 60 total_seconds %= 60
controller.position_label.setText(' %02d:%02d / %02d:%02d' % controller.position_label.setText(' %02d:%02d / %02d:%02d' % (0, 0, total_minutes, total_seconds))
(0, 0, total_minutes, total_seconds))
controller.mediabar.actions['playbackPlay'].setVisible(True) controller.mediabar.actions['playbackPlay'].setVisible(True)
controller.mediabar.actions['playbackStop'].setDisabled(True) controller.mediabar.actions['playbackStop'].setDisabled(True)
controller.mediabar.actions['playbackPause'].setVisible(False) controller.mediabar.actions['playbackPause'].setVisible(False)

View File

@ -139,11 +139,12 @@ class MediaPlayer(RegistryProperties):
""" """
pass pass
def update_ui(self, display): def update_ui(self, controller, output_display):
""" """
Do some ui related stuff (e.g. update the seek slider) Do some ui related stuff (e.g. update the seek slider)
:param display: The display to be updated. :param controller: Which Controller is running the show.
:param output_display: The display where the media is
""" """
pass pass

View File

@ -20,11 +20,12 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # # along with this program. If not, see <https://www.gnu.org/licenses/>. #
########################################################################## ##########################################################################
""" """
The :mod:`~openlp.core.ui.media.playertab` module holds the configuration tab for the media stuff. The :mod:`~openlp.core.ui.media.mediatab` module holds the configuration tab for the media stuff.
""" """
import logging
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
# from PyQt5.QtMultimedia import QCameraInfo, QAudioDeviceInfo, QAudio from PyQt5.QtMultimedia import QCameraInfo, QAudioDeviceInfo, QAudio
from openlp.core.common import is_linux, is_win from openlp.core.common import is_linux, is_win
from openlp.core.common.i18n import translate from openlp.core.common.i18n import translate
@ -32,8 +33,11 @@ from openlp.core.common.settings import Settings
from openlp.core.lib.settingstab import SettingsTab from openlp.core.lib.settingstab import SettingsTab
from openlp.core.ui.icons import UiIcons from openlp.core.ui.icons import UiIcons
LINUX_STREAM = 'v4l2:///dev/video0' LINUX_STREAM = 'v4l2://{video} :v4l2-standard= :input-slave={audio} :live-caching=300'
WIN_STREAM = 'dshow:// :dshow-vdev=' WIN_STREAM = 'dshow://:dshow-vdev={video} :dshow-adev={audio} :live-caching=300'
OSX_STREAM = 'avcapture://{video} :qtsound://{audio} :live-caching=300'
log = logging.getLogger(__name__)
class MediaTab(SettingsTab): class MediaTab(SettingsTab):
@ -44,8 +48,6 @@ class MediaTab(SettingsTab):
""" """
Constructor Constructor
""" """
# self.media_players = Registry().get('media_controller').media_players
# self.saved_used_players = None
self.icon_path = UiIcons().video self.icon_path = UiIcons().video
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)
@ -67,39 +69,52 @@ class MediaTab(SettingsTab):
self.stream_media_group_box = QtWidgets.QGroupBox(self.left_column) self.stream_media_group_box = QtWidgets.QGroupBox(self.left_column)
self.stream_media_group_box.setObjectName('stream_media_group_box') self.stream_media_group_box.setObjectName('stream_media_group_box')
self.stream_media_layout = QtWidgets.QHBoxLayout(self.stream_media_group_box) self.stream_media_layout = QtWidgets.QHBoxLayout(self.stream_media_group_box)
self.stream_media_layout.setObjectName('live_media_layout') self.stream_media_layout.setObjectName('stream_media_layout')
self.stream_media_layout.setContentsMargins(0, 0, 0, 0) self.stream_media_layout.setContentsMargins(0, 0, 0, 0)
self.stream_edit = QtWidgets.QPlainTextEdit(self) self.stream_edit = QtWidgets.QLabel(self)
self.stream_media_layout.addWidget(self.stream_edit) self.stream_media_layout.addWidget(self.stream_edit)
self.browse_button = QtWidgets.QToolButton(self)
self.browse_button.setIcon(UiIcons().undo)
self.stream_media_layout.addWidget(self.browse_button)
self.left_layout.addWidget(self.stream_media_group_box)
self.left_layout.addWidget(self.stream_media_group_box) self.left_layout.addWidget(self.stream_media_group_box)
self.vlc_arguments_group_box = QtWidgets.QGroupBox(self.left_column)
self.vlc_arguments_group_box.setObjectName('vlc_arguments_group_box')
self.vlc_arguments_layout = QtWidgets.QHBoxLayout(self.vlc_arguments_group_box)
self.vlc_arguments_layout.setObjectName('vlc_arguments_layout')
self.vlc_arguments_layout.setContentsMargins(0, 0, 0, 0)
self.vlc_arguments_edit = QtWidgets.QPlainTextEdit(self)
self.vlc_arguments_layout.addWidget(self.vlc_arguments_edit)
self.left_layout.addWidget(self.vlc_arguments_group_box)
self.left_layout.addStretch() self.left_layout.addStretch()
self.right_layout.addStretch() self.right_layout.addStretch()
# # Signals and slots # # Signals and slots
self.browse_button.clicked.connect(self.on_revert)
def retranslateUi(self): def retranslate_ui(self):
""" """
Translate the UI on the fly Translate the UI on the fly
""" """
self.live_media_group_box.setTitle(translate('MediaPlugin.MediaTab', 'Live Media')) self.live_media_group_box.setTitle(translate('MediaPlugin.MediaTab', 'Live Media'))
self.stream_media_group_box.setTitle(translate('MediaPlugin.MediaTab', 'Stream Media Command')) self.stream_media_group_box.setTitle(translate('MediaPlugin.MediaTab', 'Stream Media Command'))
self.auto_start_check_box.setText(translate('MediaPlugin.MediaTab', 'Start automatically')) self.vlc_arguments_group_box.setTitle(translate('MediaPlugin.MediaTab', 'VLC arguments'))
self.auto_start_check_box.setText(translate('MediaPlugin.MediaTab', 'Start Live items automatically'))
def load(self): def load(self):
""" """
Load the settings Load the settings
""" """
self.auto_start_check_box.setChecked(Settings().value(self.settings_section + '/media auto start')) self.auto_start_check_box.setChecked(Settings().value(self.settings_section + '/media auto start'))
self.stream_edit.setPlainText(Settings().value(self.settings_section + '/stream command')) self.stream_edit.setText(Settings().value(self.settings_section + '/stream command'))
if not self.stream_edit.toPlainText(): if not self.stream_edit.text():
if is_linux: if is_linux:
self.stream_edit.setPlainText(LINUX_STREAM) self.stream_edit.setText(LINUX_STREAM)
elif is_win: elif is_win:
self.stream_edit.setPlainText(WIN_STREAM) self.stream_edit.setText(WIN_STREAM)
else:
self.stream_edit.setText(OSX_STREAM)
self.vlc_arguments_edit.setPlainText(Settings().value(self.settings_section + '/vlc arguments'))
if Settings().value('advanced/experimental'):
for cam in QCameraInfo.availableCameras():
log.debug(cam.deviceName())
log.debug(cam.description())
for au in QAudioDeviceInfo.availableDevices(QAudio.AudioInput):
log.debug(au.deviceName())
def save(self): def save(self):
""" """
@ -108,17 +123,8 @@ class MediaTab(SettingsTab):
setting_key = self.settings_section + '/media auto start' setting_key = self.settings_section + '/media auto start'
if Settings().value(setting_key) != self.auto_start_check_box.checkState(): if Settings().value(setting_key) != self.auto_start_check_box.checkState():
Settings().setValue(setting_key, self.auto_start_check_box.checkState()) Settings().setValue(setting_key, self.auto_start_check_box.checkState())
# settings = Settings() Settings().setValue(self.settings_section + '/stream command', self.stream_edit.text())
# settings.beginGroup(self.settings_section) Settings().setValue(self.settings_section + '/vlc arguments', self.vlc_arguments_edit.toPlainText())
# settings.setValue('background color', self.background_color)
# settings.endGroup()
# old_players, override_player = get_media_players()
# if self.used_players != old_players:
# # clean old Media stuff
# set_media_players(self.used_players, override_player)
# self.settings_form.register_post_process('mediaitem_suffix_reset')
# self.settings_form.register_post_process('mediaitem_media_rebuild')
# self.settings_form.register_post_process('config_screen_changed')
def post_set_up(self, post_update=False): def post_set_up(self, post_update=False):
""" """
@ -127,22 +133,6 @@ class MediaTab(SettingsTab):
:param post_update: Indicates if called before or after updates. :param post_update: Indicates if called before or after updates.
""" """
pass pass
# for key, player in self.media_players.items():
# player = self.media_players[key]
# checkbox = MediaQCheckBox(self.media_player_group_box)
# checkbox.setEnabled(player.available)
# checkbox.setObjectName(player.name + '_check_box')
# checkbox.setToolTip(player.get_info())
# checkbox.set_player_name(player.name)
# self.player_check_boxes[player.name] = checkbox
# checkbox.stateChanged.connect(self.on_player_check_box_changed)
# self.media_player_layout.addWidget(checkbox)
# if player.available and player.name in self.used_players:
# checkbox.setChecked(True)
# else:
# checkbox.setChecked(False)
# self.update_player_list()
# self.retranslate_players()
def on_revert(self): def on_revert(self):
pass pass

View File

@ -164,9 +164,11 @@ class VlcPlayer(MediaPlayer):
output_display.vlc_widget = QtWidgets.QFrame(output_display) output_display.vlc_widget = QtWidgets.QFrame(output_display)
output_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 Settings().value('advanced/hide mouse') and live_display: if Settings().value('advanced/hide mouse') and live_display:
command_line_options += ' --mouse-hide-timeout=0' command_line_options += '--mouse-hide-timeout=0 '
if Settings().value('media/vlc arguments'):
command_line_options += Settings().value('media/vlc arguments')
output_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
output_display.vlc_media_player = output_display.vlc_instance.media_player_new() output_display.vlc_media_player = output_display.vlc_instance.media_player_new()
@ -224,7 +226,8 @@ class VlcPlayer(MediaPlayer):
return False return False
output_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:
output_display.vlc_media = output_display.vlc_instance.media_new_location('ZZZZZZ') stream_cmd = Settings().value('media/stream command')
output_display.vlc_media = output_display.vlc_instance.media_new_location(stream_cmd)
else: else:
output_display.vlc_media = output_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
@ -240,7 +243,7 @@ class VlcPlayer(MediaPlayer):
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)
:param media_state: The state of the playing media :param media_state: The state of the playing media
: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()
@ -314,7 +317,7 @@ class VlcPlayer(MediaPlayer):
self.volume(output_display, output_display.media_info.volume) self.volume(output_display, output_display.media_info.volume)
if start_time > 0 and output_display.vlc_media_player.is_seekable(): if start_time > 0 and output_display.vlc_media_player.is_seekable():
output_display.vlc_media_player.set_time(int(start_time)) output_display.vlc_media_player.set_time(int(start_time))
controller.seek_slider.setMaximum(output_display.media_info.length) controller.seek_slider.setMaximum(controller.media_info.length)
self.set_state(MediaState.Playing, output_display) self.set_state(MediaState.Playing, output_display)
output_display.vlc_widget.raise_() output_display.vlc_widget.raise_()
return True return True
@ -361,9 +364,9 @@ class VlcPlayer(MediaPlayer):
:param seek_value: The position of where a seek goes to :param seek_value: The position of where a seek goes to
:param output_display: The display where the media is :param output_display: The display where the media is
""" """
if output_display.controller.media_info.media_type == MediaType.CD \ if output_display.media_info.media_type == MediaType.CD \
or output_display.controller.media_info.media_type == MediaType.DVD: or output_display.media_info.media_type == MediaType.DVD:
seek_value += int(output_display.controller.media_info.start_time) seek_value += int(output_display.media_info.start_time)
if output_display.vlc_media_player.is_seekable(): if output_display.vlc_media_player.is_seekable():
output_display.vlc_media_player.set_time(seek_value) output_display.vlc_media_player.set_time(seek_value)

View File

@ -30,7 +30,6 @@ from openlp.core.state import State
from openlp.core.api.tab import ApiTab from openlp.core.api.tab import ApiTab
from openlp.core.common.mixins import RegistryProperties from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.lib import build_icon from openlp.core.lib import build_icon
from openlp.core.projectors.tab import ProjectorTab from openlp.core.projectors.tab import ProjectorTab
from openlp.core.ui.advancedtab import AdvancedTab from openlp.core.ui.advancedtab import AdvancedTab
@ -61,6 +60,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
self.setting_list_widget.currentRowChanged.connect(self.list_item_changed) self.setting_list_widget.currentRowChanged.connect(self.list_item_changed)
self.general_tab = None self.general_tab = None
self.themes_tab = None self.themes_tab = None
self.player_tab = None
self.projector_tab = None self.projector_tab = None
self.advanced_tab = None self.advanced_tab = None
self.api_tab = None self.api_tab = None
@ -79,8 +79,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
self.insert_tab(self.advanced_tab) self.insert_tab(self.advanced_tab)
self.insert_tab(self.screens_tab) self.insert_tab(self.screens_tab)
self.insert_tab(self.themes_tab) self.insert_tab(self.themes_tab)
if Settings().value('core/experimental'): self.insert_tab(self.player_tab)
self.insert_tab(self.player_tab)
self.insert_tab(self.projector_tab) self.insert_tab(self.projector_tab)
self.insert_tab(self.api_tab) self.insert_tab(self.api_tab)
for plugin in State().list_plugins(): for plugin in State().list_plugins():
@ -161,8 +160,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
self.themes_tab = ThemesTab(self) self.themes_tab = ThemesTab(self)
self.projector_tab = ProjectorTab(self) self.projector_tab = ProjectorTab(self)
self.advanced_tab = AdvancedTab(self) self.advanced_tab = AdvancedTab(self)
if Settings().value('core/experimental'): self.player_tab = MediaTab(self)
self.player_tab = MediaTab(self)
self.api_tab = ApiTab(self) self.api_tab = ApiTab(self)
self.screens_tab = ScreensTab(self) self.screens_tab = ScreensTab(self)
except Exception as e: except Exception as e:
@ -170,8 +168,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
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()
if Settings().value('core/experimental'): self.player_tab.post_set_up()
self.player_tab.post_set_up()
self.api_tab.post_set_up() self.api_tab.post_set_up()
for plugin in State().list_plugins(): for plugin in State().list_plugins():
if plugin.settings_tab: if plugin.settings_tab:

View File

@ -112,7 +112,7 @@ class MediaSlider(QtWidgets.QSlider):
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 ability to add a ellipsis if the text is cut off. Original
source: https://stackoverflow.com/questions/11446478/pyside-pyqt-truncate-text-in-qlabel-based-on-minimumsize source: https://stackoverflow.com/questions/11446478/pyside-pyqt-truncate-text-in-qlabel-based-on-minimumsize
""" """
@ -177,7 +177,6 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
if screen.is_display: if screen.is_display:
display = DisplayWindow(self, screen) display = DisplayWindow(self, screen)
self.displays.append(display) self.displays.append(display)
# display.media_watcher.progress.connect(self.on_audio_time_remaining)
@property @property
def display(self): def display(self):
@ -381,7 +380,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.position_label.setMinimumSize(90, 0) self.position_label.setMinimumSize(90, 0)
self.position_label.setObjectName('position_label') self.position_label.setObjectName('position_label')
self.mediabar.add_toolbar_widget(self.position_label) self.mediabar.add_toolbar_widget(self.position_label)
# Build the seek_slider. # Build the media seek_slider.
self.seek_slider = MediaSlider(QtCore.Qt.Horizontal, self, self) self.seek_slider = MediaSlider(QtCore.Qt.Horizontal, self, self)
self.seek_slider.setMaximum(1000) self.seek_slider.setMaximum(1000)
self.seek_slider.setTracking(True) self.seek_slider.setTracking(True)
@ -398,7 +397,6 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.volume_slider.setMaximum(100) self.volume_slider.setMaximum(100)
self.volume_slider.setTracking(True) self.volume_slider.setTracking(True)
self.volume_slider.setToolTip(translate('OpenLP.SlideController', 'Audio Volume.')) 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.setGeometry(QtCore.QRect(90, 160, 221, 24))
self.volume_slider.setObjectName('volume_slider') self.volume_slider.setObjectName('volume_slider')
self.mediabar.add_toolbar_widget(self.volume_slider) self.mediabar.add_toolbar_widget(self.volume_slider)

View File

@ -26,19 +26,18 @@ import os
import zipfile import zipfile
from xml.etree.ElementTree import XML, ElementTree from xml.etree.ElementTree import XML, ElementTree
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtWidgets
from openlp.core.common import delete_file from openlp.core.common import delete_file
from openlp.core.common.applocation import AppLocation from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import UiStrings, get_locale_key, translate from openlp.core.common.i18n import UiStrings, get_locale_key, translate
from openlp.core.common.mixins import LogMixin, RegistryProperties from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.path import Path, copyfile, create_paths, path_to_str from openlp.core.common.path import Path, copyfile, create_paths
from openlp.core.common.registry import Registry, RegistryBase from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.core.lib import ImageSource, build_icon, check_item_selected, create_thumb, get_text_file_string, \ from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb
validate_thumb
from openlp.core.lib.exceptions import ValidationError from openlp.core.lib.exceptions import ValidationError
from openlp.core.lib.theme import BackgroundType, Theme from openlp.core.lib.theme import Theme
from openlp.core.lib.ui import create_widget_action, critical_error_message_box from openlp.core.lib.ui import create_widget_action, critical_error_message_box
from openlp.core.ui.filerenameform import FileRenameForm from openlp.core.ui.filerenameform import FileRenameForm
from openlp.core.ui.icons import UiIcons from openlp.core.ui.icons import UiIcons
@ -648,11 +647,6 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
:rtype: None :rtype: None
""" """
self._write_theme(theme, image_source_path, image_destination_path) self._write_theme(theme, image_source_path, image_destination_path)
if theme.background_type == BackgroundType.to_string(BackgroundType.Image):
self.image_manager.update_image_border(path_to_str(theme.background_filename),
ImageSource.Theme,
QtGui.QColor(theme.background_border_color))
self.image_manager.process_updates()
def _write_theme(self, theme, image_source_path=None, image_destination_path=None): def _write_theme(self, theme, image_source_path=None, image_destination_path=None):
""" """

View File

@ -93,16 +93,6 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
to another language. to another language.
""" """
self.on_new_prompt = translate('MediaPlugin.MediaItem', 'Select Media') self.on_new_prompt = translate('MediaPlugin.MediaItem', 'Select Media')
# self.replace_action.setText(UiStrings().ReplaceBG)
# self.replace_action_context.setText(UiStrings().ReplaceBG)
# self.replace_action.setToolTip(UiStrings().ReplaceLiveBGDisabled)
# self.replace_action_context.setToolTip(UiStrings().ReplaceLiveBGDisabled)
# self.reset_action.setText(UiStrings().ResetBG)
# self.reset_action.setToolTip(UiStrings().ResetLiveBG)
# self.reset_action_context.setText(UiStrings().ResetBG)
# self.reset_action_context.setToolTip(UiStrings().ResetLiveBG)
# self.automatic = UiStrings().Automatic
# self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:'))
def required_icons(self): def required_icons(self):
""" """
@ -117,7 +107,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
self.can_make_live = False self.can_make_live = False
self.can_add_to_service = False self.can_add_to_service = False
if State().check_preconditions('media_live'): if State().check_preconditions('media_live'):
self.can_make_live = False self.can_make_live = True
def add_list_view_to_toolbar(self): def add_list_view_to_toolbar(self):
""" """

View File

@ -126,7 +126,7 @@ class TestVLCPlayer(TestCase, TestMixin):
mocked_is_macosx.return_value = False mocked_is_macosx.return_value = False
mocked_is_win.return_value = False mocked_is_win.return_value = False
mocked_settings = MagicMock() mocked_settings = MagicMock()
mocked_settings.value.return_value = True mocked_settings.value.return_value = ''
MockedSettings.return_value = mocked_settings MockedSettings.return_value = mocked_settings
mocked_qframe = MagicMock() mocked_qframe = MagicMock()
mocked_qframe.winId.return_value = 2 mocked_qframe.winId.return_value = 2
@ -150,8 +150,9 @@ class TestVLCPlayer(TestCase, TestMixin):
# THEN: The VLC widget should be set up correctly # THEN: The VLC widget should be set up correctly
assert mocked_output_display.vlc_widget == mocked_qframe assert mocked_output_display.vlc_widget == mocked_qframe
mocked_qframe.setFrameStyle.assert_called_with(1) mocked_qframe.setFrameStyle.assert_called_with(1)
mocked_settings.value.assert_called_with('advanced/hide mouse') mocked_settings.value.assert_any_call('advanced/hide mouse')
mocked_vlc.Instance.assert_called_with('--no-video-title-show --mouse-hide-timeout=0') mocked_settings.value.assert_any_call('media/vlc arguments')
mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
assert mocked_output_display.vlc_instance == mocked_instance assert mocked_output_display.vlc_instance == mocked_instance
mocked_instance.media_player_new.assert_called_with() mocked_instance.media_player_new.assert_called_with()
assert mocked_output_display.vlc_media_player == mocked_media_player_new assert mocked_output_display.vlc_media_player == mocked_media_player_new
@ -175,7 +176,7 @@ class TestVLCPlayer(TestCase, TestMixin):
mocked_is_macosx.return_value = False mocked_is_macosx.return_value = False
mocked_is_win.return_value = False mocked_is_win.return_value = False
mocked_settings = MagicMock() mocked_settings = MagicMock()
mocked_settings.value.return_value = True mocked_settings.value.return_value = ''
MockedSettings.return_value = mocked_settings MockedSettings.return_value = mocked_settings
mocked_qframe = MagicMock() mocked_qframe = MagicMock()
mocked_qframe.winId.return_value = 2 mocked_qframe.winId.return_value = 2
@ -197,7 +198,7 @@ class TestVLCPlayer(TestCase, TestMixin):
vlc_player.setup(mocked_output_display, mocked_controller) vlc_player.setup(mocked_output_display, mocked_controller)
# THEN: The VLC instance should be created with the correct options # THEN: The VLC instance should be created with the correct options
mocked_vlc.Instance.assert_called_with('--no-video-title-show --mouse-hide-timeout=0') mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
@patch('openlp.core.ui.media.vlcplayer.is_win') @patch('openlp.core.ui.media.vlcplayer.is_win')
@patch('openlp.core.ui.media.vlcplayer.is_macosx') @patch('openlp.core.ui.media.vlcplayer.is_macosx')
@ -213,7 +214,7 @@ class TestVLCPlayer(TestCase, TestMixin):
mocked_is_macosx.return_value = False mocked_is_macosx.return_value = False
mocked_is_win.return_value = False mocked_is_win.return_value = False
mocked_settings = MagicMock() mocked_settings = MagicMock()
mocked_settings.value.return_value = False mocked_settings.value.return_value = ''
MockedSettings.return_value = mocked_settings MockedSettings.return_value = mocked_settings
mocked_qframe = MagicMock() mocked_qframe = MagicMock()
mocked_qframe.winId.return_value = 2 mocked_qframe.winId.return_value = 2
@ -235,7 +236,7 @@ class TestVLCPlayer(TestCase, TestMixin):
vlc_player.setup(mocked_output_display, mocked_controller) vlc_player.setup(mocked_output_display, mocked_controller)
# THEN: The VLC instance should be created with the correct options # THEN: The VLC instance should be created with the correct options
mocked_vlc.Instance.assert_called_with('--no-video-title-show') mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
@patch('openlp.core.ui.media.vlcplayer.is_win') @patch('openlp.core.ui.media.vlcplayer.is_win')
@patch('openlp.core.ui.media.vlcplayer.is_macosx') @patch('openlp.core.ui.media.vlcplayer.is_macosx')
@ -863,7 +864,7 @@ class TestVLCPlayer(TestCase, TestMixin):
# THEN: nothing should happen # THEN: nothing should happen
mocked_display.vlc_media_player.is_seekable.assert_called_with() mocked_display.vlc_media_player.is_seekable.assert_called_with()
mocked_display.vlc_media_player.set_time.assert_called_with(5000) mocked_display.vlc_media_player.set_time.assert_called_with(2000)
def test_reset(self): def test_reset(self):
""" """