Merge lp:~trb143/openlp/more_media into lp:openlp

Proposed by Tim Bentley
Status: Merged
Merged at revision: 2866
Proposed branch: lp:~trb143/openlp/more_media
Merge into: lp:openlp
Diff against target: 672 lines (+100/-138)
13 files modified
openlp/core/common/settings.py (+5/-4)
openlp/core/ui/__init__.py (+1/-1)
openlp/core/ui/advancedtab.py (+7/-0)
openlp/core/ui/generaltab.py (+1/-19)
openlp/core/ui/media/mediacontroller.py (+15/-17)
openlp/core/ui/media/mediaplayer.py (+3/-2)
openlp/core/ui/media/mediatab.py (+37/-47)
openlp/core/ui/media/vlcplayer.py (+11/-8)
openlp/core/ui/settingsform.py (+4/-7)
openlp/core/ui/slidecontroller.py (+2/-4)
openlp/core/ui/thememanager.py (+4/-10)
openlp/plugins/media/lib/mediaitem.py (+1/-11)
tests/functional/openlp_core/ui/media/test_vlcplayer.py (+9/-8)
To merge this branch: bzr merge lp:~trb143/openlp/more_media
Reviewer Review Type Date Requested Status
Raoul Snyman Approve
Tomas Groth Pending
Review via email: mp+366957@code.launchpad.net

This proposal supersedes a proposal from 2019-04-27.

Commit message

Media plays successfully and cleanups.
Added VLC additions

Description of the change

Media now plays, stops, seeks and repeats.
Media Tab now works but needs more love.
VLC arguments is now added and usable.
Experimental flag added to UI. Set this and it may go bang. You will need to edit settings manually to release this!
Add code (provided by tgc and superfly) to get media components. Works fine outside OpenLP but takes out OpenLP on Fedora 30. Activate by using experimental and restart.
Fixed the imagemanager bug on saving themes. Now works except preview image is black!
Removed many bits of commented out code.

To post a comment you must log in.
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linting failed, please see https://ci.openlp.io/job/MP-03-Linting/76/ for more details

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linting passed!

Revision history for this message
Tomas Groth (tomasgroth) wrote : Posted in a previous version of this proposal

A few comments below. Will try to test on a few systems later.

review: Needs Fixing
Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

Prints are there as the code just explodes on my machine and shuts OpenLP down.
No worth doing anything cute while it is this state! They never get called.

Happy to move flag.

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

macOS tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linting passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

macOS tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Looks good.

One thing I would prefer to change though, is "VLC additions" aka "VLC additional commands". They are not commands, they are command line arguments, so I would call them "VLC arguments". In my opinion, "additions" is ambiguous and unclear.

review: Needs Fixing
Revision history for this message
Tomas Groth (tomasgroth) wrote : Posted in a previous version of this proposal

I tried running the branch on a windows system which I then realized didn't have VLC. But it resulted in this traceback: https://bin.snyman.info/mmmvuquw

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

Linux tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

Linting passed!

Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

macOS tests passed!

Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve
lp:~trb143/openlp/more_media updated
2866. By Tim Bentley

