mirror of https://gitlab.com/openlp/openlp.git
Implemented DVD clip selection and playback, still needs a lot of cleanups.
This commit is contained in:
parent
6d21a326ed
commit
67acb9d824
|
@ -108,6 +108,8 @@ class ItemCapabilities(object):
|
|||
``CanAutoStartForLive``
|
||||
The capability to ignore the do not play if display blank flag.
|
||||
|
||||
``IsOptical``
|
||||
.Determines is the service_item is based on an optical device
|
||||
"""
|
||||
CanPreview = 1
|
||||
CanEdit = 2
|
||||
|
@ -125,6 +127,7 @@ class ItemCapabilities(object):
|
|||
CanWordSplit = 14
|
||||
HasBackgroundAudio = 15
|
||||
CanAutoStartForLive = 16
|
||||
IsOptical = 17
|
||||
|
||||
|
||||
class ServiceItem(object):
|
||||
|
@ -573,7 +576,7 @@ class ServiceItem(object):
|
|||
frame = self._raw_frames[row]
|
||||
except IndexError:
|
||||
return ''
|
||||
if self.is_image():
|
||||
if self.is_image() or self.is_capable(ItemCapabilities.IsOptical):
|
||||
path_from = frame['path']
|
||||
else:
|
||||
path_from = os.path.join(frame['path'], frame['title'])
|
||||
|
|
|
@ -72,6 +72,9 @@ class MediaInfo(object):
|
|||
length = 0
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
title_track = 0
|
||||
audio_track = 0
|
||||
subtitle_track = 0
|
||||
media_type = MediaType()
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ import datetime
|
|||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.common import Registry, Settings, UiStrings, translate
|
||||
from openlp.core.lib import OpenLPToolbar
|
||||
from openlp.core.lib import OpenLPToolbar, ItemCapabilities
|
||||
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.mediaplayer import MediaPlayer
|
||||
|
@ -387,6 +387,14 @@ class MediaController(object):
|
|||
controller.media_info.file_info = QtCore.QFileInfo(service_item.get_frame_path())
|
||||
display = self._define_display(controller)
|
||||
if controller.is_live:
|
||||
# if this is an optical device use special handling
|
||||
if service_item.is_capable(ItemCapabilities.IsOptical):
|
||||
log.debug('video is optical and live')
|
||||
path = service_item.get_frame_path()
|
||||
(name, title, audio_track, subtitle_track, start, end) = self.parse_optical_path(path)
|
||||
is_valid = self.media_setup_optical(name, title, audio_track, subtitle_track, start, end, display, controller)
|
||||
else :
|
||||
log.debug('video is not optical and live')
|
||||
is_valid = self._check_file_type(controller, display, service_item)
|
||||
display.override['theme'] = ''
|
||||
display.override['video'] = True
|
||||
|
@ -398,12 +406,20 @@ class MediaController(object):
|
|||
controller.media_info.start_time = service_item.start_time
|
||||
controller.media_info.end_time = service_item.end_time
|
||||
elif controller.preview_display:
|
||||
if service_item.is_capable(ItemCapabilities.IsOptical):
|
||||
log.debug('video is optical and preview')
|
||||
path = service_item.get_frame_path()
|
||||
(name, title, audio_track, subtitle_track, start, end) = self.parse_optical_path(path)
|
||||
is_valid = self.media_setup_optical(name, title, audio_track, subtitle_track, start, end, display, controller)
|
||||
else :
|
||||
log.debug('video is not optical and preview')
|
||||
is_valid = self._check_file_type(controller, display, service_item)
|
||||
if not is_valid:
|
||||
# Media could not be loaded correctly
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
return False
|
||||
log.debug('video mediatype: ' +str(controller.media_info.media_type))
|
||||
# dont care about actual theme, set a black background
|
||||
if controller.is_live and not controller.media_info.is_background:
|
||||
display.frame.evaluateJavaScript('show_video( "setBackBoard", null, null, null,"visible");')
|
||||
|
@ -456,6 +472,44 @@ class MediaController(object):
|
|||
log.debug('use %s controller' % self.current_media_players[controller.controller_type])
|
||||
return True
|
||||
|
||||
def media_setup_optical(self, filename, title, audio_track, subtitle_track, start, end, display, controller):
|
||||
log.debug('media_setup_optical')
|
||||
if controller is None:
|
||||
controller = self.display_controllers[DisplayControllerType.Plugin]
|
||||
# stop running videos
|
||||
self.media_reset(controller)
|
||||
# Setup media info
|
||||
controller.media_info = MediaInfo()
|
||||
#controller.media_info.volume = 0
|
||||
controller.media_info.file_info = QtCore.QFileInfo(filename)
|
||||
controller.media_info.media_type = MediaType.DVD
|
||||
controller.media_info.start_time = start/1000
|
||||
controller.media_info.end_time = end/1000
|
||||
controller.media_info.length = (end - start)/1000
|
||||
controller.media_info.title_track = title
|
||||
controller.media_info.audio_track = audio_track
|
||||
controller.media_info.subtitle_track = subtitle_track
|
||||
# When called from mediaitem display is None
|
||||
if display is None:
|
||||
display = controller.preview_display
|
||||
# Find vlc player
|
||||
used_players = get_media_players()[0]
|
||||
vlc_player = None
|
||||
for title in used_players:
|
||||
player = self.media_players[title]
|
||||
if player.name == 'vlc':
|
||||
vlc_player = player
|
||||
if vlc_player is None:
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'VLC player required'),
|
||||
translate('MediaPlugin.MediaItem', 'VLC player required for playback of optical devices'))
|
||||
return False
|
||||
vlc_player.load(display)
|
||||
self.resize(display, vlc_player)
|
||||
self.current_media_players[controller.controller_type] = vlc_player
|
||||
controller.media_info.media_type = MediaType.DVD
|
||||
return True
|
||||
|
||||
|
||||
def _check_file_type(self, controller, display, service_item):
|
||||
"""
|
||||
Select the correct media Player type from the prioritized Player list
|
||||
|
@ -758,3 +812,17 @@ class MediaController(object):
|
|||
return self._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
|
||||
|
|
|
@ -39,7 +39,7 @@ from PyQt4 import QtGui
|
|||
|
||||
from openlp.core.common import Settings
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.ui.media import MediaState
|
||||
from openlp.core.ui.media import MediaState, MediaType
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -205,14 +205,35 @@ class VlcPlayer(MediaPlayer):
|
|||
"""
|
||||
controller = display.controller
|
||||
start_time = 0
|
||||
if self.state != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
start_time = controller.media_info.start_time
|
||||
log.debug('vlc play')
|
||||
display.vlcMediaPlayer.play()
|
||||
if not self.media_state_wait(display, vlc.State.Playing):
|
||||
return False
|
||||
if self.state != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
log.debug('vlc play, starttime set')
|
||||
start_time = controller.media_info.start_time
|
||||
log.debug('mediatype: ' +str(controller.media_info.media_type))
|
||||
# Set tracks for the optical device
|
||||
if controller.media_info.media_type == MediaType.DVD:
|
||||
log.debug('vlc play, playing started')
|
||||
if controller.media_info.title_track > 0:
|
||||
log.debug('vlc play, title_track set: ' + str(controller.media_info.title_track))
|
||||
display.vlcMediaPlayer.set_title(controller.media_info.title_track)
|
||||
display.vlcMediaPlayer.play()
|
||||
if not self.media_state_wait(display, vlc.State.Playing):
|
||||
return False
|
||||
if controller.media_info.audio_track > 0:
|
||||
display.vlcMediaPlayer.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:
|
||||
display.vlcMediaPlayer.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
|
||||
self.volume(display, controller.media_info.volume)
|
||||
if start_time > 0:
|
||||
self.seek(display, controller.media_info.start_time * 1000)
|
||||
self.seek(display, int(start_time * 1000))
|
||||
controller.media_info.length = int(display.vlcMediaPlayer.get_media().get_duration() / 1000)
|
||||
controller.seek_slider.setMaximum(controller.media_info.length * 1000)
|
||||
self.state = MediaState.Playing
|
||||
|
@ -248,6 +269,7 @@ class VlcPlayer(MediaPlayer):
|
|||
Go to a particular position
|
||||
"""
|
||||
if display.vlcMediaPlayer.is_seekable():
|
||||
log.debug('vlc seek to: ' + str(seek_value))
|
||||
display.vlcMediaPlayer.set_time(seek_value)
|
||||
|
||||
def reset(self, display):
|
||||
|
|
|
@ -31,6 +31,8 @@ import os
|
|||
import sys
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
@ -132,12 +134,14 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
|||
self.toggle_disable_load_media(False)
|
||||
return
|
||||
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)
|
||||
#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):
|
||||
return
|
||||
time.sleep(0.1)
|
||||
self.vlc_media_player.pause()
|
||||
self.vlc_media_player.set_time(0)
|
||||
# Get titles, insert in combobox
|
||||
|
@ -223,11 +227,13 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
|||
self.vlc_media_player.set_time(0)
|
||||
self.vlc_media_player.play()
|
||||
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')
|
||||
#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):
|
||||
return
|
||||
time.sleep(0.1)
|
||||
# pause
|
||||
self.vlc_media_player.pause()
|
||||
self.vlc_media_player.set_time(0)
|
||||
|
@ -358,3 +364,16 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
|
|||
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
|
||||
self.media_item.add_optical_clip(optical)
|
||||
|
||||
def media_state_wait(self, media_state):
|
||||
"""
|
||||
Wait for the video to change its state
|
||||
Wait no longer than 15 seconds. (loading an iso file needs a long time)
|
||||
"""
|
||||
start = datetime.now()
|
||||
while not media_state == self.vlc_media.get_state():
|
||||
if self.vlc_media.get_state() == vlc.State.Error:
|
||||
return False
|
||||
if (datetime.now() - start).seconds > 15:
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -43,7 +43,6 @@ from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorFo
|
|||
from openlp.core.ui.media.vlcplayer import VLC_AVAILABLE
|
||||
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -193,6 +192,29 @@ class MediaMediaItem(MediaManagerItem):
|
|||
if item is None:
|
||||
return False
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
log.debug('generate_slide_data, filename: ' + filename)
|
||||
if filename.startswith('optical:'):
|
||||
(name, title, audio_track, subtitle_track, start, end) = self.parse_optical_path(filename)
|
||||
log.debug('generate_slide_data, optical name: ' + name)
|
||||
if not os.path.exists(name):
|
||||
if not remote:
|
||||
# Optical disc is no longer present
|
||||
critical_error_message_box(
|
||||
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
||||
translate('MediaPlugin.MediaItem', 'The optical disc %s is no longer available.') % name)
|
||||
return False
|
||||
service_item.title = name
|
||||
service_item.processor = self.display_type_combo_box.currentText()
|
||||
service_item.add_from_command(filename, name, OPTICAL_ICON)
|
||||
# Only set start and end times if going to a service
|
||||
#if context == ServiceItemContext.Service:
|
||||
# Set the length
|
||||
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.start_time = start/1000
|
||||
service_item.end_time = end/1000
|
||||
service_item.add_capability(ItemCapabilities.IsOptical)
|
||||
else:
|
||||
if not os.path.exists(filename):
|
||||
if not remote:
|
||||
# File is no longer present
|
||||
|
@ -329,7 +351,14 @@ class MediaMediaItem(MediaManagerItem):
|
|||
log.debug('in on_load_optical')
|
||||
self.media_clip_selector_form.exec_()
|
||||
|
||||
def parse_optical_path(self, input):
|
||||
def add_optical_clip(self, optical):
|
||||
full_list = self.get_file_list()
|
||||
full_list.append(optical)
|
||||
self.load_list([optical])
|
||||
Settings().setValue(self.settings_section + '/media files', self.get_file_list())
|
||||
|
||||
@staticmethod
|
||||
def parse_optical_path(input):
|
||||
# split the clip info
|
||||
clip_info = input.split(sep=':')
|
||||
title = int(clip_info[1])
|
||||
|
@ -341,9 +370,3 @@ class MediaMediaItem(MediaManagerItem):
|
|||
if len(clip_info) > 7:
|
||||
filename += clip_info[7]
|
||||
return filename, title, audio_track, subtitle_track, start, end
|
||||
|
||||
def add_optical_clip(self, optical):
|
||||
full_list = self.get_file_list()
|
||||
full_list.append(optical)
|
||||
self.load_list([optical])
|
||||
Settings().setValue(self.settings_section + '/media files', self.get_file_list())
|
||||
|
|
Loading…
Reference in New Issue