forked from openlp/openlp
Merge branch 'master' of gitlab.com:openlp/openlp
This commit is contained in:
commit
820bf131c5
@ -212,6 +212,8 @@ class Settings(QtCore.QSettings):
|
||||
'media/vlc arguments': '',
|
||||
'media/video': '',
|
||||
'media/audio': '',
|
||||
'media/live volume': 50,
|
||||
'media/preview volume': 0,
|
||||
'remotes/download version': '0.0',
|
||||
'players/background color': '#000000',
|
||||
'servicemanager/last directory': None,
|
||||
|
@ -214,7 +214,6 @@ class ServiceItem(RegistryProperties):
|
||||
"""
|
||||
Render the frames for printing and return them
|
||||
|
||||
:param can_render_chords: bool Whether or not to render the chords
|
||||
"""
|
||||
if not self._print_slides:
|
||||
self._print_slides = []
|
||||
@ -345,7 +344,11 @@ class ServiceItem(RegistryProperties):
|
||||
service_data = [slide['title'] for slide in self.slides]
|
||||
elif self.service_item_type == ServiceItemType.Command:
|
||||
for slide in self.slides:
|
||||
service_data.append({'title': slide['title'], 'image': slide['image'], 'path': slide['path'],
|
||||
if isinstance(slide['image'], QtGui.QIcon):
|
||||
image = "clapperboard"
|
||||
else:
|
||||
image = slide['image']
|
||||
service_data.append({'title': slide['title'], 'image': image, 'path': slide['path'],
|
||||
'display_title': slide['display_title'], 'notes': slide['notes']})
|
||||
return {'header': service_header, 'data': service_data}
|
||||
|
||||
@ -425,6 +428,8 @@ class ServiceItem(RegistryProperties):
|
||||
self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
|
||||
elif path:
|
||||
self.has_original_files = False
|
||||
if text_image['image'] == "clapperboard":
|
||||
text_image['image'] = UiIcons().clapperboard
|
||||
self.add_from_command(path, text_image['title'], text_image['image'],
|
||||
text_image.get('display_title', ''), text_image.get('notes', ''))
|
||||
else:
|
||||
@ -631,7 +636,7 @@ class ServiceItem(RegistryProperties):
|
||||
"""
|
||||
Validates a service item to make sure it is valid
|
||||
|
||||
:param set[str] suffixes: A set of vaild suffixes
|
||||
:param set[str] suffixes: A set of valid suffixes
|
||||
"""
|
||||
self.is_valid = True
|
||||
for slide in self.slides:
|
||||
@ -649,7 +654,7 @@ class ServiceItem(RegistryProperties):
|
||||
self.is_valid = False
|
||||
break
|
||||
if suffixes and not self.is_text():
|
||||
file_suffix = slide['title'].split('.')[-1]
|
||||
file_suffix = "*.{suffx}".format(suffx=slide['title'].split('.')[-1])
|
||||
if file_suffix.lower() not in suffixes:
|
||||
self.is_valid = False
|
||||
break
|
||||
|
@ -70,7 +70,7 @@ class ItemMediaInfo(object):
|
||||
file_info = None
|
||||
volume = 100
|
||||
is_background = False
|
||||
can_loop_playback = False
|
||||
is_looping_playback = False
|
||||
length = 0
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
@ -91,7 +91,7 @@ def parse_optical_path(input_string):
|
||||
"""
|
||||
log.debug('parse_optical_path, about to parse: "{text}"'.format(text=input_string))
|
||||
clip_info = input_string.split(sep=':')
|
||||
title = int(clip_info[1])
|
||||
title = str(clip_info[1])
|
||||
audio_track = int(clip_info[2])
|
||||
subtitle_track = int(clip_info[3])
|
||||
start = float(clip_info[4])
|
||||
|
@ -64,6 +64,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
self.live_timer.setInterval(TICK_TIME)
|
||||
self.preview_timer = QtCore.QTimer()
|
||||
self.preview_timer.setInterval(TICK_TIME)
|
||||
self.settings = Settings()
|
||||
# Signals
|
||||
self.live_timer.timeout.connect(self.media_state_live)
|
||||
self.preview_timer.timeout.connect(self.media_state_preview)
|
||||
@ -116,13 +117,13 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
"""
|
||||
if State().check_preconditions('mediacontroller'):
|
||||
try:
|
||||
self.setup_display(self.live_controller.display, False)
|
||||
self.setup_display(self.live_controller, False)
|
||||
except AttributeError:
|
||||
State().update_pre_conditions('media_live', False)
|
||||
State().missing_text('media_live', translate(
|
||||
'OpenLP.MediaController',
|
||||
'No Displays have been configured, so Live Media has been disabled'))
|
||||
self.setup_display(self.preview_controller.preview_display, True)
|
||||
self.setup_display(self.preview_controller, True)
|
||||
|
||||
def display_controllers(self, controller_type):
|
||||
"""
|
||||
@ -140,7 +141,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
"""
|
||||
display = self._define_display(self.display_controllers(DisplayControllerType.Live))
|
||||
if DisplayControllerType.Live in self.current_media_players:
|
||||
self.current_media_players[DisplayControllerType.Live].resize(display)
|
||||
self.current_media_players[DisplayControllerType.Live].resize(self.live_controller)
|
||||
self.current_media_players[DisplayControllerType.Live].update_ui(self.live_controller, display)
|
||||
self.tick(self.display_controllers(DisplayControllerType.Live))
|
||||
if self.current_media_players[DisplayControllerType.Live].get_live_state() is not MediaState.Playing:
|
||||
@ -148,8 +149,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
else:
|
||||
self.live_timer.stop()
|
||||
self.media_stop(self.display_controllers(DisplayControllerType.Live))
|
||||
if self.display_controllers(DisplayControllerType.Live).media_info.can_loop_playback:
|
||||
self.media_play(self.display_controllers(DisplayControllerType.Live), True)
|
||||
|
||||
def media_state_preview(self):
|
||||
"""
|
||||
@ -157,7 +156,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
"""
|
||||
display = self._define_display(self.display_controllers(DisplayControllerType.Preview))
|
||||
if DisplayControllerType.Preview in self.current_media_players:
|
||||
self.current_media_players[DisplayControllerType.Preview].resize(display)
|
||||
self.current_media_players[DisplayControllerType.Preview].resize(self.live_controller)
|
||||
self.current_media_players[DisplayControllerType.Preview].update_ui(self.preview_controller, display)
|
||||
self.tick(self.display_controllers(DisplayControllerType.Preview))
|
||||
if self.current_media_players[DisplayControllerType.Preview].get_preview_state() is not MediaState.Playing:
|
||||
@ -165,23 +164,19 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
else:
|
||||
self.preview_timer.stop()
|
||||
self.media_stop(self.display_controllers(DisplayControllerType.Preview))
|
||||
if self.display_controllers(DisplayControllerType.Preview).media_info.can_loop_playback:
|
||||
self.media_play(self.display_controllers(DisplayControllerType.Preview), True)
|
||||
|
||||
def setup_display(self, display, preview):
|
||||
def setup_display(self, controller, preview):
|
||||
"""
|
||||
After a new display is configured, all media related widgets will be created too
|
||||
|
||||
:param display: Display on which the output is to be played
|
||||
:param controller: Display on which the output is to be played
|
||||
:param preview: Whether the display is a main or preview display
|
||||
"""
|
||||
display.media_info = ItemMediaInfo()
|
||||
display.has_audio = True
|
||||
# if display.is_live and preview:
|
||||
# return
|
||||
controller.media_info = ItemMediaInfo()
|
||||
controller.has_audio = True
|
||||
if preview:
|
||||
display.has_audio = False
|
||||
self.vlc_player.setup(display, preview)
|
||||
controller.has_audio = False
|
||||
self.vlc_player.setup(controller, self._define_display(controller), preview)
|
||||
|
||||
@staticmethod
|
||||
def set_controls_visible(controller, value):
|
||||
@ -195,33 +190,33 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
controller.mediabar.setVisible(value)
|
||||
|
||||
@staticmethod
|
||||
def resize(display, player):
|
||||
def resize(controller, player):
|
||||
"""
|
||||
After Mainwindow changes or Splitter moved all related media widgets have to be resized
|
||||
|
||||
:param display: The display on which output is playing.
|
||||
:param controller: The display on which output is playing.
|
||||
:param player: The player which is doing the playing.
|
||||
"""
|
||||
player.resize(display)
|
||||
player.resize(controller)
|
||||
|
||||
def load_video(self, source, service_item, hidden=False, video_behind_text=False):
|
||||
def load_video(self, source, service_item, hidden=False):
|
||||
"""
|
||||
Loads and starts a video to run with the option of sound
|
||||
Loads and starts a video to run and sets the stored sound value.
|
||||
|
||||
:param source: Where the call originated form
|
||||
:param service_item: The player which is doing the playing
|
||||
:param hidden: The player which is doing the playing
|
||||
:param video_behind_text: Is the video to be played behind text.
|
||||
"""
|
||||
is_valid = True
|
||||
controller = self.display_controllers(source)
|
||||
# stop running videos
|
||||
self.media_reset(controller)
|
||||
controller.media_info = ItemMediaInfo()
|
||||
controller.media_info.volume = controller.volume_slider.value()
|
||||
controller.media_info.is_background = video_behind_text
|
||||
if controller.is_live:
|
||||
controller.media_info.volume = self.settings.value('media/live volume')
|
||||
else:
|
||||
controller.media_info.volume = self.settings.value('media/preview volume')
|
||||
# background will always loop video.
|
||||
controller.media_info.can_loop_playback = video_behind_text
|
||||
if service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
controller.media_info.file_info = service_item.background_audio
|
||||
else:
|
||||
@ -242,13 +237,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
log.debug('video is not optical and live')
|
||||
controller.media_info.length = service_item.media_length
|
||||
is_valid = self._check_file_type(controller, display)
|
||||
# display.override['theme'] = ''
|
||||
# display.override['video'] = True
|
||||
if controller.media_info.is_background:
|
||||
# ignore start/end time
|
||||
controller.media_info.start_time = 0
|
||||
controller.media_info.end_time = 0
|
||||
else:
|
||||
controller.media_info.start_time = service_item.start_time
|
||||
controller.media_info.end_time = service_item.end_time
|
||||
elif controller.preview_display:
|
||||
@ -280,10 +268,10 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
if not controller.is_live:
|
||||
autoplay = True
|
||||
# Visible or background requested or Service Item wants to autostart
|
||||
elif not hidden or controller.media_info.is_background or service_item.will_auto_start:
|
||||
elif not hidden or service_item.will_auto_start:
|
||||
autoplay = True
|
||||
# Unblank on load set
|
||||
elif Settings().value('core/auto unblank'):
|
||||
elif self.settings.value('core/auto unblank'):
|
||||
autoplay = True
|
||||
if autoplay:
|
||||
if not self.media_play(controller):
|
||||
@ -344,7 +332,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
if display is None:
|
||||
display = controller.preview_display
|
||||
self.vlc_player.load(display, filename)
|
||||
self.resize(display, self.vlc_player)
|
||||
self.resize(controller, self.vlc_player)
|
||||
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||
if audio_track == -1 and subtitle_track == -1:
|
||||
controller.media_info.media_type = MediaType.CD
|
||||
@ -361,9 +349,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
:param stream: Are we streaming or not
|
||||
"""
|
||||
if stream:
|
||||
self.resize(display, self.vlc_player)
|
||||
display.media_info.media_type = MediaType.Stream
|
||||
if self.vlc_player.load(display, None):
|
||||
self.resize(controller, self.vlc_player)
|
||||
controller.media_info.media_type = MediaType.Stream
|
||||
if self.vlc_player.load(controller, display, None):
|
||||
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||
return True
|
||||
return True
|
||||
@ -372,23 +360,21 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
suffix = '*%s' % file.suffix.lower()
|
||||
file = str(file)
|
||||
if suffix in VIDEO_EXT:
|
||||
if not controller.media_info.is_background or controller.media_info.is_background and \
|
||||
self.vlc_player.can_background:
|
||||
self.resize(display, self.vlc_player)
|
||||
if self.vlc_player.load(display, file):
|
||||
self.resize(controller, self.vlc_player)
|
||||
if self.vlc_player.load(controller, display, file):
|
||||
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||
controller.media_info.media_type = MediaType.Video
|
||||
return True
|
||||
if suffix in AUDIO_EXT:
|
||||
if self.vlc_player.load(display, file):
|
||||
if self.vlc_player.load(controller, display, file):
|
||||
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||
controller.media_info.media_type = MediaType.Audio
|
||||
return True
|
||||
else:
|
||||
file = str(file)
|
||||
if self.vlc_player.can_folder:
|
||||
self.resize(display, self.vlc_player)
|
||||
if self.vlc_player.load(display, file):
|
||||
self.resize(controller, self.vlc_player)
|
||||
if self.vlc_player.load(controller, display, file):
|
||||
self.current_media_players[controller.controller_type] = self.vlc_player
|
||||
controller.media_info.media_type = MediaType.Video
|
||||
return True
|
||||
@ -423,19 +409,14 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
controller.seek_slider.blockSignals(False)
|
||||
controller.volume_slider.blockSignals(False)
|
||||
return False
|
||||
if controller.media_info.is_background:
|
||||
self.media_volume(controller, 0)
|
||||
else:
|
||||
self.media_volume(controller, controller.media_info.volume)
|
||||
if first_time:
|
||||
# if not controller.media_info.is_background:
|
||||
# display.frame.runJavaScript('show_blank("desktop");')
|
||||
self.current_media_players[controller.controller_type].set_visible(display, True)
|
||||
self.current_media_players[controller.controller_type].set_visible(controller, True)
|
||||
controller.mediabar.actions['playbackPlay'].setVisible(False)
|
||||
controller.mediabar.actions['playbackPause'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setDisabled(False)
|
||||
if controller.is_live:
|
||||
if controller.hide_menu.defaultAction().isChecked() and not controller.media_info.is_background:
|
||||
if controller.hide_menu.defaultAction().isChecked():
|
||||
controller.hide_menu.defaultAction().trigger()
|
||||
# Start Timer for ui updates
|
||||
if not self.live_timer.isActive():
|
||||
@ -448,6 +429,10 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
controller.volume_slider.blockSignals(False)
|
||||
controller.media_info.is_playing = True
|
||||
display = self._define_display(controller)
|
||||
if controller.is_live:
|
||||
display.setVisible(False)
|
||||
controller.preview_display.hide()
|
||||
else:
|
||||
display.setVisible(True)
|
||||
return True
|
||||
|
||||
@ -460,8 +445,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
start_again = False
|
||||
if controller.media_info.is_playing and controller.media_info.length > 0:
|
||||
if controller.media_info.timer > controller.media_info.length:
|
||||
self.media_stop(controller, True)
|
||||
if controller.media_info.can_loop_playback:
|
||||
self.media_stop(controller)
|
||||
if controller.media_info.is_looping_playback:
|
||||
start_again = True
|
||||
controller.media_info.timer += TICK_TIME
|
||||
seconds = controller.media_info.timer // 1000
|
||||
@ -495,9 +480,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
|
||||
:param controller: The Controller to be paused
|
||||
"""
|
||||
display = self._define_display(controller)
|
||||
if controller.controller_type in self.current_media_players:
|
||||
self.current_media_players[controller.controller_type].pause(display)
|
||||
self.current_media_players[controller.controller_type].pause(controller)
|
||||
controller.mediabar.actions['playbackPlay'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setDisabled(False)
|
||||
controller.mediabar.actions['playbackPause'].setVisible(False)
|
||||
@ -518,8 +502,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
|
||||
:param controller: The controller that needs to be stopped
|
||||
"""
|
||||
controller.media_info.can_loop_playback = not controller.media_info.can_loop_playback
|
||||
controller.mediabar.actions['playbackLoop'].setChecked(controller.media_info.can_loop_playback)
|
||||
controller.media_info.is_looping_playback = not controller.media_info.is_looping_playback
|
||||
controller.mediabar.actions['playbackLoop'].setChecked(controller.media_info.is_looping_playback)
|
||||
|
||||
def media_stop_msg(self, msg):
|
||||
"""
|
||||
@ -535,19 +519,16 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
"""
|
||||
self.media_stop(Registry().get('live_controller'))
|
||||
|
||||
def media_stop(self, controller, looping_background=False):
|
||||
def media_stop(self, controller):
|
||||
"""
|
||||
Responds to the request to stop a loaded video
|
||||
|
||||
:param controller: The controller that needs to be stopped
|
||||
:param looping_background: The background is looping so do not blank.
|
||||
"""
|
||||
display = self._define_display(controller)
|
||||
if controller.controller_type in self.current_media_players:
|
||||
# if not looping_background:
|
||||
# display.frame.runJavaScript('show_blank("black");')
|
||||
self.current_media_players[controller.controller_type].stop(display)
|
||||
self.current_media_players[controller.controller_type].set_visible(display, False)
|
||||
self.current_media_players[controller.controller_type].stop(controller)
|
||||
self.current_media_players[controller.controller_type].set_visible(controller, False)
|
||||
controller.preview_display.hide()
|
||||
controller.seek_slider.setSliderPosition(0)
|
||||
total_seconds = controller.media_info.length // 1000
|
||||
total_minutes = total_seconds // 60
|
||||
@ -578,8 +559,12 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
:param volume: The volume to be set
|
||||
"""
|
||||
log.debug('media_volume {vol}'.format(vol=volume))
|
||||
display = self._define_display(controller)
|
||||
self.current_media_players[controller.controller_type].volume(display, volume)
|
||||
if controller.is_live:
|
||||
self.settings.setValue('media/live volume', volume)
|
||||
else:
|
||||
self.settings.setValue('media/preview volume', volume)
|
||||
controller.media_info.volume = volume
|
||||
self.current_media_players[controller.controller_type].volume(controller, volume)
|
||||
controller.volume_slider.setValue(volume)
|
||||
|
||||
def media_seek_msg(self, msg):
|
||||
@ -600,8 +585,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
:param controller: The controller to use.
|
||||
:param seek_value: The value to set.
|
||||
"""
|
||||
display = self._define_display(controller)
|
||||
self.current_media_players[controller.controller_type].seek(display, seek_value)
|
||||
self.current_media_players[controller.controller_type].seek(controller, seek_value)
|
||||
controller.media_info.timer = seek_value
|
||||
|
||||
def media_reset(self, controller):
|
||||
@ -610,12 +594,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
:param controller: The controller to use.
|
||||
"""
|
||||
self.set_controls_visible(controller, False)
|
||||
display = self._define_display(controller)
|
||||
if controller.controller_type in self.current_media_players:
|
||||
display.override = {}
|
||||
self.current_media_players[controller.controller_type].reset(display)
|
||||
self.current_media_players[controller.controller_type].set_visible(display, False)
|
||||
# display.frame.runJavaScript('show_video("setBackBoard", null, null, "hidden");')
|
||||
self.current_media_players[controller.controller_type].reset(controller)
|
||||
self.current_media_players[controller.controller_type].set_visible(controller, False)
|
||||
del self.current_media_players[controller.controller_type]
|
||||
|
||||
def media_hide(self, msg):
|
||||
@ -631,7 +612,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
if self.live_controller.controller_type in self.current_media_players and \
|
||||
self.current_media_players[self.live_controller.controller_type].get_live_state() == MediaState.Playing:
|
||||
self.media_pause(display.controller)
|
||||
self.current_media_players[self.live_controller.controller_type].set_visible(display, False)
|
||||
self.current_media_players[self.live_controller.controller_type].set_visible(self.live_controller, False)
|
||||
|
||||
def media_blank(self, msg):
|
||||
"""
|
||||
@ -649,7 +630,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
if self.live_controller.controller_type in self.current_media_players and \
|
||||
self.current_media_players[self.live_controller.controller_type].get_live_state() == MediaState.Playing:
|
||||
self.media_pause(display.controller)
|
||||
self.current_media_players[self.live_controller.controller_type].set_visible(display, False)
|
||||
self.current_media_players[self.live_controller.controller_type].set_visible(self.live_controller, False)
|
||||
|
||||
def media_unblank(self, msg):
|
||||
"""
|
||||
@ -667,7 +648,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
self.current_media_players[self.live_controller.controller_type].get_live_state() != \
|
||||
MediaState.Playing:
|
||||
if self.media_play(display.controller):
|
||||
self.current_media_players[self.live_controller.controller_type].set_visible(display, True)
|
||||
self.current_media_players[self.live_controller.controller_type].set_visible(self.live_controller, True)
|
||||
# Start Timer for ui updates
|
||||
if not self.live_timer.isActive():
|
||||
self.live_timer.start()
|
||||
|
@ -48,7 +48,7 @@ class MediaPlayer(RegistryProperties):
|
||||
"""
|
||||
return False
|
||||
|
||||
def setup(self, display, live_display):
|
||||
def setup(self, controller, display, live_display):
|
||||
"""
|
||||
Create the related widgets for the current display
|
||||
|
||||
@ -57,10 +57,10 @@ class MediaPlayer(RegistryProperties):
|
||||
"""
|
||||
pass
|
||||
|
||||
def load(self, display, file):
|
||||
def load(self, controller, display, file):
|
||||
"""
|
||||
Load a new media file and check if it is valid
|
||||
|
||||
:param controller: Which Controller is running the show.
|
||||
:param display: The display to be updated.
|
||||
:param file: The file to be loaded
|
||||
"""
|
||||
@ -70,7 +70,6 @@ class MediaPlayer(RegistryProperties):
|
||||
"""
|
||||
If the main display size or position is changed, the media widgets
|
||||
should also resized
|
||||
|
||||
:param display: The display to be updated.
|
||||
"""
|
||||
pass
|
||||
@ -192,14 +191,14 @@ class MediaPlayer(RegistryProperties):
|
||||
"""
|
||||
self.state[1] = state
|
||||
|
||||
def set_state(self, state, display):
|
||||
def set_state(self, state, controller):
|
||||
"""
|
||||
Set the State based on the display being processed
|
||||
Set the State based on the display being processed within the controller
|
||||
:param state: State to be set
|
||||
:param display: Identify the Display type
|
||||
:param controller: Identify the Display type
|
||||
:return: None
|
||||
"""
|
||||
if display.is_display:
|
||||
if controller.is_live:
|
||||
self.set_live_state(state)
|
||||
else:
|
||||
self.set_preview_state(state)
|
||||
|
@ -27,6 +27,7 @@ import os
|
||||
import sys
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from time import sleep
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
@ -95,50 +96,49 @@ class VlcPlayer(MediaPlayer):
|
||||
self.parent = parent
|
||||
self.can_folder = True
|
||||
|
||||
def setup(self, output_display, live_display):
|
||||
def setup(self, controller, display, live_display):
|
||||
"""
|
||||
Set up the media player
|
||||
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The display where the media is
|
||||
:param live_display: Is the display a live one.
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
if output_display.is_display:
|
||||
output_display.vlc_widget = QtWidgets.QFrame()
|
||||
output_display.vlc_widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
|
||||
if controller.is_live:
|
||||
controller.vlc_widget = QtWidgets.QFrame()
|
||||
controller.vlc_widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
|
||||
QtCore.Qt.WindowStaysOnTopHint)
|
||||
else:
|
||||
output_display.vlc_widget = QtWidgets.QFrame(output_display)
|
||||
output_display.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame)
|
||||
|
||||
controller.vlc_widget = QtWidgets.QFrame(display)
|
||||
controller.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame)
|
||||
# creating a basic vlc instance
|
||||
command_line_options = '--no-video-title-show '
|
||||
if Settings().value('advanced/hide mouse') and live_display:
|
||||
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)
|
||||
controller.vlc_instance = vlc.Instance(command_line_options)
|
||||
# creating an empty vlc media player
|
||||
output_display.vlc_media_player = output_display.vlc_instance.media_player_new()
|
||||
output_display.vlc_widget.resize(output_display.size())
|
||||
output_display.vlc_widget.raise_()
|
||||
output_display.vlc_widget.hide()
|
||||
controller.vlc_media_player = controller.vlc_instance.media_player_new()
|
||||
controller.vlc_widget.resize(controller.size())
|
||||
controller.vlc_widget.raise_()
|
||||
controller.vlc_widget.hide()
|
||||
# The media player has to be 'connected' to the QFrame.
|
||||
# (otherwise a video would be displayed in it's own window)
|
||||
# This is platform specific!
|
||||
# You have to give the id of the QFrame (or similar object)
|
||||
# to vlc, different platforms have different functions for this.
|
||||
win_id = int(output_display.vlc_widget.winId())
|
||||
win_id = int(controller.vlc_widget.winId())
|
||||
if is_win():
|
||||
output_display.vlc_media_player.set_hwnd(win_id)
|
||||
controller.vlc_media_player.set_hwnd(win_id)
|
||||
elif is_macosx():
|
||||
# We have to use 'set_nsobject' since Qt5 on OSX uses Cocoa
|
||||
# framework and not the old Carbon.
|
||||
output_display.vlc_media_player.set_nsobject(win_id)
|
||||
controller.vlc_media_player.set_nsobject(win_id)
|
||||
else:
|
||||
# for Linux/*BSD using the X Server
|
||||
output_display.vlc_media_player.set_xwindow(win_id)
|
||||
controller.vlc_media_player.set_xwindow(win_id)
|
||||
self.has_own_widget = True
|
||||
|
||||
def check_available(self):
|
||||
@ -147,74 +147,77 @@ class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
return get_vlc() is not None
|
||||
|
||||
def load(self, output_display, file):
|
||||
def load(self, controller, output_display, file):
|
||||
"""
|
||||
Load a video into VLC
|
||||
|
||||
:param controller: The controller where the media is
|
||||
:param output_display: The display where the media is
|
||||
:param file: file to be played or None for live streaming
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
log.debug('load vid in Vlc Controller')
|
||||
path = None
|
||||
if file:
|
||||
path = os.path.normcase(file)
|
||||
# create the media
|
||||
if output_display.media_info.media_type == MediaType.CD:
|
||||
if controller.media_info.media_type == MediaType.CD:
|
||||
if is_win():
|
||||
path = '/' + path
|
||||
output_display.vlc_media = output_display.vlc_instance.media_new_location('cdda://' + path)
|
||||
output_display.vlc_media_player.set_media(output_display.vlc_media)
|
||||
output_display.vlc_media_player.play()
|
||||
controller.vlc_media = controller.vlc_instance.media_new_location('cdda://' + path)
|
||||
controller.vlc_media_player.set_media(controller.vlc_media)
|
||||
controller.vlc_media_player.play()
|
||||
# Wait for media to start playing. In this case VLC actually returns an error.
|
||||
self.media_state_wait(output_display, vlc.State.Playing)
|
||||
# If subitems exists, this is a CD
|
||||
audio_cd_tracks = output_display.vlc_media.subitems()
|
||||
audio_cd_tracks = controller.vlc_media.subitems()
|
||||
if not audio_cd_tracks or audio_cd_tracks.count() < 1:
|
||||
return False
|
||||
output_display.vlc_media = audio_cd_tracks.item_at_index(output_display.media_info.title_track)
|
||||
elif output_display.media_info.media_type == MediaType.Stream:
|
||||
controller.vlc_media_player = audio_cd_tracks.item_at_index(controller.media_info.title_track)
|
||||
elif controller.media_info.media_type == MediaType.Stream:
|
||||
stream_cmd = Settings().value('media/stream command')
|
||||
output_display.vlc_media = output_display.vlc_instance.media_new_location(stream_cmd)
|
||||
controller.vlc_media = controller.vlc_instance.media_new_location(stream_cmd)
|
||||
else:
|
||||
output_display.vlc_media = output_display.vlc_instance.media_new_path(path)
|
||||
controller.vlc_media = controller.vlc_instance.media_new_path(path)
|
||||
# put the media in the media player
|
||||
output_display.vlc_media_player.set_media(output_display.vlc_media)
|
||||
controller.vlc_media_player.set_media(controller.vlc_media)
|
||||
# parse the metadata of the file
|
||||
output_display.vlc_media.parse()
|
||||
self.volume(output_display, output_display.media_info.volume)
|
||||
controller.vlc_media.parse()
|
||||
self.volume(controller, controller.media_info.volume)
|
||||
return True
|
||||
|
||||
def media_state_wait(self, output_display, media_state):
|
||||
def media_state_wait(self, controller, media_state):
|
||||
"""
|
||||
Wait for the video to change its state
|
||||
Wait no longer than 60 seconds. (loading an iso file needs a long time)
|
||||
|
||||
:param media_state: The state of the playing media
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The controller where the media is
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
start = datetime.now()
|
||||
while media_state != output_display.vlc_media.get_state():
|
||||
if output_display.vlc_media.get_state() == vlc.State.Error:
|
||||
while media_state != controller.vlc_media.get_state():
|
||||
sleep(0.1)
|
||||
if controller.vlc_media.get_state() == vlc.State.Error:
|
||||
return False
|
||||
self.application.process_events()
|
||||
if (datetime.now() - start).seconds > 60:
|
||||
return False
|
||||
return True
|
||||
|
||||
def resize(self, output_display):
|
||||
def resize(self, controller):
|
||||
"""
|
||||
Resize the player
|
||||
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The display where the media is stored within the controller.
|
||||
:return:
|
||||
"""
|
||||
if output_display.is_display:
|
||||
output_display.vlc_widget.setGeometry(ScreenList().current.display_geometry)
|
||||
if controller.is_live:
|
||||
controller.vlc_widget.setGeometry(ScreenList().current.display_geometry)
|
||||
else:
|
||||
output_display.vlc_widget.resize(output_display.size())
|
||||
controller.vlc_widget.resize(controller.preview_display.size())
|
||||
|
||||
def play(self, controller, output_display):
|
||||
"""
|
||||
@ -227,119 +230,117 @@ class VlcPlayer(MediaPlayer):
|
||||
vlc = get_vlc()
|
||||
start_time = 0
|
||||
log.debug('vlc play')
|
||||
if output_display.is_display:
|
||||
if self.get_live_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||
start_time = output_display.media_info.start_time
|
||||
if controller.is_live:
|
||||
if self.get_live_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
start_time = controller.media_info.start_time
|
||||
else:
|
||||
if self.get_preview_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||
start_time = output_display.media_info.start_time
|
||||
threading.Thread(target=output_display.vlc_media_player.play).start()
|
||||
if not self.media_state_wait(output_display, vlc.State.Playing):
|
||||
if self.get_preview_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
start_time = controller.media_info.start_time
|
||||
threading.Thread(target=controller.vlc_media_player.play).start()
|
||||
if not self.media_state_wait(controller, vlc.State.Playing):
|
||||
return False
|
||||
if output_display.is_display:
|
||||
if self.get_live_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||
if controller.is_live:
|
||||
if self.get_live_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
log.debug('vlc play, start time set')
|
||||
start_time = output_display.media_info.start_time
|
||||
start_time = controller.media_info.start_time
|
||||
else:
|
||||
if self.get_preview_state() != MediaState.Paused and output_display.media_info.start_time > 0:
|
||||
if self.get_preview_state() != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
log.debug('vlc play, start time set')
|
||||
start_time = output_display.media_info.start_time
|
||||
log.debug('mediatype: ' + str(output_display.media_info.media_type))
|
||||
start_time = controller.media_info.start_time
|
||||
log.debug('mediatype: ' + str(controller.media_info.media_type))
|
||||
# Set tracks for the optical device
|
||||
if output_display.media_info.media_type == MediaType.DVD and \
|
||||
if controller.media_info.media_type == MediaType.DVD and \
|
||||
self.get_live_state() != MediaState.Paused and self.get_preview_state() != MediaState.Paused:
|
||||
log.debug('vlc play, playing started')
|
||||
if output_display.media_info.title_track > 0:
|
||||
log.debug('vlc play, title_track set: ' + str(output_display.media_info.title_track))
|
||||
output_display.vlc_media_player.set_title(output_display.media_info.title_track)
|
||||
output_display.vlc_media_player.play()
|
||||
if not self.media_state_wait(output_display, vlc.State.Playing):
|
||||
if controller.media_info.title_track > 0:
|
||||
log.debug('vlc play, title_track set: ' + str(controller.media_info.title_track))
|
||||
controller.vlc_media_player.set_title(controller.media_info.title_track)
|
||||
controller.vlc_media_player.play()
|
||||
if not self.media_state_wait(controller, vlc.State.Playing):
|
||||
return False
|
||||
if output_display.media_info.audio_track > 0:
|
||||
output_display.vlc_media_player.audio_set_track(output_display.media_info.audio_track)
|
||||
log.debug('vlc play, audio_track set: ' + str(output_display.media_info.audio_track))
|
||||
if output_display.media_info.subtitle_track > 0:
|
||||
output_display.vlc_media_player.video_set_spu(output_display.media_info.subtitle_track)
|
||||
log.debug('vlc play, subtitle_track set: ' + str(output_display.media_info.subtitle_track))
|
||||
if output_display.media_info.start_time > 0:
|
||||
log.debug('vlc play, starttime set: ' + str(output_display.media_info.start_time))
|
||||
start_time = output_display.media_info.start_time
|
||||
output_display.media_info.length = output_display.media_info.end_time - output_display.media_info.start_time
|
||||
self.volume(output_display, output_display.media_info.volume)
|
||||
if start_time > 0 and output_display.vlc_media_player.is_seekable():
|
||||
output_display.vlc_media_player.set_time(int(start_time))
|
||||
if controller.media_info.audio_track > 0:
|
||||
controller.vlc_media_player.audio_set_track(controller.media_info.audio_track)
|
||||
log.debug('vlc play, audio_track set: ' + str(controller.media_info.audio_track))
|
||||
if controller.media_info.subtitle_track > 0:
|
||||
controller.vlc_media_player.video_set_spu(controller.media_info.subtitle_track)
|
||||
log.debug('vlc play, subtitle_track set: ' + str(controller.media_info.subtitle_track))
|
||||
if controller.media_info.start_time > 0:
|
||||
log.debug('vlc play, starttime set: ' + str(controller.media_info.start_time))
|
||||
start_time = controller.media_info.start_time
|
||||
controller.media_info.length = controller.media_info.end_time - controller.media_info.start_time
|
||||
self.volume(controller, controller.media_info.volume)
|
||||
if start_time > 0 and controller.vlc_media_player.is_seekable():
|
||||
controller.vlc_media_player.set_time(int(start_time))
|
||||
controller.seek_slider.setMaximum(controller.media_info.length)
|
||||
self.set_state(MediaState.Playing, output_display)
|
||||
output_display.vlc_widget.raise_()
|
||||
self.set_state(MediaState.Playing, controller)
|
||||
controller.vlc_widget.raise_()
|
||||
return True
|
||||
|
||||
def pause(self, output_display):
|
||||
def pause(self, controller):
|
||||
"""
|
||||
Pause the current item
|
||||
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The controller which is managing the display
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
if output_display.vlc_media.get_state() != vlc.State.Playing:
|
||||
if controller.vlc_media.get_state() != vlc.State.Playing:
|
||||
return
|
||||
output_display.vlc_media_player.pause()
|
||||
if self.media_state_wait(output_display, vlc.State.Paused):
|
||||
self.set_state(MediaState.Paused, output_display)
|
||||
controller.vlc_media_player.pause()
|
||||
if self.media_state_wait(controller, vlc.State.Paused):
|
||||
self.set_state(MediaState.Paused, controller)
|
||||
|
||||
def stop(self, output_display):
|
||||
def stop(self, controller):
|
||||
"""
|
||||
Stop the current item
|
||||
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The controller where the media is
|
||||
:return:
|
||||
"""
|
||||
threading.Thread(target=output_display.vlc_media_player.stop).start()
|
||||
self.set_state(MediaState.Stopped, output_display)
|
||||
threading.Thread(target=controller.vlc_media_player.stop).start()
|
||||
self.set_state(MediaState.Stopped, controller)
|
||||
|
||||
def volume(self, output_display, vol):
|
||||
def volume(self, controller, vol):
|
||||
"""
|
||||
Set the volume
|
||||
|
||||
:param vol: The volume to be sets
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The controller where the media is
|
||||
:return:
|
||||
"""
|
||||
if output_display.has_audio:
|
||||
output_display.vlc_media_player.audio_set_volume(vol)
|
||||
controller.vlc_media_player.audio_set_volume(vol)
|
||||
|
||||
def seek(self, output_display, seek_value):
|
||||
def seek(self, controller, seek_value):
|
||||
"""
|
||||
Go to a particular position
|
||||
|
||||
:param seek_value: The position of where a seek goes to
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The controller where the media is
|
||||
"""
|
||||
if output_display.media_info.media_type == MediaType.CD \
|
||||
or output_display.media_info.media_type == MediaType.DVD:
|
||||
seek_value += int(output_display.media_info.start_time)
|
||||
if output_display.vlc_media_player.is_seekable():
|
||||
output_display.vlc_media_player.set_time(seek_value)
|
||||
if controller.media_info.media_type == MediaType.CD \
|
||||
or controller.media_info.media_type == MediaType.DVD:
|
||||
seek_value += int(controller.media_info.start_time)
|
||||
if controller.vlc_media_player.is_seekable():
|
||||
controller.vlc_media_player.set_time(seek_value)
|
||||
|
||||
def reset(self, output_display):
|
||||
def reset(self, controller):
|
||||
"""
|
||||
Reset the player
|
||||
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The controller where the media is
|
||||
"""
|
||||
output_display.vlc_media_player.stop()
|
||||
output_display.vlc_widget.setVisible(False)
|
||||
self.set_state(MediaState.Off, output_display)
|
||||
controller.vlc_media_player.stop()
|
||||
controller.vlc_widget.setVisible(False)
|
||||
self.set_state(MediaState.Off, controller)
|
||||
|
||||
def set_visible(self, output_display, status):
|
||||
def set_visible(self, controller, status):
|
||||
"""
|
||||
Set the visibility
|
||||
|
||||
:param output_display: The display where the media is
|
||||
:param controller: The controller where the media display is
|
||||
:param status: The visibility status
|
||||
"""
|
||||
if self.has_own_widget:
|
||||
output_display.vlc_widget.setVisible(status)
|
||||
controller.vlc_widget.setVisible(status)
|
||||
|
||||
def update_ui(self, controller, output_display):
|
||||
"""
|
||||
@ -350,18 +351,18 @@ class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
# Stop video if playback is finished.
|
||||
if output_display.vlc_media.get_state() == vlc.State.Ended:
|
||||
self.stop(output_display)
|
||||
if controller.vlc_media.get_state() == vlc.State.Ended:
|
||||
self.stop(controller)
|
||||
if controller.media_info.end_time > 0:
|
||||
if output_display.vlc_media_player.get_time() > controller.media_info.end_time:
|
||||
self.stop(output_display)
|
||||
self.set_visible(output_display, False)
|
||||
if controller.vlc_media_player.get_time() > controller.media_info.end_time:
|
||||
self.stop(controller)
|
||||
self.set_visible(controller, False)
|
||||
if not controller.seek_slider.isSliderDown():
|
||||
controller.seek_slider.blockSignals(True)
|
||||
if controller.media_info.media_type == MediaType.CD \
|
||||
or controller.media_info.media_type == MediaType.DVD:
|
||||
controller.seek_slider.setSliderPosition(
|
||||
output_display.vlc_media_player.get_time() - int(output_display.controller.media_info.start_time))
|
||||
controller.vlc_media_player.get_time() - int(controller.media_info.start_time))
|
||||
else:
|
||||
controller.seek_slider.setSliderPosition(output_display.vlc_media_player.get_time())
|
||||
controller.seek_slider.setSliderPosition(controller.vlc_media_player.get_time())
|
||||
controller.seek_slider.blockSignals(False)
|
||||
|
@ -1241,7 +1241,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
||||
child = QtWidgets.QTreeWidgetItem(tree_widget_item)
|
||||
# prefer to use a display_title
|
||||
if service_item_from_item.is_capable(ItemCapabilities.HasDisplayTitle) or \
|
||||
service_item_from_item.service_item_type == ServiceItemType.Image:
|
||||
service_item_from_item.service_item_type is not ServiceItemType.Text:
|
||||
text = slide['title'].replace('\n', ' ')
|
||||
else:
|
||||
text = service_item_from_item.get_rendered_frame(slide_index)
|
||||
|
@ -402,8 +402,6 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
self.mediabar.add_toolbar_widget(self.volume_slider)
|
||||
self.controller_layout.addWidget(self.mediabar)
|
||||
self.mediabar.setVisible(False)
|
||||
if not self.is_live:
|
||||
self.volume_slider.setEnabled(False)
|
||||
# Signals
|
||||
self.seek_slider.valueChanged.connect(self.send_to_plugins)
|
||||
self.volume_slider.valueChanged.connect(self.send_to_plugins)
|
||||
@ -885,6 +883,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
width = self.main_window.control_splitter.sizes()[self.split]
|
||||
if self.service_item.is_text():
|
||||
self.preview_display.load_verses(service_item.rendered_slides)
|
||||
self.preview_display.show()
|
||||
for display in self.displays:
|
||||
display.load_verses(service_item.rendered_slides)
|
||||
for slide_index, slide in enumerate(self.service_item.display_slides):
|
||||
@ -909,17 +908,8 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
for slide_index, slide in enumerate(self.service_item.slides):
|
||||
row += 1
|
||||
self.slide_list[str(row)] = row - 1
|
||||
# If current slide set background to image
|
||||
# if not self.service_item.is_command() and slide_index == slide_no:
|
||||
# self.service_item.bg_image_bytes = \
|
||||
# self.image_manager.get_image_bytes(slide['filename'], ImageSource.ImagePlugin)
|
||||
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
|
||||
self.enable_tool_bar(self.service_item)
|
||||
# Pass to display for viewing.
|
||||
# Postpone image build, we need to do this later to avoid the theme
|
||||
# flashing on the screen
|
||||
# if not self.service_item.is_image():
|
||||
# self.display.build_html(self.service_item)
|
||||
if self.service_item.is_media():
|
||||
self.on_media_start(self.service_item)
|
||||
self.slide_selected(True)
|
||||
@ -1397,25 +1387,6 @@ class SlideController(QtWidgets.QWidget, 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_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()
|
||||
|
||||
def timerEvent(self, event):
|
||||
"""
|
||||
If the timer event is for this window select next slide
|
||||
@ -1511,12 +1482,10 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
Respond to a request to close the Video
|
||||
"""
|
||||
self.media_controller.media_reset(self)
|
||||
self.preview_display.hide()
|
||||
|
||||
def _reset_blank(self, no_theme):
|
||||
"""
|
||||
Used by command items which provide their own displays to reset the
|
||||
screen hide attributes
|
||||
Used by command items which provide their own displays to reset the screen hide attributes
|
||||
|
||||
:param no_theme: Does the new item support theme-blanking.
|
||||
"""
|
||||
@ -1549,30 +1518,6 @@ class SlideController(QtWidgets.QWidget, 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())
|
||||
|
||||
|
||||
class PreviewController(RegistryBase, SlideController):
|
||||
"""
|
||||
|
@ -71,7 +71,7 @@ class Ui_ThemeWizard(object):
|
||||
self.background_label = QtWidgets.QLabel(self.background_page)
|
||||
self.background_label.setObjectName('background_label')
|
||||
self.background_combo_box = QtWidgets.QComboBox(self.background_page)
|
||||
self.background_combo_box.addItems(['', '', '', '', '', ''])
|
||||
self.background_combo_box.addItems(['', '', '', ''])
|
||||
self.background_combo_box.setObjectName('background_combo_box')
|
||||
self.background_type_layout.addRow(self.background_label, self.background_combo_box)
|
||||
self.background_type_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
@ -421,11 +421,8 @@ class Ui_ThemeWizard(object):
|
||||
self.background_combo_box.setItemText(BackgroundType.Solid, translate('OpenLP.ThemeWizard', 'Solid color'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Gradient, translate('OpenLP.ThemeWizard', 'Gradient'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Image, UiStrings().Image)
|
||||
self.background_combo_box.setItemText(BackgroundType.Video, UiStrings().Video)
|
||||
self.background_combo_box.setItemText(BackgroundType.Transparent,
|
||||
translate('OpenLP.ThemeWizard', 'Transparent'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Stream,
|
||||
translate('OpenLP.ThemeWizard', 'Live Stream'))
|
||||
self.color_label.setText(translate('OpenLP.ThemeWizard', 'color:'))
|
||||
self.gradient_start_label.setText(translate('OpenLP.ThemeWizard', 'Starting color:'))
|
||||
self.gradient_end_label.setText(translate('OpenLP.ThemeWizard', 'Ending color:'))
|
||||
|
@ -256,7 +256,7 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
||||
titles = self.vlc_media_player.video_get_title_description()
|
||||
self.titles_combo_box.clear()
|
||||
for title in titles:
|
||||
self.titles_combo_box.addItem(title[1].decode(), title[0])
|
||||
self.titles_combo_box.addItem(title.name.decode(), title.id)
|
||||
# Re-enable signals
|
||||
self.blockSignals(False)
|
||||
# Main title is usually title #1
|
||||
@ -626,6 +626,7 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
||||
vlc = get_vlc()
|
||||
start = datetime.now()
|
||||
while media_state != self.vlc_media_player.get_state():
|
||||
sleep(0.1)
|
||||
if self.vlc_media_player.get_state() == vlc.State.Error:
|
||||
return False
|
||||
if (datetime.now() - start).seconds > 15:
|
||||
|
@ -240,7 +240,10 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
track_str = str(track)
|
||||
track_info = QtCore.QFileInfo(track_str)
|
||||
item_name = None
|
||||
if track_str.startswith('optical:'):
|
||||
# Dont add the live stream in when reloading the UI.
|
||||
if track_str == UiStrings().LiveStream:
|
||||
continue
|
||||
elif track_str.startswith('optical:'):
|
||||
# Handle optical based item
|
||||
(file_name, title, audio_track, subtitle_track, start, end, clip_name) = parse_optical_path(track_str)
|
||||
item_name = QtWidgets.QListWidgetItem(clip_name)
|
||||
|
@ -152,7 +152,7 @@ class ImpressController(PresentationController):
|
||||
self.toggle_presentation_screen(False)
|
||||
return desktop
|
||||
except Exception:
|
||||
log.warning('Failed to get UNO desktop')
|
||||
log.exception('Failed to get UNO desktop')
|
||||
return None
|
||||
|
||||
def get_com_desktop(self):
|
||||
@ -232,7 +232,7 @@ class ImpressController(PresentationController):
|
||||
self.conf_provider = self.manager.createInstanceWithContext(
|
||||
'com.sun.star.configuration.ConfigurationProvider', uno.getComponentContext())
|
||||
# Setup lookup properties to get Impress settings
|
||||
properties = tuple(self.create_property('nodepath', 'org.openoffice.Office.Impress'))
|
||||
properties = (self.create_property('nodepath', 'org.openoffice.Office.Impress'),)
|
||||
try:
|
||||
# Get an updateable configuration view
|
||||
impress_conf_props = self.conf_provider.createInstanceWithArguments(
|
||||
@ -308,7 +308,7 @@ class ImpressDocument(PresentationDocument):
|
||||
if desktop is None:
|
||||
return False
|
||||
self.desktop = desktop
|
||||
properties = tuple(self.controller.create_property('Hidden', True))
|
||||
properties = (self.controller.create_property('Hidden', True),)
|
||||
try:
|
||||
self.document = desktop.loadComponentFromURL(url, '_blank', 0, properties)
|
||||
except Exception:
|
||||
@ -333,7 +333,7 @@ class ImpressDocument(PresentationDocument):
|
||||
return
|
||||
temp_folder_path = self.get_temp_folder()
|
||||
thumb_dir_url = temp_folder_path.as_uri()
|
||||
properties = tuple(self.controller.create_property('FilterName', 'impress_png_Export'))
|
||||
properties = (self.controller.create_property('FilterName', 'impress_png_Export'),)
|
||||
doc = self.document
|
||||
pages = doc.getDrawPages()
|
||||
if not pages:
|
||||
|
@ -144,7 +144,7 @@ class OpenOfficeImport(SongImport):
|
||||
"""
|
||||
self.file_path = file_path
|
||||
url = file_path.as_uri()
|
||||
properties = tuple(self.create_property('Hidden', True))
|
||||
properties = (self.create_property('Hidden', True),)
|
||||
try:
|
||||
self.document = self.desktop.loadComponentFromURL(url, '_blank', 0, properties)
|
||||
if not self.document.supportsService("com.sun.star.presentation.PresentationDocument") and not \
|
||||
|
@ -138,9 +138,9 @@ class TestMedia(TestCase, TestMixin):
|
||||
(device_path, title_track, audio_track, subtitle_track, start, end, name) = parse_optical_path(path)
|
||||
|
||||
# THEN: The return values should match the original values
|
||||
assert org_title_track == title_track, 'Returned title_track should match the original'
|
||||
assert org_title_track == int(title_track), 'Returned title_track should match the original'
|
||||
assert org_audio_track == audio_track, 'Returned audio_track should match the original'
|
||||
assert org_subtitle_track == subtitle_track, 'Returned subtitle_track should match the original'
|
||||
assert org_subtitle_track == int(subtitle_track), 'Returned subtitle_track should match the original'
|
||||
assert org_start == start, 'Returned start should match the original'
|
||||
assert org_end == end, 'Returned end should match the original'
|
||||
assert org_name == name, 'Returned end should match the original'
|
||||
@ -166,9 +166,9 @@ class TestMedia(TestCase, TestMixin):
|
||||
(device_path, title_track, audio_track, subtitle_track, start, end, name) = parse_optical_path(path)
|
||||
|
||||
# THEN: The return values should match the original values
|
||||
assert org_title_track == title_track, 'Returned title_track should match the original'
|
||||
assert org_title_track == int(title_track), 'Returned title_track should match the original'
|
||||
assert org_audio_track == audio_track, 'Returned audio_track should match the original'
|
||||
assert org_subtitle_track == subtitle_track, 'Returned subtitle_track should match the original'
|
||||
assert org_subtitle_track == int(subtitle_track), 'Returned subtitle_track should match the original'
|
||||
assert org_start == start, 'Returned start should match the original'
|
||||
assert org_end == end, 'Returned end should match the original'
|
||||
assert org_name == name, 'Returned end should match the original'
|
@ -28,7 +28,7 @@ from unittest import TestCase, skip
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.ui.media import MediaState, MediaType
|
||||
from openlp.core.ui.media import ItemMediaInfo, MediaState, MediaType
|
||||
from openlp.core.ui.media.vlcplayer import VlcPlayer, get_vlc
|
||||
from tests.helpers import MockDateTime
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
@ -127,7 +127,7 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: setup() is run
|
||||
vlc_player.setup(mocked_output_display, mocked_controller)
|
||||
vlc_player.setup(mocked_output_display, mocked_controller, True)
|
||||
|
||||
# THEN: The VLC widget should be set up correctly
|
||||
assert mocked_output_display.vlc_widget == mocked_qframe
|
||||
@ -177,7 +177,7 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: setup() is run
|
||||
vlc_player.setup(mocked_output_display, mocked_controller)
|
||||
vlc_player.setup(mocked_output_display, mocked_controller, True)
|
||||
|
||||
# THEN: The VLC instance should be created with the correct options
|
||||
mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
|
||||
@ -215,7 +215,7 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: setup() is run
|
||||
vlc_player.setup(mocked_output_display, mocked_controller)
|
||||
vlc_player.setup(mocked_output_display, mocked_controller, True)
|
||||
|
||||
# THEN: The VLC instance should be created with the correct options
|
||||
mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
|
||||
@ -252,7 +252,7 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: setup() is run
|
||||
vlc_player.setup(mocked_output_display, mocked_controller)
|
||||
vlc_player.setup(mocked_output_display, mocked_controller, True)
|
||||
|
||||
# THEN: set_hwnd should be called
|
||||
mocked_media_player_new.set_hwnd.assert_called_with(2)
|
||||
@ -289,7 +289,7 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: setup() is run
|
||||
vlc_player.setup(mocked_output_display, mocked_controller)
|
||||
vlc_player.setup(mocked_output_display, mocked_controller, True)
|
||||
|
||||
# THEN: set_nsobject should be called
|
||||
mocked_media_player_new.set_nsobject.assert_called_with(2)
|
||||
@ -336,27 +336,28 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_vlc = MagicMock()
|
||||
mocked_get_vlc.return_value = mocked_vlc
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.media_info.volume = 100
|
||||
mocked_display.media_info.media_type = MediaType.Video
|
||||
mocked_display.media_info.file_info.absoluteFilePath.return_value = media_path
|
||||
mocked_controller = MagicMock()
|
||||
mocked_controller.media_info.volume = 100
|
||||
mocked_controller.media_info.media_type = MediaType.Video
|
||||
mocked_controller.media_info.file_info.absoluteFilePath.return_value = media_path
|
||||
mocked_vlc_media = MagicMock()
|
||||
mocked_media = MagicMock()
|
||||
mocked_media.get_duration.return_value = 10000
|
||||
mocked_display.vlc_instance.media_new_path.return_value = mocked_vlc_media
|
||||
mocked_display.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_controller.vlc_instance.media_new_path.return_value = mocked_vlc_media
|
||||
mocked_controller.vlc_media_player.get_media.return_value = mocked_media
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: A video is loaded into VLC
|
||||
with patch.object(vlc_player, 'volume') as mocked_volume:
|
||||
result = vlc_player.load(mocked_display, media_path)
|
||||
result = vlc_player.load(mocked_controller, mocked_display, media_path)
|
||||
|
||||
# THEN: The video should be loaded
|
||||
mocked_normcase.assert_called_with(media_path)
|
||||
mocked_display.vlc_instance.media_new_path.assert_called_with(media_path)
|
||||
assert mocked_vlc_media == mocked_display.vlc_media
|
||||
mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
mocked_controller.vlc_instance.media_new_path.assert_called_with(media_path)
|
||||
assert mocked_vlc_media == mocked_controller.vlc_media
|
||||
mocked_controller.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
mocked_vlc_media.parse.assert_called_with()
|
||||
mocked_volume.assert_called_with(mocked_display, 100)
|
||||
mocked_volume.assert_called_with(mocked_controller, 100)
|
||||
assert result is True
|
||||
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_win')
|
||||
@ -373,14 +374,15 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_vlc = MagicMock()
|
||||
mocked_get_vlc.return_value = mocked_vlc
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.media_info.volume = 100
|
||||
mocked_display.media_info.media_type = MediaType.CD
|
||||
mocked_display.media_info.title_track = 1
|
||||
mocked_controller = MagicMock()
|
||||
mocked_controller.media_info.volume = 100
|
||||
mocked_controller.media_info.media_type = MediaType.CD
|
||||
mocked_controller.media_info.title_track = 1
|
||||
mocked_vlc_media = MagicMock()
|
||||
mocked_media = MagicMock()
|
||||
mocked_media.get_duration.return_value = 10000
|
||||
mocked_display.vlc_instance.media_new_location.return_value = mocked_vlc_media
|
||||
mocked_display.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_controller.vlc_instance.media_new_location.return_value = mocked_vlc_media
|
||||
mocked_controller.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_subitems = MagicMock()
|
||||
mocked_subitems.count.return_value = 1
|
||||
mocked_subitems.item_at_index.return_value = mocked_vlc_media
|
||||
@ -390,15 +392,15 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
# WHEN: An audio CD is loaded into VLC
|
||||
with patch.object(vlc_player, 'volume') as mocked_volume, \
|
||||
patch.object(vlc_player, 'media_state_wait'):
|
||||
result = vlc_player.load(mocked_display, media_path)
|
||||
result = vlc_player.load(mocked_controller, mocked_display, media_path)
|
||||
|
||||
# THEN: The video should be loaded
|
||||
mocked_normcase.assert_called_with(media_path)
|
||||
mocked_display.vlc_instance.media_new_location.assert_called_with('cdda://' + media_path)
|
||||
assert mocked_vlc_media == mocked_display.vlc_media
|
||||
mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
mocked_controller.vlc_instance.media_new_location.assert_called_with('cdda://' + media_path)
|
||||
assert mocked_vlc_media == mocked_controller.vlc_media
|
||||
mocked_controller.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
mocked_vlc_media.parse.assert_called_with()
|
||||
mocked_volume.assert_called_with(mocked_display, 100)
|
||||
mocked_volume.assert_called_with(mocked_controller, 100)
|
||||
assert result is True
|
||||
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_win')
|
||||
@ -415,15 +417,16 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_vlc = MagicMock()
|
||||
mocked_get_vlc.return_value = mocked_vlc
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.media_info.volume = 100
|
||||
mocked_display.media_info.media_type = MediaType.CD
|
||||
mocked_display.media_info.file_info.absoluteFilePath.return_value = media_path
|
||||
mocked_display.media_info.title_track = 1
|
||||
mocked_controller = MagicMock()
|
||||
mocked_controller.media_info.volume = 100
|
||||
mocked_controller.media_info.media_type = MediaType.CD
|
||||
mocked_controller.media_info.file_info.absoluteFilePath.return_value = media_path
|
||||
mocked_controller.media_info.title_track = 1
|
||||
mocked_vlc_media = MagicMock()
|
||||
mocked_media = MagicMock()
|
||||
mocked_media.get_duration.return_value = 10000
|
||||
mocked_display.vlc_instance.media_new_location.return_value = mocked_vlc_media
|
||||
mocked_display.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_controller.vlc_instance.media_new_location.return_value = mocked_vlc_media
|
||||
mocked_controller.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_subitems = MagicMock()
|
||||
mocked_subitems.count.return_value = 1
|
||||
mocked_subitems.item_at_index.return_value = mocked_vlc_media
|
||||
@ -433,15 +436,15 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
# WHEN: An audio CD is loaded into VLC
|
||||
with patch.object(vlc_player, 'volume') as mocked_volume, \
|
||||
patch.object(vlc_player, 'media_state_wait'):
|
||||
result = vlc_player.load(mocked_display, media_path)
|
||||
result = vlc_player.load(mocked_controller, mocked_display, media_path)
|
||||
|
||||
# THEN: The video should be loaded
|
||||
mocked_normcase.assert_called_with(media_path)
|
||||
mocked_display.vlc_instance.media_new_location.assert_called_with('cdda:///' + media_path)
|
||||
assert mocked_vlc_media == mocked_display.vlc_media
|
||||
mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
mocked_controller.vlc_instance.media_new_location.assert_called_with('cdda:///' + media_path)
|
||||
assert mocked_vlc_media == mocked_controller.vlc_media
|
||||
mocked_controller.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
mocked_vlc_media.parse.assert_called_with()
|
||||
mocked_volume.assert_called_with(mocked_display, 100)
|
||||
mocked_volume.assert_called_with(mocked_controller, 100)
|
||||
assert result is True
|
||||
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_win')
|
||||
@ -458,15 +461,19 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_vlc = MagicMock()
|
||||
mocked_get_vlc.return_value = mocked_vlc
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.media_info.volume = 100
|
||||
mocked_display.media_info.media_type = MediaType.CD
|
||||
mocked_display.media_info.file_info.absoluteFilePath.return_value = media_path
|
||||
mocked_display.media_info.title_track = 1
|
||||
mocked_controller = MagicMock()
|
||||
mocked_controller.media_info.volume = 100
|
||||
mocked_controller.media_info.media_type = MediaType.CD
|
||||
mocked_controller.media_info.file_info.absoluteFilePath.return_value = media_path
|
||||
mocked_controller.media_info.title_track = 1
|
||||
mocked_vlc_media = MagicMock()
|
||||
mocked_vlc_media_player = MagicMock()
|
||||
mocked_controller.vlc_media = mocked_vlc_media
|
||||
mocked_controller.vlc_media_player = mocked_vlc_media_player
|
||||
mocked_media = MagicMock()
|
||||
mocked_media.get_duration.return_value = 10000
|
||||
mocked_display.vlc_instance.media_new_location.return_value = mocked_vlc_media
|
||||
mocked_display.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_controller.vlc_instance.media_new_location.return_value = mocked_vlc_media
|
||||
mocked_controller.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_subitems = MagicMock()
|
||||
mocked_subitems.count.return_value = 0
|
||||
mocked_subitems.item_at_index.return_value = mocked_vlc_media
|
||||
@ -475,14 +482,14 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
|
||||
# WHEN: An audio CD is loaded into VLC
|
||||
with patch.object(vlc_player, 'volume'), patch.object(vlc_player, 'media_state_wait'):
|
||||
result = vlc_player.load(mocked_display, media_path)
|
||||
result = vlc_player.load(mocked_controller, mocked_display, media_path)
|
||||
|
||||
# THEN: The video should be loaded
|
||||
mocked_normcase.assert_called_with(media_path)
|
||||
mocked_display.vlc_instance.media_new_location.assert_called_with('cdda://' + media_path)
|
||||
assert mocked_vlc_media == mocked_display.vlc_media
|
||||
mocked_controller.vlc_instance.media_new_location.assert_called_with('cdda://' + media_path)
|
||||
assert mocked_vlc_media == mocked_controller.vlc_media
|
||||
assert 0 == mocked_subitems.item_at_index.call_count
|
||||
mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
mocked_controller.vlc_media_player.set_media.assert_called_with(mocked_vlc_media)
|
||||
assert 0 == mocked_vlc_media.parse.call_count
|
||||
assert result is False
|
||||
|
||||
@ -562,17 +569,17 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
Test resizing the player
|
||||
"""
|
||||
# GIVEN: A display object and a VlcPlayer instance
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.size.return_value = (10, 10)
|
||||
mocked_display.is_display = False
|
||||
mocked_controller = MagicMock()
|
||||
mocked_controller.preview_display.size.return_value = (10, 10)
|
||||
mocked_controller.is_live = False
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: resize is called
|
||||
vlc_player.resize(mocked_display)
|
||||
vlc_player.resize(mocked_controller)
|
||||
|
||||
# THEN: The right methods should have been called
|
||||
mocked_display.size.assert_called_with()
|
||||
mocked_display.vlc_widget.resize.assert_called_with((10, 10))
|
||||
mocked_controller.preview_display.size.assert_called_with()
|
||||
mocked_controller.vlc_widget.resize.assert_called_with((10, 10))
|
||||
|
||||
@patch('openlp.core.ui.media.vlcplayer.threading')
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
@ -586,27 +593,27 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_vlc = MagicMock()
|
||||
mocked_get_vlc.return_value = mocked_vlc
|
||||
mocked_display = MagicMock()
|
||||
mocked_controller = MagicMock()
|
||||
mocked_media = MagicMock()
|
||||
mocked_media.get_duration.return_value = 50000
|
||||
mocked_output_display = MagicMock()
|
||||
mocked_output_display.media_info.start_time = 0
|
||||
mocked_output_display.media_info.media_type = MediaType.Video
|
||||
mocked_output_display.media_info.volume = 100
|
||||
mocked_output_display.vlc_media_player.get_media.return_value = mocked_media
|
||||
mocked_controller.media_info.start_time = 0
|
||||
mocked_controller.media_info.media_type = MediaType.Video
|
||||
mocked_controller.media_info.volume = 100
|
||||
mocked_controller.vlc_media_player.get_media.return_value = mocked_media
|
||||
vlc_player = VlcPlayer(None)
|
||||
vlc_player.set_state(MediaState.Paused, mocked_output_display)
|
||||
vlc_player.set_state(MediaState.Paused, mocked_controller)
|
||||
|
||||
# WHEN: play() is called
|
||||
with patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait, \
|
||||
patch.object(vlc_player, 'volume') as mocked_volume:
|
||||
mocked_media_state_wait.return_value = True
|
||||
result = vlc_player.play(mocked_display, mocked_output_display)
|
||||
result = vlc_player.play(mocked_controller, mocked_display)
|
||||
|
||||
# THEN: A bunch of things should happen to play the media
|
||||
mocked_thread.start.assert_called_with()
|
||||
mocked_volume.assert_called_with(mocked_output_display, 100)
|
||||
mocked_volume.assert_called_with(mocked_controller, 100)
|
||||
assert MediaState.Playing == vlc_player.get_live_state()
|
||||
mocked_output_display.vlc_widget.raise_.assert_called_with()
|
||||
mocked_controller.vlc_widget.raise_.assert_called_with()
|
||||
assert result is True, 'The value returned from play() should be True'
|
||||
|
||||
@patch('openlp.core.ui.media.vlcplayer.threading')
|
||||
@ -649,13 +656,14 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_get_vlc.return_value = mocked_vlc
|
||||
mocked_controller = MagicMock()
|
||||
mocked_output_display = MagicMock()
|
||||
mocked_output_display.media_info.start_time = 0
|
||||
mocked_output_display.media_info.end_time = 50
|
||||
mocked_output_display.media_info.media_type = MediaType.DVD
|
||||
mocked_output_display.media_info.volume = 100
|
||||
mocked_output_display.media_info.title_track = 1
|
||||
mocked_output_display.media_info.audio_track = 1
|
||||
mocked_output_display.media_info.subtitle_track = 1
|
||||
mocked_controller.media_info = ItemMediaInfo()
|
||||
mocked_controller.media_info.start_time = 0
|
||||
mocked_controller.media_info.end_time = 50
|
||||
mocked_controller.media_info.media_type = MediaType.DVD
|
||||
mocked_controller.media_info.volume = 100
|
||||
mocked_controller.media_info.title_track = 1
|
||||
mocked_controller.media_info.audio_track = 1
|
||||
mocked_controller.media_info.subtitle_track = 1
|
||||
vlc_player = VlcPlayer(None)
|
||||
vlc_player.set_state(MediaState.Paused, mocked_output_display)
|
||||
|
||||
@ -667,13 +675,13 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
|
||||
# THEN: A bunch of things should happen to play the media
|
||||
mocked_thread.start.assert_called_with()
|
||||
mocked_output_display.vlc_media_player.set_title.assert_called_with(1)
|
||||
mocked_output_display.vlc_media_player.play.assert_called_with()
|
||||
mocked_output_display.vlc_media_player.audio_set_track.assert_called_with(1)
|
||||
mocked_output_display.vlc_media_player.video_set_spu.assert_called_with(1)
|
||||
mocked_volume.assert_called_with(mocked_output_display, 100)
|
||||
mocked_controller.vlc_media_player.set_title.assert_called_with(1)
|
||||
mocked_controller.vlc_media_player.play.assert_called_with()
|
||||
mocked_controller.vlc_media_player.audio_set_track.assert_called_with(1)
|
||||
mocked_controller.vlc_media_player.video_set_spu.assert_called_with(1)
|
||||
mocked_volume.assert_called_with(mocked_controller, 100)
|
||||
assert MediaState.Playing == vlc_player.get_live_state()
|
||||
mocked_output_display.vlc_widget.raise_.assert_called_with()
|
||||
mocked_controller.vlc_widget.raise_.assert_called_with()
|
||||
assert result is True, 'The value returned from play() should be True'
|
||||
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
@ -782,21 +790,6 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
# THEN: The volume should have been set
|
||||
mocked_display.vlc_media_player.audio_set_volume.assert_called_with(10)
|
||||
|
||||
def test_volume_no_audio(self):
|
||||
"""
|
||||
Test setting the volume when there's no audio
|
||||
"""
|
||||
# GIVEN: A display object and a VlcPlayer instance
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.has_audio = False
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: The volume is set
|
||||
vlc_player.volume(mocked_display, 10)
|
||||
|
||||
# THEN: The volume should NOT have been set
|
||||
assert 0 == mocked_display.vlc_media_player.audio_set_volume.call_count
|
||||
|
||||
def test_seek_unseekable_media(self):
|
||||
"""
|
||||
Test seeking something that can't be seeked
|
||||
@ -880,21 +873,6 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
# THEN: The media should be stopped and invsibile
|
||||
mocked_display.vlc_widget.setVisible.assert_called_with(True)
|
||||
|
||||
def test_set_visible_no_widget(self):
|
||||
"""
|
||||
Test the set_visible() method when the player doesn't have a widget
|
||||
"""
|
||||
# GIVEN: Some mocked out stuff
|
||||
mocked_display = MagicMock()
|
||||
vlc_player = VlcPlayer(None)
|
||||
vlc_player.has_own_widget = False
|
||||
|
||||
# WHEN: reset() is called
|
||||
vlc_player.set_visible(mocked_display, True)
|
||||
|
||||
# THEN: The media should be stopped and invsibile
|
||||
assert 0 == mocked_display.vlc_widget.setVisible.call_count
|
||||
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
def test_update_ui(self, mocked_get_vlc):
|
||||
"""
|
||||
@ -908,8 +886,8 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_controller.media_info.end_time = 300
|
||||
mocked_controller.seek_slider.isSliderDown.return_value = False
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.vlc_media.get_state.return_value = 1
|
||||
mocked_display.vlc_media_player.get_time.return_value = 400000
|
||||
mocked_controller.vlc_media.get_state.return_value = 1
|
||||
mocked_controller.vlc_media_player.get_time.return_value = 400000
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: update_ui() is called
|
||||
@ -918,10 +896,10 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
vlc_player.update_ui(mocked_controller, mocked_display)
|
||||
|
||||
# THEN: Certain methods should be called
|
||||
mocked_stop.assert_called_with(mocked_display)
|
||||
mocked_stop.assert_called_with(mocked_controller)
|
||||
assert 2 == mocked_stop.call_count
|
||||
mocked_display.vlc_media_player.get_time.assert_called_with()
|
||||
mocked_set_visible.assert_called_with(mocked_display, False)
|
||||
mocked_controller.vlc_media_player.get_time.assert_called_with()
|
||||
mocked_set_visible.assert_called_with(mocked_controller, False)
|
||||
mocked_controller.seek_slider.setSliderPosition.assert_called_with(400000)
|
||||
expected_calls = [call(True), call(False)]
|
||||
assert expected_calls == mocked_controller.seek_slider.blockSignals.call_args_list
|
||||
@ -936,13 +914,14 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
mocked_vlc.State.Ended = 1
|
||||
mocked_get_vlc.return_value = mocked_vlc
|
||||
mocked_controller = MagicMock()
|
||||
mocked_controller.media_info = ItemMediaInfo()
|
||||
mocked_controller.media_info.start_time = 100
|
||||
mocked_controller.media_info.end_time = 300
|
||||
mocked_controller.seek_slider.isSliderDown.return_value = False
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.vlc_media.get_state.return_value = 1
|
||||
mocked_display.vlc_media_player.get_time.return_value = 300
|
||||
mocked_display.controller.media_info.media_type = MediaType.DVD
|
||||
mocked_controller.vlc_media.get_state.return_value = 1
|
||||
mocked_controller.vlc_media_player.get_time.return_value = 300
|
||||
mocked_controller.media_info.media_type = MediaType.DVD
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: update_ui() is called
|
||||
@ -950,9 +929,9 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
vlc_player.update_ui(mocked_controller, mocked_display)
|
||||
|
||||
# THEN: Certain methods should be called
|
||||
mocked_stop.assert_called_with(mocked_display)
|
||||
mocked_stop.assert_called_with(mocked_controller)
|
||||
assert 1 == mocked_stop.call_count
|
||||
mocked_display.vlc_media_player.get_time.assert_called_with()
|
||||
mocked_controller.seek_slider.setSliderPosition.assert_called_with(300)
|
||||
mocked_controller.vlc_media_player.get_time.assert_called_with()
|
||||
mocked_controller.seek_slider.setSliderPosition.assert_called_with(200)
|
||||
expected_calls = [call(True), call(False)]
|
||||
assert expected_calls == mocked_controller.seek_slider.blockSignals.call_args_list
|
||||
|
@ -24,7 +24,7 @@ Functional tests to test the Impress class and related methods.
|
||||
import shutil
|
||||
from tempfile import mkdtemp
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.plugins.presentations.lib.impresscontroller import ImpressController, ImpressDocument, TextType
|
||||
@ -86,7 +86,7 @@ class TestImpressController(TestCase, TestMixin):
|
||||
assert result is False
|
||||
|
||||
@patch('openlp.plugins.presentations.lib.impresscontroller.log')
|
||||
def test_check_available1(self, mocked_log):
|
||||
def test_check_available_on_windows(self, mocked_log):
|
||||
"""
|
||||
Test `ImpressController.check_available` on Windows
|
||||
"""
|
||||
@ -106,7 +106,7 @@ class TestImpressController(TestCase, TestMixin):
|
||||
|
||||
@patch('openlp.plugins.presentations.lib.impresscontroller.log')
|
||||
@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False)
|
||||
def test_check_available2(self, mocked_is_win, mocked_log):
|
||||
def test_check_available_on_linux(self, mocked_is_win, mocked_log):
|
||||
"""
|
||||
Test `ImpressController.check_available` when not on Windows
|
||||
"""
|
||||
@ -122,6 +122,44 @@ class TestImpressController(TestCase, TestMixin):
|
||||
assert mocked_get_com_servicemanager.called is False
|
||||
assert result is True
|
||||
|
||||
@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True)
|
||||
def test_start_process_on_windows(self, mocked_is_win):
|
||||
"""
|
||||
Test that start_process() on Windows starts the process
|
||||
"""
|
||||
# GIVEN: An ImpressController object
|
||||
controller = ImpressController(plugin=self.mock_plugin)
|
||||
controller.get_com_servicemanager = MagicMock(return_value=MagicMock())
|
||||
|
||||
# WHEN: start_process() is called
|
||||
controller.start_process()
|
||||
|
||||
# THEN: The correct methods should have been called
|
||||
controller.get_com_servicemanager.assert_called_once()
|
||||
assert controller.manager._FlagAsMethod.call_args_list == [call('Bridge_GetStruct'),
|
||||
call('Bridge_GetValueObject')]
|
||||
|
||||
@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False)
|
||||
@patch('openlp.plugins.presentations.lib.impresscontroller.get_uno_command', return_value='libreoffice')
|
||||
@patch('openlp.plugins.presentations.lib.impresscontroller.QtCore.QProcess')
|
||||
def test_start_process_on_linux(self, MockQProcess, mocked_get_uno_command, mocked_is_win):
|
||||
"""
|
||||
Test that start_process() on Linux starts the process
|
||||
"""
|
||||
# GIVEN: An ImpressController object
|
||||
mocked_process = MagicMock()
|
||||
MockQProcess.return_value = mocked_process
|
||||
controller = ImpressController(plugin=self.mock_plugin)
|
||||
|
||||
# WHEN: start_process() is called
|
||||
controller.start_process()
|
||||
|
||||
# THEN: The correct methods should have been called
|
||||
mocked_get_uno_command.assert_called_once()
|
||||
MockQProcess.assert_called_once()
|
||||
assert controller.process is mocked_process
|
||||
mocked_process.startDetached.assert_called_once_with('libreoffice')
|
||||
|
||||
|
||||
class TestImpressDocument(TestCase):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user