mirror of https://gitlab.com/openlp/openlp.git
Made it possible to save and load optical clip to servicefile. Also some pep8 and general cleanup.
This commit is contained in:
parent
e6f23324ba
commit
3988aacfbd
|
@ -435,7 +435,10 @@ class ServiceItem(object):
|
||||||
for text_image in serviceitem['serviceitem']['data']:
|
for text_image in serviceitem['serviceitem']['data']:
|
||||||
if not self.title:
|
if not self.title:
|
||||||
self.title = text_image['title']
|
self.title = text_image['title']
|
||||||
if path:
|
if self.is_capable(ItemCapabilities.IsOptical):
|
||||||
|
self.has_original_files = False
|
||||||
|
self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
|
||||||
|
elif path:
|
||||||
self.has_original_files = False
|
self.has_original_files = False
|
||||||
self.add_from_command(path, text_image['title'], text_image['image'])
|
self.add_from_command(path, text_image['title'], text_image['image'])
|
||||||
else:
|
else:
|
||||||
|
@ -446,7 +449,7 @@ class ServiceItem(object):
|
||||||
"""
|
"""
|
||||||
Returns the title of the service item.
|
Returns the title of the service item.
|
||||||
"""
|
"""
|
||||||
if self.is_text():
|
if self.is_text() or self.is_capable(ItemCapabilities.IsOptical):
|
||||||
return self.title
|
return self.title
|
||||||
else:
|
else:
|
||||||
if len(self._raw_frames) > 1:
|
if len(self._raw_frames) > 1:
|
||||||
|
@ -516,7 +519,8 @@ class ServiceItem(object):
|
||||||
"""
|
"""
|
||||||
Confirms if the ServiceItem uses a file
|
Confirms if the ServiceItem uses a file
|
||||||
"""
|
"""
|
||||||
return self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command
|
return self.service_item_type == ServiceItemType.Image or \
|
||||||
|
(self.service_item_type == ServiceItemType.Command and not self.is_capable(ItemCapabilities.IsOptical))
|
||||||
|
|
||||||
def is_text(self):
|
def is_text(self):
|
||||||
"""
|
"""
|
||||||
|
@ -646,15 +650,20 @@ class ServiceItem(object):
|
||||||
self.is_valid = False
|
self.is_valid = False
|
||||||
break
|
break
|
||||||
elif self.is_command():
|
elif self.is_command():
|
||||||
file_name = os.path.join(frame['path'], frame['title'])
|
if self.is_capable(ItemCapabilities.IsOptical):
|
||||||
if not os.path.exists(file_name):
|
if not os.path.exists(frame['title']):
|
||||||
self.is_valid = False
|
|
||||||
break
|
|
||||||
if suffix_list and not self.is_text():
|
|
||||||
file_suffix = frame['title'].split('.')[-1]
|
|
||||||
if file_suffix.lower() not in suffix_list:
|
|
||||||
self.is_valid = False
|
self.is_valid = False
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
file_name = os.path.join(frame['path'], frame['title'])
|
||||||
|
if not os.path.exists(file_name):
|
||||||
|
self.is_valid = False
|
||||||
|
break
|
||||||
|
if suffix_list and not self.is_text():
|
||||||
|
file_suffix = frame['title'].split('.')[-1]
|
||||||
|
if file_suffix.lower() not in suffix_list:
|
||||||
|
self.is_valid = False
|
||||||
|
break
|
||||||
|
|
||||||
def _get_renderer(self):
|
def _get_renderer(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -102,11 +102,8 @@ def set_media_players(players_list, overridden_player='auto'):
|
||||||
This method saves the configured media players and overridden player to the
|
This method saves the configured media players and overridden player to the
|
||||||
settings
|
settings
|
||||||
|
|
||||||
``players_list``
|
:param players_list: A list with all active media players.
|
||||||
A list with all active media players.
|
:param overridden_player: Here an special media player is chosen for all media actions.
|
||||||
|
|
||||||
``overridden_player``
|
|
||||||
Here an special media player is chosen for all media actions.
|
|
||||||
"""
|
"""
|
||||||
log.debug('set_media_players')
|
log.debug('set_media_players')
|
||||||
players = ','.join(players_list)
|
players = ','.join(players_list)
|
||||||
|
@ -114,6 +111,24 @@ def set_media_players(players_list, overridden_player='auto'):
|
||||||
players = players.replace(overridden_player, '[%s]' % overridden_player)
|
players = players.replace(overridden_player, '[%s]' % overridden_player)
|
||||||
Settings().setValue('media/players', players)
|
Settings().setValue('media/players', players)
|
||||||
|
|
||||||
|
def parse_optical_path(input):
|
||||||
|
"""
|
||||||
|
Split the optical path info.
|
||||||
|
|
||||||
|
:param input: The string to parse
|
||||||
|
:return: The elements extracted from the string: filename, title, audio_track, subtitle_track, start, end
|
||||||
|
"""
|
||||||
|
clip_info = input.split(sep=':')
|
||||||
|
title = int(clip_info[1])
|
||||||
|
audio_track = int(clip_info[2])
|
||||||
|
subtitle_track = int(clip_info[3])
|
||||||
|
start = float(clip_info[4])
|
||||||
|
end = float(clip_info[5])
|
||||||
|
filename = clip_info[6]
|
||||||
|
if len(clip_info) > 7:
|
||||||
|
filename += clip_info[7]
|
||||||
|
return filename, title, audio_track, subtitle_track, start, end
|
||||||
|
|
||||||
from .mediacontroller import MediaController
|
from .mediacontroller import MediaController
|
||||||
from .playertab import PlayerTab
|
from .playertab import PlayerTab
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ from PyQt4 import QtCore, QtGui
|
||||||
from openlp.core.common import Registry, RegistryMixin, Settings, UiStrings, translate
|
from openlp.core.common import Registry, RegistryMixin, Settings, UiStrings, translate
|
||||||
from openlp.core.lib import OpenLPToolbar, ItemCapabilities
|
from openlp.core.lib import OpenLPToolbar, ItemCapabilities
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players
|
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players, parse_optical_path
|
||||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||||
from openlp.core.common import AppLocation
|
from openlp.core.common import AppLocation
|
||||||
from openlp.core.ui import DisplayControllerType
|
from openlp.core.ui import DisplayControllerType
|
||||||
|
@ -397,7 +397,7 @@ class MediaController(object):
|
||||||
if service_item.is_capable(ItemCapabilities.IsOptical):
|
if service_item.is_capable(ItemCapabilities.IsOptical):
|
||||||
log.debug('video is optical and live')
|
log.debug('video is optical and live')
|
||||||
path = service_item.get_frame_path()
|
path = service_item.get_frame_path()
|
||||||
(name, title, audio_track, subtitle_track, start, end) = self.parse_optical_path(path)
|
(name, title, audio_track, subtitle_track, start, end) = parse_optical_path(path)
|
||||||
is_valid = self.media_setup_optical(name, title, audio_track, subtitle_track, start, end, display, controller)
|
is_valid = self.media_setup_optical(name, title, audio_track, subtitle_track, start, end, display, controller)
|
||||||
else :
|
else :
|
||||||
log.debug('video is not optical and live')
|
log.debug('video is not optical and live')
|
||||||
|
@ -415,7 +415,7 @@ class MediaController(object):
|
||||||
if service_item.is_capable(ItemCapabilities.IsOptical):
|
if service_item.is_capable(ItemCapabilities.IsOptical):
|
||||||
log.debug('video is optical and preview')
|
log.debug('video is optical and preview')
|
||||||
path = service_item.get_frame_path()
|
path = service_item.get_frame_path()
|
||||||
(name, title, audio_track, subtitle_track, start, end) = self.parse_optical_path(path)
|
(name, title, audio_track, subtitle_track, start, end) = parse_optical_path(path)
|
||||||
is_valid = self.media_setup_optical(name, title, audio_track, subtitle_track, start, end, display, controller)
|
is_valid = self.media_setup_optical(name, title, audio_track, subtitle_track, start, end, display, controller)
|
||||||
else :
|
else :
|
||||||
log.debug('video is not optical and preview')
|
log.debug('video is not optical and preview')
|
||||||
|
@ -819,16 +819,3 @@ class MediaController(object):
|
||||||
|
|
||||||
live_controller = property(_get_live_controller)
|
live_controller = property(_get_live_controller)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse_optical_path(input):
|
|
||||||
# split the clip info
|
|
||||||
clip_info = input.split(sep=':')
|
|
||||||
title = int(clip_info[1])
|
|
||||||
audio_track = int(clip_info[2])
|
|
||||||
subtitle_track = int(clip_info[3])
|
|
||||||
start = float(clip_info[4])
|
|
||||||
end = float(clip_info[5])
|
|
||||||
filename = clip_info[6]
|
|
||||||
if len(clip_info) > 7:
|
|
||||||
filename += clip_info[7]
|
|
||||||
return filename, title, audio_track, subtitle_track, start, end
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
"""
|
"""
|
||||||
Exit Dialog and do not save
|
Exit Dialog and do not save
|
||||||
"""
|
"""
|
||||||
log.debug ('MediaClipSelectorForm.reject')
|
log.debug('MediaClipSelectorForm.reject')
|
||||||
self.vlc_media_player.stop()
|
self.vlc_media_player.stop()
|
||||||
QtGui.QDialog.reject(self)
|
QtGui.QDialog.reject(self)
|
||||||
|
|
||||||
|
@ -110,6 +110,8 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_load_disc_pushbutton_clicked(self, clicked):
|
def on_load_disc_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Load the media when the load-button has been clicked
|
Load the media when the load-button has been clicked
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
self.disable_all()
|
self.disable_all()
|
||||||
path = self.media_path_combobox.currentText()
|
path = self.media_path_combobox.currentText()
|
||||||
|
@ -134,12 +136,6 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
self.toggle_disable_load_media(False)
|
self.toggle_disable_load_media(False)
|
||||||
return
|
return
|
||||||
self.vlc_media_player.audio_set_mute(True)
|
self.vlc_media_player.audio_set_mute(True)
|
||||||
#while self.vlc_media_player.get_time() == 0:
|
|
||||||
# if self.vlc_media_player.get_state() == vlc.State.Error:
|
|
||||||
# log.debug('player in error state')
|
|
||||||
# self.toggle_disable_load_media(False)
|
|
||||||
# return
|
|
||||||
# time.sleep(0.1)
|
|
||||||
if not self.media_state_wait(vlc.State.Playing):
|
if not self.media_state_wait(vlc.State.Playing):
|
||||||
return
|
return
|
||||||
self.vlc_media_player.pause()
|
self.vlc_media_player.pause()
|
||||||
|
@ -163,6 +159,8 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_pause_pushbutton_clicked(self, clicked):
|
def on_pause_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Pause the playback
|
Pause the playback
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
self.vlc_media_player.pause()
|
self.vlc_media_player.pause()
|
||||||
|
|
||||||
|
@ -170,6 +168,8 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_play_pushbutton_clicked(self, clicked):
|
def on_play_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Start the playback
|
Start the playback
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
self.vlc_media_player.play()
|
self.vlc_media_player.play()
|
||||||
|
|
||||||
|
@ -177,26 +177,40 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_set_start_pushbutton_clicked(self, clicked):
|
def on_set_start_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Copy the current player position to start_timeedit
|
Copy the current player position to start_timeedit
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
vlc_ms_pos = self.vlc_media_player.get_time()
|
vlc_ms_pos = self.vlc_media_player.get_time()
|
||||||
time = QtCore.QTime()
|
time = QtCore.QTime()
|
||||||
new_pos_time = time.addMSecs(vlc_ms_pos)
|
new_pos_time = time.addMSecs(vlc_ms_pos)
|
||||||
self.start_timeedit.setTime(new_pos_time)
|
self.start_timeedit.setTime(new_pos_time)
|
||||||
|
# If start time is after end time, update end time.
|
||||||
|
end_time = self.end_timeedit.time()
|
||||||
|
if end_time < new_pos_time:
|
||||||
|
self.end_timeedit.setTime(new_pos_time)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(bool)
|
@QtCore.pyqtSlot(bool)
|
||||||
def on_set_end_pushbutton_clicked(self, clicked):
|
def on_set_end_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Copy the current player position to end_timeedit
|
Copy the current player position to end_timeedit
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
vlc_ms_pos = self.vlc_media_player.get_time()
|
vlc_ms_pos = self.vlc_media_player.get_time()
|
||||||
time = QtCore.QTime()
|
time = QtCore.QTime()
|
||||||
new_pos_time = time.addMSecs(vlc_ms_pos)
|
new_pos_time = time.addMSecs(vlc_ms_pos)
|
||||||
self.end_timeedit.setTime(new_pos_time)
|
self.end_timeedit.setTime(new_pos_time)
|
||||||
|
# If start time is after end time, update end time.
|
||||||
|
start_time = self.start_timeedit.time()
|
||||||
|
if start_time > new_pos_time:
|
||||||
|
self.start_timeedit.setTime(new_pos_time)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(bool)
|
@QtCore.pyqtSlot(bool)
|
||||||
def on_jump_end_pushbutton_clicked(self, clicked):
|
def on_jump_end_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Set the player position to the position stored in end_timeedit
|
Set the player position to the position stored in end_timeedit
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
end_time = self.end_timeedit.time()
|
end_time = self.end_timeedit.time()
|
||||||
end_time_ms = end_time.hour() * 60 * 60 * 1000 + \
|
end_time_ms = end_time.hour() * 60 * 60 * 1000 + \
|
||||||
|
@ -209,6 +223,8 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_jump_start_pushbutton_clicked(self, clicked):
|
def on_jump_start_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Set the player position to the position stored in start_timeedit
|
Set the player position to the position stored in start_timeedit
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
start_time = self.start_timeedit.time()
|
start_time = self.start_timeedit.time()
|
||||||
start_time_ms = start_time.hour() * 60 * 60 * 1000 + \
|
start_time_ms = start_time.hour() * 60 * 60 * 1000 + \
|
||||||
|
@ -221,17 +237,14 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_title_combo_box_currentIndexChanged(self, index):
|
def on_title_combo_box_currentIndexChanged(self, index):
|
||||||
"""
|
"""
|
||||||
When a new title is chosen, it is loaded by VLC and info about audio and subtitle tracks is reloaded
|
When a new title is chosen, it is loaded by VLC and info about audio and subtitle tracks is reloaded
|
||||||
|
|
||||||
|
:param index: The index of the newly chosen title track.
|
||||||
"""
|
"""
|
||||||
log.debug('in on_title_combo_box_changed, index: ', str(index))
|
log.debug('in on_title_combo_box_changed, index: ', str(index))
|
||||||
self.vlc_media_player.set_title(index)
|
self.vlc_media_player.set_title(index)
|
||||||
self.vlc_media_player.set_time(0)
|
self.vlc_media_player.set_time(0)
|
||||||
self.vlc_media_player.play()
|
self.vlc_media_player.play()
|
||||||
self.vlc_media_player.audio_set_mute(True)
|
self.vlc_media_player.audio_set_mute(True)
|
||||||
#while self.vlc_media_player.get_time() == 0:
|
|
||||||
# if self.vlc_media_player.get_state() == vlc.State.Error:
|
|
||||||
# log.debug('player in error state')
|
|
||||||
# return
|
|
||||||
# time.sleep(0.1)
|
|
||||||
if not self.media_state_wait(vlc.State.Playing):
|
if not self.media_state_wait(vlc.State.Playing):
|
||||||
return
|
return
|
||||||
# pause
|
# pause
|
||||||
|
@ -241,7 +254,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
audio_tracks = self.vlc_media_player.audio_get_track_description()
|
audio_tracks = self.vlc_media_player.audio_get_track_description()
|
||||||
self.audio_tracks_combobox.clear()
|
self.audio_tracks_combobox.clear()
|
||||||
for audio_track in audio_tracks:
|
for audio_track in audio_tracks:
|
||||||
self.audio_tracks_combobox.addItem(audio_track[1].decode(),audio_track[0])
|
self.audio_tracks_combobox.addItem(audio_track[1].decode(), audio_track[0])
|
||||||
# Enable audio track combobox if anything is in it
|
# Enable audio track combobox if anything is in it
|
||||||
if len(audio_tracks) > 0:
|
if len(audio_tracks) > 0:
|
||||||
self.audio_tracks_combobox.setDisabled(False)
|
self.audio_tracks_combobox.setDisabled(False)
|
||||||
|
@ -270,6 +283,8 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_audio_tracks_combobox_currentIndexChanged(self, index):
|
def on_audio_tracks_combobox_currentIndexChanged(self, index):
|
||||||
"""
|
"""
|
||||||
When a new audio track is chosen update audio track bing played by VLC
|
When a new audio track is chosen update audio track bing played by VLC
|
||||||
|
|
||||||
|
:param index: The index of the newly chosen audio track.
|
||||||
"""
|
"""
|
||||||
audio_track = self.audio_tracks_combobox.itemData(index)
|
audio_track = self.audio_tracks_combobox.itemData(index)
|
||||||
log.debug('in on_audio_tracks_combobox_currentIndexChanged, index: ', str(index), ' audio_track: ', audio_track)
|
log.debug('in on_audio_tracks_combobox_currentIndexChanged, index: ', str(index), ' audio_track: ', audio_track)
|
||||||
|
@ -280,15 +295,18 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
def on_subtitle_tracks_combobox_currentIndexChanged(self, index):
|
def on_subtitle_tracks_combobox_currentIndexChanged(self, index):
|
||||||
"""
|
"""
|
||||||
When a new subtitle track is chosen update subtitle track bing played by VLC
|
When a new subtitle track is chosen update subtitle track bing played by VLC
|
||||||
|
|
||||||
|
:param index: The index of the newly chosen subtitle.
|
||||||
"""
|
"""
|
||||||
subtitle_track = self.subtitle_tracks_combobox.itemData(index)
|
subtitle_track = self.subtitle_tracks_combobox.itemData(index)
|
||||||
log.debug('in on_subtitle_tracks_combobox_currentIndexChanged, index: ', str(index), ' subtitle_track: ', subtitle_track)
|
|
||||||
if subtitle_track:
|
if subtitle_track:
|
||||||
self.vlc_media_player.video_set_spu(int(subtitle_track))
|
self.vlc_media_player.video_set_spu(int(subtitle_track))
|
||||||
|
|
||||||
def on_position_horizontalslider_sliderMoved(self, position):
|
def on_position_horizontalslider_sliderMoved(self, position):
|
||||||
"""
|
"""
|
||||||
Set player position according to new slider position.
|
Set player position according to new slider position.
|
||||||
|
|
||||||
|
:param position: Position to seek to.
|
||||||
"""
|
"""
|
||||||
self.vlc_media_player.set_time(position)
|
self.vlc_media_player.set_time(position)
|
||||||
|
|
||||||
|
@ -318,16 +336,16 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
"""
|
"""
|
||||||
Enable/disable load media combobox and button.
|
Enable/disable load media combobox and button.
|
||||||
|
|
||||||
@param action: If True elements are disabled, if False they are enabled.
|
:param action: If True elements are disabled, if False they are enabled.
|
||||||
"""
|
"""
|
||||||
self.media_path_combobox.setDisabled(action)
|
self.media_path_combobox.setDisabled(action)
|
||||||
self.load_disc_pushbutton.setDisabled(action)
|
self.load_disc_pushbutton.setDisabled(action)
|
||||||
|
|
||||||
def toggle_disable_player(self, action):
|
def toggle_disable_player(self, action):
|
||||||
"""
|
"""
|
||||||
Enable/disable player elementa.
|
Enable/disable player elements.
|
||||||
|
|
||||||
@param action: If True elements are disabled, if False they are enabled.
|
:param action: If True elements are disabled, if False they are enabled.
|
||||||
"""
|
"""
|
||||||
self.play_pushbutton.setDisabled(action)
|
self.play_pushbutton.setDisabled(action)
|
||||||
self.pause_pushbutton.setDisabled(action)
|
self.pause_pushbutton.setDisabled(action)
|
||||||
|
@ -343,9 +361,11 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
self.save_pushbutton.setDisabled(action)
|
self.save_pushbutton.setDisabled(action)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(bool)
|
@QtCore.pyqtSlot(bool)
|
||||||
def on_save_pushbutton_clicked(self, checked):
|
def on_save_pushbutton_clicked(self, clicked):
|
||||||
"""
|
"""
|
||||||
Saves the current media and trackinfo as a clip to the mediamanager
|
Saves the current media and trackinfo as a clip to the mediamanager
|
||||||
|
|
||||||
|
:param clicked: Given from signal, not used.
|
||||||
"""
|
"""
|
||||||
log.debug('in on_save_pushbutton_clicked')
|
log.debug('in on_save_pushbutton_clicked')
|
||||||
start_time = self.start_timeedit.time()
|
start_time = self.start_timeedit.time()
|
||||||
|
@ -362,13 +382,17 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
||||||
audio_track = self.audio_tracks_combobox.itemData(self.audio_tracks_combobox.currentIndex())
|
audio_track = self.audio_tracks_combobox.itemData(self.audio_tracks_combobox.currentIndex())
|
||||||
subtitle_track = self.subtitle_tracks_combobox.itemData(self.subtitle_tracks_combobox.currentIndex())
|
subtitle_track = self.subtitle_tracks_combobox.itemData(self.subtitle_tracks_combobox.currentIndex())
|
||||||
path = self.media_path_combobox.currentText()
|
path = self.media_path_combobox.currentText()
|
||||||
optical = 'optical:' + str(title) + ':' + str(audio_track) + ':' + str(subtitle_track) + ':' + str(start_time_ms) + ':' + str(end_time_ms) + ':' + path
|
optical = 'optical:' + str(title) + ':' + str(audio_track) + ':' + str(subtitle_track) + ':' + str(
|
||||||
|
start_time_ms) + ':' + str(end_time_ms) + ':' + path
|
||||||
self.media_item.add_optical_clip(optical)
|
self.media_item.add_optical_clip(optical)
|
||||||
|
|
||||||
def media_state_wait(self, media_state):
|
def media_state_wait(self, media_state):
|
||||||
"""
|
"""
|
||||||
Wait for the video to change its state
|
Wait for the video to change its state
|
||||||
Wait no longer than 15 seconds. (loading an iso file needs a long time)
|
Wait no longer than 15 seconds. (loading an iso file needs a long time)
|
||||||
|
|
||||||
|
:param media_state: VLC media state to wait for.
|
||||||
|
:return: True if state was reached within 15 seconds, False if not or error occurred.
|
||||||
"""
|
"""
|
||||||
start = datetime.now()
|
start = datetime.now()
|
||||||
while not media_state == self.vlc_media.get_state():
|
while not media_state == self.vlc_media.get_state():
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from datetime import time
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, Servi
|
||||||
build_icon, check_item_selected
|
build_icon, check_item_selected
|
||||||
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
|
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
|
||||||
from openlp.core.ui import DisplayController, Display, DisplayControllerType
|
from openlp.core.ui import DisplayController, Display, DisplayControllerType
|
||||||
from openlp.core.ui.media import get_media_players, set_media_players
|
from openlp.core.ui.media import get_media_players, set_media_players, parse_optical_path
|
||||||
from openlp.core.utils import get_locale_key
|
from openlp.core.utils import get_locale_key
|
||||||
from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorForm
|
from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorForm
|
||||||
from openlp.core.ui.media.vlcplayer import VLC_AVAILABLE
|
from openlp.core.ui.media.vlcplayer import VLC_AVAILABLE
|
||||||
|
@ -47,9 +48,10 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
CLAPPERBOARD = ':/media/slidecontroller_multimedia.png'
|
CLAPPERBOARD = ':/media/slidecontroller_multimedia.png'
|
||||||
|
OPTICAL = ':/media/media_optical.png'
|
||||||
VIDEO_ICON = build_icon(':/media/media_video.png')
|
VIDEO_ICON = build_icon(':/media/media_video.png')
|
||||||
AUDIO_ICON = build_icon(':/media/media_audio.png')
|
AUDIO_ICON = build_icon(':/media/media_audio.png')
|
||||||
OPTICAL_ICON = build_icon(':/media/media_optical.png')
|
OPTICAL_ICON = build_icon(OPTICAL)
|
||||||
ERROR_ICON = build_icon(':/general/general_delete.png')
|
ERROR_ICON = build_icon(':/general/general_delete.png')
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,6 +91,10 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
self.list_view.activateDnD()
|
self.list_view.activateDnD()
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
|
"""
|
||||||
|
This method is called automatically to provide OpenLP with the opportunity to translate the ``MediaManagerItem``
|
||||||
|
to another language.
|
||||||
|
"""
|
||||||
self.on_new_prompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
self.on_new_prompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
||||||
self.replace_action.setText(UiStrings().ReplaceBG)
|
self.replace_action.setText(UiStrings().ReplaceBG)
|
||||||
self.replace_action.setToolTip(UiStrings().ReplaceLiveBG)
|
self.replace_action.setToolTip(UiStrings().ReplaceLiveBG)
|
||||||
|
@ -108,16 +114,25 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
self.has_edit_icon = False
|
self.has_edit_icon = False
|
||||||
|
|
||||||
def add_list_view_to_toolbar(self):
|
def add_list_view_to_toolbar(self):
|
||||||
|
"""
|
||||||
|
Creates the main widget for listing items.
|
||||||
|
"""
|
||||||
MediaManagerItem.add_list_view_to_toolbar(self)
|
MediaManagerItem.add_list_view_to_toolbar(self)
|
||||||
self.list_view.addAction(self.replace_action)
|
self.list_view.addAction(self.replace_action)
|
||||||
|
|
||||||
def add_start_header_bar(self):
|
def add_start_header_bar(self):
|
||||||
|
"""
|
||||||
|
Adds buttons to the start of the header bar.
|
||||||
|
"""
|
||||||
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=OPTICAL_ICON, text='Load optical disc',
|
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=OPTICAL_ICON, text='Load optical disc',
|
||||||
tooltip='Load optical disc', triggers=self.on_load_optical)
|
tooltip='Load optical disc', triggers=self.on_load_optical)
|
||||||
if not VLC_AVAILABLE:
|
if not VLC_AVAILABLE:
|
||||||
self.load_optical.setDisabled(True)
|
self.load_optical.setDisabled(True)
|
||||||
|
|
||||||
def add_end_header_bar(self):
|
def add_end_header_bar(self):
|
||||||
|
"""
|
||||||
|
Adds buttons to the end of the header bar.
|
||||||
|
"""
|
||||||
# Replace backgrounds do not work at present so remove functionality.
|
# Replace backgrounds do not work at present so remove functionality.
|
||||||
self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=':/slides/slide_blank.png',
|
self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=':/slides/slide_blank.png',
|
||||||
triggers=self.on_replace_click)
|
triggers=self.on_replace_click)
|
||||||
|
@ -139,6 +154,11 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
self.display_type_combo_box.currentIndexChanged.connect(self.override_player_changed)
|
self.display_type_combo_box.currentIndexChanged.connect(self.override_player_changed)
|
||||||
|
|
||||||
def override_player_changed(self, index):
|
def override_player_changed(self, index):
|
||||||
|
"""
|
||||||
|
Change to the selected override media player
|
||||||
|
|
||||||
|
:param index: Index of the new selected player.
|
||||||
|
"""
|
||||||
player = get_media_players()[0]
|
player = get_media_players()[0]
|
||||||
if index == 0:
|
if index == 0:
|
||||||
set_media_players(player)
|
set_media_players(player)
|
||||||
|
@ -163,7 +183,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
Called to replace Live background with the media selected.
|
Called to replace Live background with the media selected.
|
||||||
"""
|
"""
|
||||||
if check_item_selected(self.list_view,
|
if check_item_selected(self.list_view,
|
||||||
translate('MediaPlugin.MediaItem',
|
translate('MediaPlugin.MediaItem',
|
||||||
'You must select a media file to replace the background with.')):
|
'You must select a media file to replace the background with.')):
|
||||||
item = self.list_view.currentItem()
|
item = self.list_view.currentItem()
|
||||||
filename = item.data(QtCore.Qt.UserRole)
|
filename = item.data(QtCore.Qt.UserRole)
|
||||||
|
@ -172,12 +192,12 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
service_item.title = 'webkit'
|
service_item.title = 'webkit'
|
||||||
service_item.processor = 'webkit'
|
service_item.processor = 'webkit'
|
||||||
(path, name) = os.path.split(filename)
|
(path, name) = os.path.split(filename)
|
||||||
service_item.add_from_command(path, name,CLAPPERBOARD)
|
service_item.add_from_command(path, name, CLAPPERBOARD)
|
||||||
if self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True):
|
if self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True):
|
||||||
self.reset_action.setVisible(True)
|
self.reset_action.setVisible(True)
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(UiStrings().LiveBGError,
|
critical_error_message_box(UiStrings().LiveBGError,
|
||||||
translate('MediaPlugin.MediaItem',
|
translate('MediaPlugin.MediaItem',
|
||||||
'There was no display item to amend.'))
|
'There was no display item to amend.'))
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(UiStrings().LiveBGError,
|
critical_error_message_box(UiStrings().LiveBGError,
|
||||||
|
@ -195,10 +215,9 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
if item is None:
|
if item is None:
|
||||||
return False
|
return False
|
||||||
filename = item.data(QtCore.Qt.UserRole)
|
filename = item.data(QtCore.Qt.UserRole)
|
||||||
log.debug('generate_slide_data, filename: ' + filename)
|
# Special handling if the filename is a optical clip
|
||||||
if filename.startswith('optical:'):
|
if filename.startswith('optical:'):
|
||||||
(name, title, audio_track, subtitle_track, start, end) = self.parse_optical_path(filename)
|
(name, title, audio_track, subtitle_track, start, end) = parse_optical_path(filename)
|
||||||
log.debug('generate_slide_data, optical name: ' + name)
|
|
||||||
if not os.path.exists(name):
|
if not os.path.exists(name):
|
||||||
if not remote:
|
if not remote:
|
||||||
# Optical disc is no longer present
|
# Optical disc is no longer present
|
||||||
|
@ -206,16 +225,16 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
||||||
translate('MediaPlugin.MediaItem', 'The optical disc %s is no longer available.') % name)
|
translate('MediaPlugin.MediaItem', 'The optical disc %s is no longer available.') % name)
|
||||||
return False
|
return False
|
||||||
service_item.title = name
|
|
||||||
service_item.processor = self.display_type_combo_box.currentText()
|
service_item.processor = self.display_type_combo_box.currentText()
|
||||||
service_item.add_from_command(filename, name, OPTICAL_ICON)
|
service_item.add_from_command(filename, name, CLAPPERBOARD)
|
||||||
|
service_item.title = name + '@' + self.format_milliseconds(start) + '-' + self.format_milliseconds(end)
|
||||||
# Only set start and end times if going to a service
|
# Only set start and end times if going to a service
|
||||||
#if context == ServiceItemContext.Service:
|
#if context == ServiceItemContext.Service:
|
||||||
# Set the length
|
# Set the length
|
||||||
self.media_controller.media_setup_optical(name, title, audio_track, subtitle_track, start, end, None, None)
|
self.media_controller.media_setup_optical(name, title, audio_track, subtitle_track, start, end, None, None)
|
||||||
service_item.set_media_length((end - start)/1000)
|
service_item.set_media_length((end - start) / 1000)
|
||||||
service_item.start_time = start/1000
|
service_item.start_time = start / 1000
|
||||||
service_item.end_time = end/1000
|
service_item.end_time = end / 1000
|
||||||
service_item.add_capability(ItemCapabilities.IsOptical)
|
service_item.add_capability(ItemCapabilities.IsOptical)
|
||||||
else:
|
else:
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
|
@ -243,12 +262,15 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
|
"""
|
||||||
|
Initialize media item.
|
||||||
|
"""
|
||||||
self.list_view.clear()
|
self.list_view.clear()
|
||||||
self.list_view.setIconSize(QtCore.QSize(88, 50))
|
self.list_view.setIconSize(QtCore.QSize(88, 50))
|
||||||
self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
|
self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
|
||||||
check_directory_exists(self.service_path)
|
check_directory_exists(self.service_path)
|
||||||
self.load_list(Settings().value(self.settings_section + '/media files'))
|
self.load_list(Settings().value(self.settings_section + '/media files'))
|
||||||
self.populate_display_types()
|
self.rebuild_players()
|
||||||
self.media_clip_selector_form = MediaClipSelectorForm(self, self.main_window, None)
|
self.media_clip_selector_form = MediaClipSelectorForm(self, self.main_window, None)
|
||||||
|
|
||||||
def rebuild_players(self):
|
def rebuild_players(self):
|
||||||
|
@ -261,6 +283,9 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
|
' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
|
||||||
|
|
||||||
def display_setup(self):
|
def display_setup(self):
|
||||||
|
"""
|
||||||
|
Setup media controller display.
|
||||||
|
"""
|
||||||
self.media_controller.setup_display(self.display_controller.preview_display, False)
|
self.media_controller.setup_display(self.display_controller.preview_display, False)
|
||||||
|
|
||||||
def populate_display_types(self):
|
def populate_display_types(self):
|
||||||
|
@ -300,24 +325,32 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
Settings().setValue(self.settings_section + '/media files', self.get_file_list())
|
Settings().setValue(self.settings_section + '/media files', self.get_file_list())
|
||||||
|
|
||||||
def load_list(self, media, target_group=None):
|
def load_list(self, media, target_group=None):
|
||||||
# Sort the media by its filename considering language specific characters.
|
"""
|
||||||
|
Sort the media by its filename considering language specific characters.
|
||||||
|
|
||||||
|
:param media: List if media to sort and list.
|
||||||
|
:param target_group: Not used in media.
|
||||||
|
"""
|
||||||
media.sort(key=lambda file_name: get_locale_key(os.path.split(str(file_name))[1]))
|
media.sort(key=lambda file_name: get_locale_key(os.path.split(str(file_name))[1]))
|
||||||
for track in media:
|
for track in media:
|
||||||
track_info = QtCore.QFileInfo(track)
|
track_info = QtCore.QFileInfo(track)
|
||||||
if track.startswith('optical:'):
|
if track.startswith('optical:'):
|
||||||
(file_name, title, audio_track, subtitle_track, start, end) = self.parse_optical_path(track)
|
# Handle optical based item
|
||||||
optical = file_name + '@' + str(title) + ':' + str(start) + '-' + str(end)
|
(file_name, title, audio_track, subtitle_track, start, end) = parse_optical_path(track)
|
||||||
|
optical = file_name + '@' + self.format_milliseconds(start) + '-' + self.format_milliseconds(end)
|
||||||
item_name = QtGui.QListWidgetItem(optical)
|
item_name = QtGui.QListWidgetItem(optical)
|
||||||
item_name.setIcon(build_icon(OPTICAL_ICON))
|
item_name.setIcon(OPTICAL_ICON)
|
||||||
item_name.setData(QtCore.Qt.UserRole, track)
|
item_name.setData(QtCore.Qt.UserRole, track)
|
||||||
item_name.setToolTip(optical)
|
item_name.setToolTip(optical)
|
||||||
elif not os.path.exists(track):
|
elif not os.path.exists(track):
|
||||||
|
# File doesn't exist, mark as error.
|
||||||
file_name = os.path.split(str(track))[1]
|
file_name = os.path.split(str(track))[1]
|
||||||
item_name = QtGui.QListWidgetItem(file_name)
|
item_name = QtGui.QListWidgetItem(file_name)
|
||||||
item_name.setIcon(ERROR_ICON)
|
item_name.setIcon(ERROR_ICON)
|
||||||
item_name.setData(QtCore.Qt.UserRole, track)
|
item_name.setData(QtCore.Qt.UserRole, track)
|
||||||
item_name.setToolTip(track)
|
item_name.setToolTip(track)
|
||||||
elif track_info.isFile():
|
elif track_info.isFile():
|
||||||
|
# Normal media file handling.
|
||||||
file_name = os.path.split(str(track))[1]
|
file_name = os.path.split(str(track))[1]
|
||||||
item_name = QtGui.QListWidgetItem(file_name)
|
item_name = QtGui.QListWidgetItem(file_name)
|
||||||
if '*.%s' % (file_name.split('.')[-1].lower()) in self.media_controller.audio_extensions_list:
|
if '*.%s' % (file_name.split('.')[-1].lower()) in self.media_controller.audio_extensions_list:
|
||||||
|
@ -329,6 +362,12 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
self.list_view.addItem(item_name)
|
self.list_view.addItem(item_name)
|
||||||
|
|
||||||
def get_list(self, type=MediaType.Audio):
|
def get_list(self, type=MediaType.Audio):
|
||||||
|
"""
|
||||||
|
Get the list of media, optional select media type.
|
||||||
|
|
||||||
|
:param type: Type to get, defaults to audio.
|
||||||
|
:return: The media list
|
||||||
|
"""
|
||||||
media = Settings().value(self.settings_section + '/media files')
|
media = Settings().value(self.settings_section + '/media files')
|
||||||
media.sort(key=lambda filename: get_locale_key(os.path.split(str(filename))[1]))
|
media.sort(key=lambda filename: get_locale_key(os.path.split(str(filename))[1]))
|
||||||
extension = []
|
extension = []
|
||||||
|
@ -341,6 +380,13 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
return media
|
return media
|
||||||
|
|
||||||
def search(self, string, show_error):
|
def search(self, string, show_error):
|
||||||
|
"""
|
||||||
|
Performs a search for items containing ``string``
|
||||||
|
|
||||||
|
:param string: String to be displayed
|
||||||
|
:param show_error: Should the error be shown (True)
|
||||||
|
:return: The search result.
|
||||||
|
"""
|
||||||
files = Settings().value(self.settings_section + '/media files')
|
files = Settings().value(self.settings_section + '/media files')
|
||||||
results = []
|
results = []
|
||||||
string = string.lower()
|
string = string.lower()
|
||||||
|
@ -351,25 +397,29 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def on_load_optical(self):
|
def on_load_optical(self):
|
||||||
log.debug('in on_load_optical')
|
"""
|
||||||
|
When the load optical button is clicked, open the clip selector window.
|
||||||
|
"""
|
||||||
self.media_clip_selector_form.exec_()
|
self.media_clip_selector_form.exec_()
|
||||||
|
|
||||||
def add_optical_clip(self, optical):
|
def add_optical_clip(self, optical):
|
||||||
|
"""
|
||||||
|
Add a optical based clip to the mediamanager, called from media_clip_selector_form.
|
||||||
|
|
||||||
|
:param optical: The clip to add.
|
||||||
|
"""
|
||||||
full_list = self.get_file_list()
|
full_list = self.get_file_list()
|
||||||
full_list.append(optical)
|
full_list.append(optical)
|
||||||
self.load_list([optical])
|
self.load_list([optical])
|
||||||
Settings().setValue(self.settings_section + '/media files', self.get_file_list())
|
Settings().setValue(self.settings_section + '/media files', self.get_file_list())
|
||||||
|
|
||||||
@staticmethod
|
def format_milliseconds(self, milliseconds):
|
||||||
def parse_optical_path(input):
|
"""
|
||||||
# split the clip info
|
Format milliseconds into a human readable time string.
|
||||||
clip_info = input.split(sep=':')
|
:param milliseconds: Milliseconds to format
|
||||||
title = int(clip_info[1])
|
:return: Time string in format: hh.mm.ss,ttt
|
||||||
audio_track = int(clip_info[2])
|
"""
|
||||||
subtitle_track = int(clip_info[3])
|
seconds, millis = divmod(milliseconds, 1000)
|
||||||
start = float(clip_info[4])
|
minutes, seconds = divmod(millis, 60)
|
||||||
end = float(clip_info[5])
|
hours, minutes = divmod(minutes, 60)
|
||||||
filename = clip_info[6]
|
return "%02d:%02d:%02d,%03d" % (hours, minutes, seconds, millis)
|
||||||
if len(clip_info) > 7:
|
|
||||||
filename += clip_info[7]
|
|
||||||
return filename, title, audio_track, subtitle_track, start, end
|
|
||||||
|
|
Loading…
Reference in New Issue