Make media play again and VLC arguments

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/common/settings.py'
2--- openlp/core/common/settings.py 2019-04-13 13:00:22 +0000
3+++ openlp/core/common/settings.py 2019-05-05 06:00:56 +0000
4@@ -180,15 +180,13 @@
5 'api/thumbnails': True,
6 'crashreport/last directory': None,
7 'formattingTags/html_tags': '',
8- 'core/audio repeat list': False,
9 'core/auto open': False,
10 'core/auto preview': False,
11- 'core/audio start paused': True,
12 'core/auto unblank': False,
13 'core/click live slide to unblank': False,
14 'core/blank warning': False,
15 'core/ccli number': '',
16- 'core/experimental': False,
17+ 'advanced/experimental': False,
18 'core/has run wizard': False,
19 'core/language': '[en]',
20 'core/last version test': '',
21@@ -213,6 +211,7 @@
22 'images/background color': '#000000',
23 'media/media auto start': QtCore.Qt.Unchecked,
24 'media/stream command': '',
25+ 'media/vlc arguments': '',
26 'remotes/download version': '0.0',
27 'players/background color': '#000000',
28 'servicemanager/last directory': None,
29@@ -317,7 +316,9 @@
30 ('bibles/proxy username', '', []),
31 ('bibles/proxy password', '', []),
32 ('media/players', '', []),
33- ('media/override player', '', [])
34+ ('media/override player', '', []),
35+ ('core/audio start paused', '', []),
36+ ('core/audio repeat list', '', [])
37 ]
38
39 @staticmethod
40
41=== modified file 'openlp/core/ui/__init__.py'
42--- openlp/core/ui/__init__.py 2019-04-13 13:00:22 +0000
43+++ openlp/core/ui/__init__.py 2019-05-05 06:00:56 +0000
44@@ -93,4 +93,4 @@
45 self.resizeRowsToContents()
46
47
48-__all__ = ['SingleColumnTableWidget']
49+__all__ = ['SingleColumnTableWidget', 'DisplayControllerType']
50
51=== modified file 'openlp/core/ui/advancedtab.py'
52--- openlp/core/ui/advancedtab.py 2019-04-13 13:00:22 +0000
53+++ openlp/core/ui/advancedtab.py 2019-05-05 06:00:56 +0000
54@@ -117,6 +117,9 @@
55 self.enable_auto_close_check_box = QtWidgets.QCheckBox(self.ui_group_box)
56 self.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box')
57 self.ui_layout.addRow(self.enable_auto_close_check_box)
58+ self.experimental_check_box = QtWidgets.QCheckBox(self.ui_group_box)
59+ self.experimental_check_box.setObjectName('experimental_check_box')
60+ self.ui_layout.addRow(self.experimental_check_box)
61 self.left_layout.addWidget(self.ui_group_box)
62 if HAS_DARK_STYLE:
63 self.use_dark_style_checkbox = QtWidgets.QCheckBox(self.ui_group_box)
64@@ -291,6 +294,8 @@
65 'Auto-scroll the next slide to bottom'))
66 self.enable_auto_close_check_box.setText(translate('OpenLP.AdvancedTab',
67 'Enable application exit confirmation'))
68+ self.experimental_check_box.setText(translate('OpenLP.GeneralTab',
69+ 'Experimental features (use at your own risk)'))
70 if HAS_DARK_STYLE:
71 self.use_dark_style_checkbox.setText(translate('OpenLP.AdvancedTab', 'Use dark style (needs restart)'))
72 self.service_name_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Default Service Name'))
73@@ -360,6 +365,7 @@
74 if self.autoscroll_map[i] == autoscroll_value and i < self.autoscroll_combo_box.count():
75 self.autoscroll_combo_box.setCurrentIndex(i)
76 self.enable_auto_close_check_box.setChecked(settings.value('enable exit confirmation'))
77+ self.experimental_check_box.setChecked(settings.value('experimental'))
78 if HAS_DARK_STYLE:
79 self.use_dark_style_checkbox.setChecked(settings.value('use_dark_style'))
80 self.hide_mouse_check_box.setChecked(settings.value('hide mouse'))
81@@ -423,6 +429,7 @@
82 slide_max_height_value = self.slide_max_height_combo_box.itemData(slide_max_height_index)
83 settings.setValue('slide max height', slide_max_height_value)
84 settings.setValue('autoscrolling', self.autoscroll_map[self.autoscroll_combo_box.currentIndex()])
85+ settings.setValue('experimental', self.experimental_check_box.isChecked())
86 settings.setValue('enable exit confirmation', self.enable_auto_close_check_box.isChecked())
87 settings.setValue('hide mouse', self.hide_mouse_check_box.isChecked())
88 settings.setValue('alternate rows', self.alternate_rows_check_box.isChecked())
89
90=== modified file 'openlp/core/ui/generaltab.py'
91--- openlp/core/ui/generaltab.py 2019-04-13 13:00:22 +0000
92+++ openlp/core/ui/generaltab.py 2019-05-05 06:00:56 +0000
93@@ -83,18 +83,6 @@
94 self.password_edit.setObjectName('password_edit')
95 self.ccli_layout.addRow(self.password_label, self.password_edit)
96 self.left_layout.addWidget(self.ccli_group_box)
97- # Background audio
98- self.audio_group_box = QtWidgets.QGroupBox(self.left_column)
99- self.audio_group_box.setObjectName('audio_group_box')
100- self.audio_layout = QtWidgets.QVBoxLayout(self.audio_group_box)
101- self.audio_layout.setObjectName('audio_layout')
102- self.start_paused_check_box = QtWidgets.QCheckBox(self.audio_group_box)
103- self.start_paused_check_box.setObjectName('start_paused_check_box')
104- self.audio_layout.addWidget(self.start_paused_check_box)
105- self.repeat_list_check_box = QtWidgets.QCheckBox(self.audio_group_box)
106- self.repeat_list_check_box.setObjectName('repeat_list_check_box')
107- self.audio_layout.addWidget(self.repeat_list_check_box)
108- self.left_layout.addWidget(self.audio_group_box)
109 self.left_layout.addStretch()
110 # Application Startup
111 self.startup_group_box = QtWidgets.QGroupBox(self.right_column)
112@@ -195,9 +183,7 @@
113 self.number_label.setText(UiStrings().CCLINumberLabel)
114 self.username_label.setText(translate('OpenLP.GeneralTab', 'SongSelect username:'))
115 self.password_label.setText(translate('OpenLP.GeneralTab', 'SongSelect password:'))
116- self.audio_group_box.setTitle(translate('OpenLP.GeneralTab', 'Background Audio'))
117- self.start_paused_check_box.setText(translate('OpenLP.GeneralTab', 'Start background audio paused'))
118- self.repeat_list_check_box.setText(translate('OpenLP.GeneralTab', 'Repeat track list'))
119+ self.logo_file_path_edit.dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File')
120 self.logo_file_path_edit.dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File')
121 self.logo_file_path_edit.filters = '{text};;{names} (*)'.format(
122 text=get_images_filter(), names=UiStrings().AllFiles)
123@@ -224,8 +210,6 @@
124 self.check_for_updates_check_box.setChecked(settings.value('update check'))
125 self.auto_preview_check_box.setChecked(settings.value('auto preview'))
126 self.timeout_spin_box.setValue(settings.value('loop delay'))
127- self.start_paused_check_box.setChecked(settings.value('audio start paused'))
128- self.repeat_list_check_box.setChecked(settings.value('audio repeat list'))
129 settings.endGroup()
130
131 def save(self):
132@@ -249,8 +233,6 @@
133 settings.setValue('ccli number', self.number_edit.displayText())
134 settings.setValue('songselect username', self.username_edit.displayText())
135 settings.setValue('songselect password', self.password_edit.displayText())
136- settings.setValue('audio start paused', self.start_paused_check_box.isChecked())
137- settings.setValue('audio repeat list', self.repeat_list_check_box.isChecked())
138 settings.endGroup()
139 self.post_set_up()
140
141
142=== modified file 'openlp/core/ui/media/mediacontroller.py'
143--- openlp/core/ui/media/mediacontroller.py 2019-04-13 13:00:22 +0000
144+++ openlp/core/ui/media/mediacontroller.py 2019-05-05 06:00:56 +0000
145@@ -20,8 +20,7 @@
146 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
147 ##########################################################################
148 """
149-The :mod:`~openlp.core.ui.media.mediacontroller` module contains a base class for media components and other widgets
150-related to playing media, such as sliders.
151+The :mod:`~openlp.core.ui.media.mediacontroller` module is the control module for all media playing.
152 """
153 import logging
154
155@@ -124,14 +123,14 @@
156 """
157 self.setup()
158 self.vlc_player = VlcPlayer(self)
159- State().add_service("mediacontroller", 0)
160- State().add_service("media_live", 0, requires="mediacontroller")
161+ State().add_service('mediacontroller', 0)
162+ State().add_service('media_live', 0)
163 if get_vlc() and pymediainfo_available:
164- State().update_pre_conditions("mediacontroller", True)
165+ State().update_pre_conditions('mediacontroller', True)
166 State().update_pre_conditions('media_live', True)
167 else:
168- State().missing_text("mediacontroller", translate('OpenLP.SlideController',
169- "VLC or pymediainfo are missing, so you are unable to play any media"))
170+ State().missing_text('media_live', translate('OpenLP.SlideController',
171+ 'VLC or pymediainfo are missing, so you are unable to play any media'))
172 self._generate_extensions_lists()
173 return True
174
175@@ -140,11 +139,14 @@
176 Set up the controllers.
177 :return:
178 """
179- try:
180- self.setup_display(self.live_controller.display, False)
181- except AttributeError:
182- State().update_pre_conditions('media_live', False)
183- self.setup_display(self.preview_controller.preview_display, True)
184+ if State().check_preconditions('mediacontroller'):
185+ try:
186+ self.setup_display(self.live_controller.display, False)
187+ except AttributeError:
188+ State().update_pre_conditions('media_live', False)
189+ State().missing_text('media_live', translate('OpenLP.SlideController',
190+ 'No Displays configure so Live Media has been disabled'))
191+ self.setup_display(self.preview_controller.preview_display, True)
192
193 def display_controllers(self, controller_type):
194 """
195@@ -215,9 +217,6 @@
196 """
197 # Generic controls
198 controller.mediabar.setVisible(value)
199- # if controller.is_live and controller.display:
200- # if self.current_media_players and value:
201- # controller.display.set_transparency(False)
202
203 @staticmethod
204 def resize(display, player):
205@@ -563,8 +562,7 @@
206 total_seconds = controller.media_info.length // 1000
207 total_minutes = total_seconds // 60
208 total_seconds %= 60
209- controller.position_label.setText(' %02d:%02d / %02d:%02d' %
210- (0, 0, total_minutes, total_seconds))
211+ controller.position_label.setText(' %02d:%02d / %02d:%02d' % (0, 0, total_minutes, total_seconds))
212 controller.mediabar.actions['playbackPlay'].setVisible(True)
213 controller.mediabar.actions['playbackStop'].setDisabled(True)
214 controller.mediabar.actions['playbackPause'].setVisible(False)
215
216=== modified file 'openlp/core/ui/media/mediaplayer.py'
217--- openlp/core/ui/media/mediaplayer.py 2019-04-13 13:00:22 +0000
218+++ openlp/core/ui/media/mediaplayer.py 2019-05-05 06:00:56 +0000
219@@ -139,11 +139,12 @@
220 """
221 pass
222
223- def update_ui(self, display):
224+ def update_ui(self, controller, output_display):
225 """
226 Do some ui related stuff (e.g. update the seek slider)
227
228- :param display: The display to be updated.
229+ :param controller: Which Controller is running the show.
230+ :param output_display: The display where the media is
231 """
232 pass
233
234
235=== modified file 'openlp/core/ui/media/mediatab.py'
236--- openlp/core/ui/media/mediatab.py 2019-04-13 13:00:22 +0000
237+++ openlp/core/ui/media/mediatab.py 2019-05-05 06:00:56 +0000
238@@ -20,11 +20,12 @@
239 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
240 ##########################################################################
241 """
242-The :mod:`~openlp.core.ui.media.playertab` module holds the configuration tab for the media stuff.
243+The :mod:`~openlp.core.ui.media.mediatab` module holds the configuration tab for the media stuff.
244 """
245+import logging
246
247 from PyQt5 import QtWidgets
248-# from PyQt5.QtMultimedia import QCameraInfo, QAudioDeviceInfo, QAudio
249+from PyQt5.QtMultimedia import QCameraInfo, QAudioDeviceInfo, QAudio
250
251 from openlp.core.common import is_linux, is_win
252 from openlp.core.common.i18n import translate
253@@ -32,8 +33,11 @@
254 from openlp.core.lib.settingstab import SettingsTab
255 from openlp.core.ui.icons import UiIcons
256
257-LINUX_STREAM = 'v4l2:///dev/video0'
258-WIN_STREAM = 'dshow:// :dshow-vdev='
259+LINUX_STREAM = 'v4l2://{video} :v4l2-standard= :input-slave={audio} :live-caching=300'
260+WIN_STREAM = 'dshow://:dshow-vdev={video} :dshow-adev={audio} :live-caching=300'
261+OSX_STREAM = 'avcapture://{video} :qtsound://{audio} :live-caching=300'
262+
263+log = logging.getLogger(__name__)
264
265
266 class MediaTab(SettingsTab):
267@@ -44,8 +48,6 @@
268 """
269 Constructor
270 """
271- # self.media_players = Registry().get('media_controller').media_players
272- # self.saved_used_players = None
273 self.icon_path = UiIcons().video
274 player_translated = translate('OpenLP.MediaTab', 'Media')
275 super(MediaTab, self).__init__(parent, 'Media', player_translated)
276@@ -67,39 +69,52 @@
277 self.stream_media_group_box = QtWidgets.QGroupBox(self.left_column)
278 self.stream_media_group_box.setObjectName('stream_media_group_box')
279 self.stream_media_layout = QtWidgets.QHBoxLayout(self.stream_media_group_box)
280- self.stream_media_layout.setObjectName('live_media_layout')
281+ self.stream_media_layout.setObjectName('stream_media_layout')
282 self.stream_media_layout.setContentsMargins(0, 0, 0, 0)
283- self.stream_edit = QtWidgets.QPlainTextEdit(self)
284+ self.stream_edit = QtWidgets.QLabel(self)
285 self.stream_media_layout.addWidget(self.stream_edit)
286- self.browse_button = QtWidgets.QToolButton(self)
287- self.browse_button.setIcon(UiIcons().undo)
288- self.stream_media_layout.addWidget(self.browse_button)
289- self.left_layout.addWidget(self.stream_media_group_box)
290- self.left_layout.addWidget(self.stream_media_group_box)
291+ self.left_layout.addWidget(self.stream_media_group_box)
292+ self.vlc_arguments_group_box = QtWidgets.QGroupBox(self.left_column)
293+ self.vlc_arguments_group_box.setObjectName('vlc_arguments_group_box')
294+ self.vlc_arguments_layout = QtWidgets.QHBoxLayout(self.vlc_arguments_group_box)
295+ self.vlc_arguments_layout.setObjectName('vlc_arguments_layout')
296+ self.vlc_arguments_layout.setContentsMargins(0, 0, 0, 0)
297+ self.vlc_arguments_edit = QtWidgets.QPlainTextEdit(self)
298+ self.vlc_arguments_layout.addWidget(self.vlc_arguments_edit)
299+ self.left_layout.addWidget(self.vlc_arguments_group_box)
300 self.left_layout.addStretch()
301 self.right_layout.addStretch()
302 # # Signals and slots
303- self.browse_button.clicked.connect(self.on_revert)
304
305- def retranslateUi(self):
306+ def retranslate_ui(self):
307 """
308 Translate the UI on the fly
309 """
310 self.live_media_group_box.setTitle(translate('MediaPlugin.MediaTab', 'Live Media'))
311 self.stream_media_group_box.setTitle(translate('MediaPlugin.MediaTab', 'Stream Media Command'))
312- self.auto_start_check_box.setText(translate('MediaPlugin.MediaTab', 'Start automatically'))
313+ self.vlc_arguments_group_box.setTitle(translate('MediaPlugin.MediaTab', 'VLC arguments'))
314+ self.auto_start_check_box.setText(translate('MediaPlugin.MediaTab', 'Start Live items automatically'))
315
316 def load(self):
317 """
318 Load the settings
319 """
320 self.auto_start_check_box.setChecked(Settings().value(self.settings_section + '/media auto start'))
321- self.stream_edit.setPlainText(Settings().value(self.settings_section + '/stream command'))
322- if not self.stream_edit.toPlainText():
323+ self.stream_edit.setText(Settings().value(self.settings_section + '/stream command'))
324+ if not self.stream_edit.text():
325 if is_linux:
326- self.stream_edit.setPlainText(LINUX_STREAM)
327+ self.stream_edit.setText(LINUX_STREAM)
328 elif is_win:
329- self.stream_edit.setPlainText(WIN_STREAM)
330+ self.stream_edit.setText(WIN_STREAM)
331+ else:
332+ self.stream_edit.setText(OSX_STREAM)
333+ self.vlc_arguments_edit.setPlainText(Settings().value(self.settings_section + '/vlc arguments'))
334+ if Settings().value('advanced/experimental'):
335+ for cam in QCameraInfo.availableCameras():
336+ log.debug(cam.deviceName())
337+ log.debug(cam.description())
338+ for au in QAudioDeviceInfo.availableDevices(QAudio.AudioInput):
339+ log.debug(au.deviceName())
340
341 def save(self):
342 """
343@@ -108,17 +123,8 @@
344 setting_key = self.settings_section + '/media auto start'
345 if Settings().value(setting_key) != self.auto_start_check_box.checkState():
346 Settings().setValue(setting_key, self.auto_start_check_box.checkState())
347- # settings = Settings()
348- # settings.beginGroup(self.settings_section)
349- # settings.setValue('background color', self.background_color)
350- # settings.endGroup()
351- # old_players, override_player = get_media_players()
352- # if self.used_players != old_players:
353- # # clean old Media stuff
354- # set_media_players(self.used_players, override_player)
355- # self.settings_form.register_post_process('mediaitem_suffix_reset')
356- # self.settings_form.register_post_process('mediaitem_media_rebuild')
357- # self.settings_form.register_post_process('config_screen_changed')
358+ Settings().setValue(self.settings_section + '/stream command', self.stream_edit.text())
359+ Settings().setValue(self.settings_section + '/vlc arguments', self.vlc_arguments_edit.toPlainText())
360
361 def post_set_up(self, post_update=False):
362 """
363@@ -127,22 +133,6 @@
364 :param post_update: Indicates if called before or after updates.
365 """
366 pass
367- # for key, player in self.media_players.items():
368- # player = self.media_players[key]
369- # checkbox = MediaQCheckBox(self.media_player_group_box)
370- # checkbox.setEnabled(player.available)
371- # checkbox.setObjectName(player.name + '_check_box')
372- # checkbox.setToolTip(player.get_info())
373- # checkbox.set_player_name(player.name)
374- # self.player_check_boxes[player.name] = checkbox
375- # checkbox.stateChanged.connect(self.on_player_check_box_changed)
376- # self.media_player_layout.addWidget(checkbox)
377- # if player.available and player.name in self.used_players:
378- # checkbox.setChecked(True)
379- # else:
380- # checkbox.setChecked(False)
381- # self.update_player_list()
382- # self.retranslate_players()
383
384 def on_revert(self):
385 pass
386
387=== modified file 'openlp/core/ui/media/vlcplayer.py'
388--- openlp/core/ui/media/vlcplayer.py 2019-04-13 13:00:22 +0000
389+++ openlp/core/ui/media/vlcplayer.py 2019-05-05 06:00:56 +0000
390@@ -164,9 +164,11 @@
391 output_display.vlc_widget = QtWidgets.QFrame(output_display)
392 output_display.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame)
393 # creating a basic vlc instance
394- command_line_options = '--no-video-title-show'
395+ command_line_options = '--no-video-title-show '
396 if Settings().value('advanced/hide mouse') and live_display:
397- command_line_options += ' --mouse-hide-timeout=0'
398+ command_line_options += '--mouse-hide-timeout=0 '
399+ if Settings().value('media/vlc arguments'):
400+ command_line_options += Settings().value('media/vlc arguments')
401 output_display.vlc_instance = vlc.Instance(command_line_options)
402 # creating an empty vlc media player
403 output_display.vlc_media_player = output_display.vlc_instance.media_player_new()
404@@ -224,7 +226,8 @@
405 return False
406 output_display.vlc_media = audio_cd_tracks.item_at_index(controller.media_info.title_track)
407 elif controller.media_info.media_type == MediaType.Stream:
408- output_display.vlc_media = output_display.vlc_instance.media_new_location('ZZZZZZ')
409+ stream_cmd = Settings().value('media/stream command')
410+ output_display.vlc_media = output_display.vlc_instance.media_new_location(stream_cmd)
411 else:
412 output_display.vlc_media = output_display.vlc_instance.media_new_path(path)
413 # put the media in the media player
414@@ -240,7 +243,7 @@
415 Wait no longer than 60 seconds. (loading an iso file needs a long time)
416
417 :param media_state: The state of the playing media
418- :param display: The display where the media is
419+ :param output_display: The display where the media is
420 :return:
421 """
422 vlc = get_vlc()
423@@ -314,7 +317,7 @@
424 self.volume(output_display, output_display.media_info.volume)
425 if start_time > 0 and output_display.vlc_media_player.is_seekable():
426 output_display.vlc_media_player.set_time(int(start_time))
427- controller.seek_slider.setMaximum(output_display.media_info.length)
428+ controller.seek_slider.setMaximum(controller.media_info.length)
429 self.set_state(MediaState.Playing, output_display)
430 output_display.vlc_widget.raise_()
431 return True
432@@ -361,9 +364,9 @@
433 :param seek_value: The position of where a seek goes to
434 :param output_display: The display where the media is
435 """
436- if output_display.controller.media_info.media_type == MediaType.CD \
437- or output_display.controller.media_info.media_type == MediaType.DVD:
438- seek_value += int(output_display.controller.media_info.start_time)
439+ if output_display.media_info.media_type == MediaType.CD \
440+ or output_display.media_info.media_type == MediaType.DVD:
441+ seek_value += int(output_display.media_info.start_time)
442 if output_display.vlc_media_player.is_seekable():
443 output_display.vlc_media_player.set_time(seek_value)
444
445
446=== modified file 'openlp/core/ui/settingsform.py'
447--- openlp/core/ui/settingsform.py 2019-04-13 13:00:22 +0000
448+++ openlp/core/ui/settingsform.py 2019-05-05 06:00:56 +0000
449@@ -30,7 +30,6 @@
450 from openlp.core.api.tab import ApiTab
451 from openlp.core.common.mixins import RegistryProperties
452 from openlp.core.common.registry import Registry
453-from openlp.core.common.settings import Settings
454 from openlp.core.lib import build_icon
455 from openlp.core.projectors.tab import ProjectorTab
456 from openlp.core.ui.advancedtab import AdvancedTab
457@@ -61,6 +60,7 @@
458 self.setting_list_widget.currentRowChanged.connect(self.list_item_changed)
459 self.general_tab = None
460 self.themes_tab = None
461+ self.player_tab = None
462 self.projector_tab = None
463 self.advanced_tab = None
464 self.api_tab = None
465@@ -79,8 +79,7 @@
466 self.insert_tab(self.advanced_tab)
467 self.insert_tab(self.screens_tab)
468 self.insert_tab(self.themes_tab)
469- if Settings().value('core/experimental'):
470- self.insert_tab(self.player_tab)
471+ self.insert_tab(self.player_tab)
472 self.insert_tab(self.projector_tab)
473 self.insert_tab(self.api_tab)
474 for plugin in State().list_plugins():
475@@ -161,8 +160,7 @@
476 self.themes_tab = ThemesTab(self)
477 self.projector_tab = ProjectorTab(self)
478 self.advanced_tab = AdvancedTab(self)
479- if Settings().value('core/experimental'):
480- self.player_tab = MediaTab(self)
481+ self.player_tab = MediaTab(self)
482 self.api_tab = ApiTab(self)
483 self.screens_tab = ScreensTab(self)
484 except Exception as e:
485@@ -170,8 +168,7 @@
486 self.general_tab.post_set_up()
487 self.themes_tab.post_set_up()
488 self.advanced_tab.post_set_up()
489- if Settings().value('core/experimental'):
490- self.player_tab.post_set_up()
491+ self.player_tab.post_set_up()
492 self.api_tab.post_set_up()
493 for plugin in State().list_plugins():
494 if plugin.settings_tab:
495
496=== modified file 'openlp/core/ui/slidecontroller.py'
497--- openlp/core/ui/slidecontroller.py 2019-04-13 13:00:22 +0000
498+++ openlp/core/ui/slidecontroller.py 2019-05-05 06:00:56 +0000
499@@ -112,7 +112,7 @@
500
501 class InfoLabel(QtWidgets.QLabel):
502 """
503- InfoLabel is a subclassed QLabel. Created to provide the ablilty to add a ellipsis if the text is cut off. Original
504+ InfoLabel is a subclassed QLabel. Created to provide the ability to add a ellipsis if the text is cut off. Original
505 source: https://stackoverflow.com/questions/11446478/pyside-pyqt-truncate-text-in-qlabel-based-on-minimumsize
506 """
507
508@@ -177,7 +177,6 @@
509 if screen.is_display:
510 display = DisplayWindow(self, screen)
511 self.displays.append(display)
512- # display.media_watcher.progress.connect(self.on_audio_time_remaining)
513
514 @property
515 def display(self):
516@@ -381,7 +380,7 @@
517 self.position_label.setMinimumSize(90, 0)
518 self.position_label.setObjectName('position_label')
519 self.mediabar.add_toolbar_widget(self.position_label)
520- # Build the seek_slider.
521+ # Build the media seek_slider.
522 self.seek_slider = MediaSlider(QtCore.Qt.Horizontal, self, self)
523 self.seek_slider.setMaximum(1000)
524 self.seek_slider.setTracking(True)
525@@ -398,7 +397,6 @@
526 self.volume_slider.setMaximum(100)
527 self.volume_slider.setTracking(True)
528 self.volume_slider.setToolTip(translate('OpenLP.SlideController', 'Audio Volume.'))
529- # self.volume_slider.setValue(self.media_info.volume)
530 self.volume_slider.setGeometry(QtCore.QRect(90, 160, 221, 24))
531 self.volume_slider.setObjectName('volume_slider')
532 self.mediabar.add_toolbar_widget(self.volume_slider)
533
534=== modified file 'openlp/core/ui/thememanager.py'
535--- openlp/core/ui/thememanager.py 2019-04-13 13:00:22 +0000
536+++ openlp/core/ui/thememanager.py 2019-05-05 06:00:56 +0000
537@@ -26,19 +26,18 @@
538 import zipfile
539 from xml.etree.ElementTree import XML, ElementTree
540
541-from PyQt5 import QtCore, QtGui, QtWidgets
542+from PyQt5 import QtCore, QtWidgets
543
544 from openlp.core.common import delete_file
545 from openlp.core.common.applocation import AppLocation
546 from openlp.core.common.i18n import UiStrings, get_locale_key, translate
547 from openlp.core.common.mixins import LogMixin, RegistryProperties
548-from openlp.core.common.path import Path, copyfile, create_paths, path_to_str
549+from openlp.core.common.path import Path, copyfile, create_paths
550 from openlp.core.common.registry import Registry, RegistryBase
551 from openlp.core.common.settings import Settings
552-from openlp.core.lib import ImageSource, build_icon, check_item_selected, create_thumb, get_text_file_string, \
553- validate_thumb
554+from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb
555 from openlp.core.lib.exceptions import ValidationError
556-from openlp.core.lib.theme import BackgroundType, Theme
557+from openlp.core.lib.theme import Theme
558 from openlp.core.lib.ui import create_widget_action, critical_error_message_box
559 from openlp.core.ui.filerenameform import FileRenameForm
560 from openlp.core.ui.icons import UiIcons
561@@ -648,11 +647,6 @@
562 :rtype: None
563 """
564 self._write_theme(theme, image_source_path, image_destination_path)
565- if theme.background_type == BackgroundType.to_string(BackgroundType.Image):
566- self.image_manager.update_image_border(path_to_str(theme.background_filename),
567- ImageSource.Theme,
568- QtGui.QColor(theme.background_border_color))
569- self.image_manager.process_updates()
570
571 def _write_theme(self, theme, image_source_path=None, image_destination_path=None):
572 """
573
574=== modified file 'openlp/plugins/media/lib/mediaitem.py'
575--- openlp/plugins/media/lib/mediaitem.py 2019-04-13 13:00:22 +0000
576+++ openlp/plugins/media/lib/mediaitem.py 2019-05-05 06:00:56 +0000
577@@ -93,16 +93,6 @@
578 to another language.
579 """
580 self.on_new_prompt = translate('MediaPlugin.MediaItem', 'Select Media')
581- # self.replace_action.setText(UiStrings().ReplaceBG)
582- # self.replace_action_context.setText(UiStrings().ReplaceBG)
583- # self.replace_action.setToolTip(UiStrings().ReplaceLiveBGDisabled)
584- # self.replace_action_context.setToolTip(UiStrings().ReplaceLiveBGDisabled)
585- # self.reset_action.setText(UiStrings().ResetBG)
586- # self.reset_action.setToolTip(UiStrings().ResetLiveBG)
587- # self.reset_action_context.setText(UiStrings().ResetBG)
588- # self.reset_action_context.setToolTip(UiStrings().ResetLiveBG)
589- # self.automatic = UiStrings().Automatic
590- # self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:'))
591
592 def required_icons(self):
593 """
594@@ -117,7 +107,7 @@
595 self.can_make_live = False
596 self.can_add_to_service = False
597 if State().check_preconditions('media_live'):
598- self.can_make_live = False
599+ self.can_make_live = True
600
601 def add_list_view_to_toolbar(self):
602 """
603
604=== modified file 'tests/functional/openlp_core/ui/media/test_vlcplayer.py'
605--- tests/functional/openlp_core/ui/media/test_vlcplayer.py 2019-04-13 13:00:22 +0000
606+++ tests/functional/openlp_core/ui/media/test_vlcplayer.py 2019-05-05 06:00:56 +0000
607@@ -126,7 +126,7 @@
608 mocked_is_macosx.return_value = False
609 mocked_is_win.return_value = False
610 mocked_settings = MagicMock()
611- mocked_settings.value.return_value = True
612+ mocked_settings.value.return_value = ''
613 MockedSettings.return_value = mocked_settings
614 mocked_qframe = MagicMock()
615 mocked_qframe.winId.return_value = 2
616@@ -150,8 +150,9 @@
617 # THEN: The VLC widget should be set up correctly
618 assert mocked_output_display.vlc_widget == mocked_qframe
619 mocked_qframe.setFrameStyle.assert_called_with(1)
620- mocked_settings.value.assert_called_with('advanced/hide mouse')
621- mocked_vlc.Instance.assert_called_with('--no-video-title-show --mouse-hide-timeout=0')
622+ mocked_settings.value.assert_any_call('advanced/hide mouse')
623+ mocked_settings.value.assert_any_call('media/vlc arguments')
624+ mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
625 assert mocked_output_display.vlc_instance == mocked_instance
626 mocked_instance.media_player_new.assert_called_with()
627 assert mocked_output_display.vlc_media_player == mocked_media_player_new
628@@ -175,7 +176,7 @@
629 mocked_is_macosx.return_value = False
630 mocked_is_win.return_value = False
631 mocked_settings = MagicMock()
632- mocked_settings.value.return_value = True
633+ mocked_settings.value.return_value = ''
634 MockedSettings.return_value = mocked_settings
635 mocked_qframe = MagicMock()
636 mocked_qframe.winId.return_value = 2
637@@ -197,7 +198,7 @@
638 vlc_player.setup(mocked_output_display, mocked_controller)
639
640 # THEN: The VLC instance should be created with the correct options
641- mocked_vlc.Instance.assert_called_with('--no-video-title-show --mouse-hide-timeout=0')
642+ mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
643
644 @patch('openlp.core.ui.media.vlcplayer.is_win')
645 @patch('openlp.core.ui.media.vlcplayer.is_macosx')
646@@ -213,7 +214,7 @@
647 mocked_is_macosx.return_value = False
648 mocked_is_win.return_value = False
649 mocked_settings = MagicMock()
650- mocked_settings.value.return_value = False
651+ mocked_settings.value.return_value = ''
652 MockedSettings.return_value = mocked_settings
653 mocked_qframe = MagicMock()
654 mocked_qframe.winId.return_value = 2
655@@ -235,7 +236,7 @@
656 vlc_player.setup(mocked_output_display, mocked_controller)
657
658 # THEN: The VLC instance should be created with the correct options
659- mocked_vlc.Instance.assert_called_with('--no-video-title-show')
660+ mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
661
662 @patch('openlp.core.ui.media.vlcplayer.is_win')
663 @patch('openlp.core.ui.media.vlcplayer.is_macosx')
664@@ -863,7 +864,7 @@
665
666 # THEN: nothing should happen
667 mocked_display.vlc_media_player.is_seekable.assert_called_with()
668- mocked_display.vlc_media_player.set_time.assert_called_with(5000)
669+ mocked_display.vlc_media_player.set_time.assert_called_with(2000)
670
671 def test_reset(self):
672 """