forked from openlp/openlp
new start
This commit is contained in:
commit
ea40173f9b
@ -542,6 +542,7 @@ class ServiceItem(RegistryProperties):
|
||||
|
||||
:param length: The length of the media item
|
||||
"""
|
||||
print("set_media_length " + str(length) + " " + self.processor)
|
||||
self.media_length = length
|
||||
if length > 0:
|
||||
self.add_capability(ItemCapabilities.HasVariableStartTime)
|
||||
@ -610,7 +611,8 @@ class ServiceItem(RegistryProperties):
|
||||
str(datetime.timedelta(seconds=self.start_time))
|
||||
if self.media_length != 0:
|
||||
end = translate('OpenLP.ServiceItem', '<strong>Length</strong>: %s') % \
|
||||
str(datetime.timedelta(seconds=self.media_length))
|
||||
str(datetime.timedelta(seconds=self.media_length // 1000))
|
||||
print("get_media_time " + str(self.media_length))
|
||||
if not start and not end:
|
||||
return ''
|
||||
elif start and not end:
|
||||
|
@ -66,6 +66,8 @@ class MediaInfo(object):
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
title_track = 0
|
||||
playing = False
|
||||
timer = 1000
|
||||
audio_track = 0
|
||||
subtitle_track = 0
|
||||
media_type = MediaType()
|
||||
|
@ -33,12 +33,15 @@ 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,\
|
||||
parse_optical_path
|
||||
from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
from openlp.core.common import AppLocation
|
||||
from openlp.core.ui import DisplayControllerType
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
TICK_TIME = 200
|
||||
|
||||
|
||||
class MediaSlider(QtWidgets.QSlider):
|
||||
"""
|
||||
@ -97,7 +100,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
self.current_media_players = {}
|
||||
# Timer for video state
|
||||
self.timer = QtCore.QTimer()
|
||||
self.timer.setInterval(200)
|
||||
self.timer.setInterval(TICK_TIME)
|
||||
# Signals
|
||||
self.timer.timeout.connect(self.media_state)
|
||||
Registry().register_function('playbackPlay', self.media_play_msg)
|
||||
@ -202,6 +205,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
self.current_media_players[source].update_ui(display)
|
||||
if self.current_media_players[source].state == MediaState.Playing:
|
||||
any_active = True
|
||||
self.tick(self.display_controllers[source])
|
||||
# There are still any active players - no need to stop timer.
|
||||
if any_active:
|
||||
return
|
||||
@ -274,6 +278,11 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
icon=':/slides/media_playback_stop.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
controller.position_label = QtWidgets.QLabel()
|
||||
controller.position_label.setText(' 00:00 / 00:00')
|
||||
controller.position_label.setToolTip(translate('OpenLP.SlideController', 'Video timer.'))
|
||||
controller.position_label.setObjectName('position_label')
|
||||
controller.mediabar.add_toolbar_widget(controller.position_label)
|
||||
# Build the seek_slider.
|
||||
controller.seek_slider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
|
||||
controller.seek_slider.setMaximum(1000)
|
||||
@ -353,9 +362,10 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
:param hidden: The player which is doing the playing
|
||||
:param video_behind_text: Is the video to be played behind text.
|
||||
"""
|
||||
log.debug('video')
|
||||
print("### video", source)
|
||||
is_valid = False
|
||||
controller = self.display_controllers[source]
|
||||
print(controller)
|
||||
# stop running videos
|
||||
self.media_reset(controller)
|
||||
controller.media_info = MediaInfo()
|
||||
@ -373,6 +383,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
controller)
|
||||
else:
|
||||
log.debug('video is not optical and live')
|
||||
controller.media_info.length = service_item.media_length
|
||||
is_valid = self._check_file_type(controller, display, service_item)
|
||||
display.override['theme'] = ''
|
||||
display.override['video'] = True
|
||||
@ -392,6 +403,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
controller)
|
||||
else:
|
||||
log.debug('video is not optical and preview')
|
||||
controller.media_info.length = service_item.media_length
|
||||
is_valid = self._check_file_type(controller, display, service_item)
|
||||
if not is_valid:
|
||||
# Media could not be loaded correctly
|
||||
@ -428,8 +440,9 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
|
||||
:param service_item: The ServiceItem containing the details to be played.
|
||||
"""
|
||||
print('### media_length')
|
||||
controller = self.display_controllers[DisplayControllerType.Plugin]
|
||||
log.debug('media_length')
|
||||
print(controller)
|
||||
# stop running videos
|
||||
self.media_reset(controller)
|
||||
controller.media_info = MediaInfo()
|
||||
@ -441,12 +454,10 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
return False
|
||||
if not self.media_play(controller):
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
return False
|
||||
service_item.set_media_length(controller.media_info.length)
|
||||
self.media_stop(controller)
|
||||
media_data = MediaInfoWrapper.parse(service_item.get_frame_path())
|
||||
print(media_data.to_data())
|
||||
# duration returns in milli seconds
|
||||
service_item.set_media_length(media_data.tracks[0].duration)
|
||||
log.debug('use %s controller' % self.current_media_players[controller.controller_type])
|
||||
return True
|
||||
|
||||
@ -464,7 +475,6 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
:param controller: The media contraoller.
|
||||
:return: True if setup succeded else False.
|
||||
"""
|
||||
log.debug('media_setup_optical')
|
||||
if controller is None:
|
||||
controller = self.display_controllers[DisplayControllerType.Plugin]
|
||||
# stop running videos
|
||||
@ -573,7 +583,6 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
:param msg: First element is the controller which should be used
|
||||
:param status:
|
||||
"""
|
||||
log.debug('media_play_msg')
|
||||
self.media_play(msg[0], status)
|
||||
|
||||
def media_play(self, controller, status=True):
|
||||
@ -583,7 +592,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
:param controller: The controller to be played
|
||||
:param status:
|
||||
"""
|
||||
log.debug('media_play')
|
||||
print('### media_play')
|
||||
controller.seek_slider.blockSignals(True)
|
||||
controller.volume_slider.blockSignals(True)
|
||||
display = self._define_display(controller)
|
||||
@ -615,6 +624,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
self.timer.start()
|
||||
controller.seek_slider.blockSignals(False)
|
||||
controller.volume_slider.blockSignals(False)
|
||||
controller.media_info.playing = True
|
||||
return True
|
||||
|
||||
def media_pause_msg(self, msg):
|
||||
@ -623,21 +633,43 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
|
||||
:param msg: First element is the controller which should be used
|
||||
"""
|
||||
log.debug('media_pause_msg')
|
||||
self.media_pause(msg[0])
|
||||
|
||||
def tick(self, controller):
|
||||
"""
|
||||
Add a tick while the media is playing but only count if not paused
|
||||
|
||||
:param controller: The Controller to be processed
|
||||
"""
|
||||
if controller.media_info.playing and controller.media_info.length > 0:
|
||||
print("tick", controller.media_info.timer, controller.media_info.length)
|
||||
if controller.media_info.timer > controller.media_info.length:
|
||||
controller.media_info.timer = controller.media_info.length
|
||||
controller.media_info.timer = controller.media_info.length
|
||||
self.media_stop(controller)
|
||||
controller.media_info.timer += TICK_TIME
|
||||
seconds = controller.media_info.timer // 1000
|
||||
minutes = seconds // 60
|
||||
seconds %= 60
|
||||
total_seconds = controller.media_info.length
|
||||
total_minutes = total_seconds // 60
|
||||
total_seconds %= 60
|
||||
controller.position_label.setText(' %02d:%02d / %02d:%02d' %
|
||||
(minutes, seconds, total_minutes, total_seconds))
|
||||
|
||||
def media_pause(self, controller):
|
||||
"""
|
||||
Responds to the request to pause a loaded video
|
||||
|
||||
:param controller: The Controller to be paused
|
||||
"""
|
||||
log.debug('media_pause')
|
||||
print('### media_pause')
|
||||
display = self._define_display(controller)
|
||||
self.current_media_players[controller.controller_type].pause(display)
|
||||
controller.mediabar.actions['playbackPlay'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setDisabled(False)
|
||||
controller.mediabar.actions['playbackPause'].setVisible(False)
|
||||
controller.media_info.playing = False
|
||||
|
||||
def media_stop_msg(self, msg):
|
||||
"""
|
||||
@ -645,7 +677,6 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
|
||||
:param msg: First element is the controller which should be used
|
||||
"""
|
||||
log.debug('media_stop_msg')
|
||||
self.media_stop(msg[0])
|
||||
|
||||
def media_stop(self, controller):
|
||||
@ -654,7 +685,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
|
||||
:param controller: The controller that needs to be stopped
|
||||
"""
|
||||
log.debug('media_stop')
|
||||
print('### media_stop')
|
||||
display = self._define_display(controller)
|
||||
if controller.controller_type in self.current_media_players:
|
||||
display.frame.evaluateJavaScript('show_blank("black");')
|
||||
@ -664,6 +695,9 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
controller.mediabar.actions['playbackPlay'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setDisabled(True)
|
||||
controller.mediabar.actions['playbackPause'].setVisible(False)
|
||||
controller.media_info.playing = False
|
||||
controller.media_info.timer = 1000
|
||||
controller.media_timer = 0
|
||||
|
||||
def media_volume_msg(self, msg):
|
||||
"""
|
||||
@ -694,7 +728,6 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
:param msg: First element is the controller which should be used
|
||||
Second element is a list with the seek value as first element
|
||||
"""
|
||||
log.debug('media_seek')
|
||||
controller = msg[0]
|
||||
seek_value = msg[1][0]
|
||||
self.media_seek(controller, seek_value)
|
||||
@ -706,15 +739,15 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
:param controller: The controller to use.
|
||||
:param seek_value: The value to set.
|
||||
"""
|
||||
log.debug('media_seek')
|
||||
display = self._define_display(controller)
|
||||
self.current_media_players[controller.controller_type].seek(display, seek_value)
|
||||
controller.media_info.timer = seek_value
|
||||
|
||||
def media_reset(self, controller):
|
||||
"""
|
||||
Responds to the request to reset a loaded video
|
||||
:param controller: The controller to use.
|
||||
"""
|
||||
log.debug('media_reset')
|
||||
self.set_controls_visible(controller, False)
|
||||
display = self._define_display(controller)
|
||||
if controller.controller_type in self.current_media_players:
|
||||
|
@ -4,14 +4,7 @@
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2014 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
@ -216,7 +209,8 @@ class SystemPlayer(MediaPlayer):
|
||||
|
||||
@staticmethod
|
||||
def set_duration(controller, duration):
|
||||
controller.media_info.length = int(duration / 1000)
|
||||
print("system set duration", controller.media_info.length, duration)
|
||||
#controller.media_info.length = int(duration / 1000)
|
||||
controller.seek_slider.setMaximum(controller.media_info.length * 1000)
|
||||
|
||||
def update_ui(self, display):
|
||||
|
140
openlp/core/ui/media/vendor/mediainfoWrapper.py
vendored
Normal file
140
openlp/core/ui/media/vendor/mediainfoWrapper.py
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.mediainfo` module contains code to run mediainfo on a media file and obtain
|
||||
information related to the rwquested media.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
from subprocess import Popen
|
||||
from tempfile import mkstemp
|
||||
|
||||
import six
|
||||
from bs4 import BeautifulSoup, NavigableString
|
||||
|
||||
ENV_DICT = os.environ
|
||||
|
||||
|
||||
class Track(object):
|
||||
|
||||
def __getattribute__(self, name):
|
||||
try:
|
||||
return object.__getattribute__(self, name)
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
def __init__(self, xml_dom_fragment):
|
||||
self.xml_dom_fragment = xml_dom_fragment
|
||||
self.track_type = xml_dom_fragment.attrs['type']
|
||||
for el in self.xml_dom_fragment.children:
|
||||
if not isinstance(el, NavigableString):
|
||||
node_name = el.name.lower().strip().strip('_')
|
||||
if node_name == 'id':
|
||||
node_name = 'track_id'
|
||||
node_value = el.string
|
||||
other_node_name = "other_%s" % node_name
|
||||
if getattr(self, node_name) is None:
|
||||
setattr(self, node_name, node_value)
|
||||
else:
|
||||
if getattr(self, other_node_name) is None:
|
||||
setattr(self, other_node_name, [node_value, ])
|
||||
else:
|
||||
getattr(self, other_node_name).append(node_value)
|
||||
|
||||
for o in [d for d in self.__dict__.keys() if d.startswith('other_')]:
|
||||
try:
|
||||
primary = o.replace('other_', '')
|
||||
setattr(self, primary, int(getattr(self, primary)))
|
||||
except:
|
||||
for v in getattr(self, o):
|
||||
try:
|
||||
current = getattr(self, primary)
|
||||
setattr(self, primary, int(v))
|
||||
getattr(self, o).append(current)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return "<Track track_id='{0}', track_type='{1}'>".format(self.track_id, self.track_type)
|
||||
|
||||
def to_data(self):
|
||||
data = {}
|
||||
for k, v in six.iteritems(self.__dict__):
|
||||
if k != 'xml_dom_fragment':
|
||||
data[k] = v
|
||||
return data
|
||||
|
||||
|
||||
class MediaInfoWrapper(object):
|
||||
|
||||
def __init__(self, xml):
|
||||
self.xml_dom = xml
|
||||
xml_types = (str,) # no unicode type in python3
|
||||
if isinstance(xml, xml_types):
|
||||
self.xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(xml)
|
||||
|
||||
@staticmethod
|
||||
def parse_xml_data_into_dom(xml_data):
|
||||
return BeautifulSoup(xml_data, "xml")
|
||||
|
||||
@staticmethod
|
||||
def parse(filename, environment=ENV_DICT):
|
||||
command = ["mediainfo", "-f", "--Output=XML", filename]
|
||||
fileno_out, fname_out = mkstemp(suffix=".xml", prefix="media-")
|
||||
fileno_err, fname_err = mkstemp(suffix=".err", prefix="media-")
|
||||
fp_out = os.fdopen(fileno_out, 'r+b')
|
||||
fp_err = os.fdopen(fileno_err, 'r+b')
|
||||
p = Popen(command, stdout=fp_out, stderr=fp_err, env=environment)
|
||||
p.wait()
|
||||
fp_out.seek(0)
|
||||
|
||||
xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(fp_out.read())
|
||||
fp_out.close()
|
||||
fp_err.close()
|
||||
os.unlink(fname_out)
|
||||
os.unlink(fname_err)
|
||||
return MediaInfoWrapper(xml_dom)
|
||||
|
||||
def _populate_tracks(self):
|
||||
if self.xml_dom is None:
|
||||
return
|
||||
for xml_track in self.xml_dom.Mediainfo.File.find_all("track"):
|
||||
self._tracks.append(Track(xml_track))
|
||||
|
||||
@property
|
||||
def tracks(self):
|
||||
if not hasattr(self, "_tracks"):
|
||||
self._tracks = []
|
||||
if len(self._tracks) == 0:
|
||||
self._populate_tracks()
|
||||
return self._tracks
|
||||
|
||||
def to_data(self):
|
||||
data = {'tracks': []}
|
||||
for track in self.tracks:
|
||||
data['tracks'].append(track.to_data())
|
||||
return data
|
||||
|
||||
def to_json(self):
|
||||
return json.dumps(self.to_data())
|
@ -144,6 +144,9 @@ class VlcPlayer(MediaPlayer):
|
||||
def setup(self, display):
|
||||
"""
|
||||
Set up the media player
|
||||
|
||||
:param display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
display.vlc_widget = QtWidgets.QFrame(display)
|
||||
@ -186,6 +189,9 @@ class VlcPlayer(MediaPlayer):
|
||||
def load(self, display):
|
||||
"""
|
||||
Load a video into VLC
|
||||
|
||||
:param display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
log.debug('load vid in Vlc Controller')
|
||||
@ -219,13 +225,17 @@ class VlcPlayer(MediaPlayer):
|
||||
# and once to just get media length.
|
||||
#
|
||||
# Media plugin depends on knowing media length before playback.
|
||||
controller.media_info.length = int(display.vlc_media_player.get_media().get_duration() / 1000)
|
||||
#controller.media_info.length = int(display.vlc_media_player.get_media().get_duration() / 1000)
|
||||
return True
|
||||
|
||||
def media_state_wait(self, display, 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 display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
start = datetime.now()
|
||||
@ -240,12 +250,18 @@ class VlcPlayer(MediaPlayer):
|
||||
def resize(self, display):
|
||||
"""
|
||||
Resize the player
|
||||
|
||||
:param display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
display.vlc_widget.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
"""
|
||||
Play the current item
|
||||
|
||||
:param display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
controller = display.controller
|
||||
@ -280,11 +296,13 @@ class VlcPlayer(MediaPlayer):
|
||||
start_time = controller.media_info.start_time
|
||||
controller.media_info.length = controller.media_info.end_time - controller.media_info.start_time
|
||||
else:
|
||||
controller.media_info.length = int(display.vlc_media_player.get_media().get_duration() / 1000)
|
||||
print("vlc len", controller.media_info.length)
|
||||
#controller.media_info.length = int(display.vlc_media_player.get_media().get_duration())
|
||||
self.volume(display, controller.media_info.volume)
|
||||
if start_time > 0 and display.vlc_media_player.is_seekable():
|
||||
display.vlc_media_player.set_time(int(start_time * 1000))
|
||||
controller.seek_slider.setMaximum(controller.media_info.length * 1000)
|
||||
display.vlc_media_player.set_time(int(start_time))
|
||||
controller.seek_slider.setMaximum(controller.media_info.length)
|
||||
print("VLC play " + str(controller.media_info.length))
|
||||
self.state = MediaState.Playing
|
||||
display.vlc_widget.raise_()
|
||||
return True
|
||||
@ -292,6 +310,9 @@ class VlcPlayer(MediaPlayer):
|
||||
def pause(self, display):
|
||||
"""
|
||||
Pause the current item
|
||||
|
||||
:param display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
if display.vlc_media.get_state() != vlc.State.Playing:
|
||||
@ -303,6 +324,9 @@ class VlcPlayer(MediaPlayer):
|
||||
def stop(self, display):
|
||||
"""
|
||||
Stop the current item
|
||||
|
||||
:param display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
threading.Thread(target=display.vlc_media_player.stop).start()
|
||||
self.state = MediaState.Stopped
|
||||
@ -310,6 +334,10 @@ class VlcPlayer(MediaPlayer):
|
||||
def volume(self, display, vol):
|
||||
"""
|
||||
Set the volume
|
||||
|
||||
:param vol: The volume to be sets
|
||||
:param display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
if display.has_audio:
|
||||
display.vlc_media_player.audio_set_volume(vol)
|
||||
@ -317,6 +345,9 @@ class VlcPlayer(MediaPlayer):
|
||||
def seek(self, display, seek_value):
|
||||
"""
|
||||
Go to a particular position
|
||||
|
||||
:param seek_value: The position of where a seek goes to
|
||||
:param display: The display where the media is
|
||||
"""
|
||||
if display.controller.media_info.media_type == MediaType.CD \
|
||||
or display.controller.media_info.media_type == MediaType.DVD:
|
||||
@ -327,6 +358,8 @@ class VlcPlayer(MediaPlayer):
|
||||
def reset(self, display):
|
||||
"""
|
||||
Reset the player
|
||||
|
||||
:param display: The display where the media is
|
||||
"""
|
||||
display.vlc_media_player.stop()
|
||||
display.vlc_widget.setVisible(False)
|
||||
@ -335,6 +368,9 @@ class VlcPlayer(MediaPlayer):
|
||||
def set_visible(self, display, status):
|
||||
"""
|
||||
Set the visibility
|
||||
|
||||
:param display: The display where the media is
|
||||
:param status: The visibility status
|
||||
"""
|
||||
if self.has_own_widget:
|
||||
display.vlc_widget.setVisible(status)
|
||||
@ -342,6 +378,8 @@ class VlcPlayer(MediaPlayer):
|
||||
def update_ui(self, display):
|
||||
"""
|
||||
Update the UI
|
||||
|
||||
:param display: The display where the media is
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
# Stop video if playback is finished.
|
||||
|
@ -281,7 +281,7 @@ class WebkitPlayer(MediaPlayer):
|
||||
if start_time > 0:
|
||||
self.seek(display, controller.media_info.start_time * 1000)
|
||||
# TODO add playing check and get the correct media length
|
||||
controller.media_info.length = length
|
||||
print("Webkit play " + str(length))
|
||||
self.state = MediaState.Playing
|
||||
display.web_view.raise_()
|
||||
return True
|
||||
@ -376,6 +376,7 @@ class WebkitPlayer(MediaPlayer):
|
||||
if length and length != float('inf'):
|
||||
length = int(length * 1000)
|
||||
if current_time and length:
|
||||
print("webkit update_ui", controller.media_info.length)
|
||||
controller.media_info.length = length
|
||||
controller.seek_slider.setMaximum(length)
|
||||
if not controller.seek_slider.isSliderDown():
|
||||
|
@ -272,9 +272,8 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
service_item.title = name
|
||||
service_item.processor = self.display_type_combo_box.currentText()
|
||||
service_item.add_from_command(path, name, CLAPPERBOARD)
|
||||
print("building service item")
|
||||
# Only get start and end times if going to a service
|
||||
if context == ServiceItemContext.Service:
|
||||
# Start media and obtain the length
|
||||
if not self.media_controller.media_length(service_item):
|
||||
return False
|
||||
service_item.add_capability(ItemCapabilities.CanAutoStartForLive)
|
||||
|
21
tests/interfaces/openlp_core_ul_media_vendor/__init__.py
Normal file
21
tests/interfaces/openlp_core_ul_media_vendor/__init__.py
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
Package to test the openlp.core.ui.media package.
|
||||
"""
|
||||
|
||||
import os
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
|
||||
|
||||
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'resources', 'media'))
|
||||
|
||||
TEST_MEDIA = [['avi_file.avi', 61495], ['mp3_file.mp3', 134426], ['mpg_file.mpg', 9404], ['mp4_file.mp4', 188336]]
|
||||
|
||||
|
||||
class TestMediainfoWrapper(TestCase):
|
||||
|
||||
def media_length_test(self):
|
||||
"""
|
||||
Test the Media Info basic functionality
|
||||
"""
|
||||
for test_data in TEST_MEDIA:
|
||||
# GIVEN: a media file
|
||||
full_path = os.path.normpath(os.path.join(TEST_PATH, test_data[0]))
|
||||
|
||||
# WHEN the media data is retrieved
|
||||
results = MediaInfoWrapper.parse(full_path)
|
||||
|
||||
# THEN you can determine the run time
|
||||
self.assertEqual(results.tracks[0].duration, test_data[1], 'The correct duration is returned for ' +
|
||||
test_data[0])
|
BIN
tests/resources/media/avi_file.avi
Normal file
BIN
tests/resources/media/avi_file.avi
Normal file
Binary file not shown.
BIN
tests/resources/media/mp3_file.mp3
Normal file
BIN
tests/resources/media/mp3_file.mp3
Normal file
Binary file not shown.
BIN
tests/resources/media/mp4_file.mp4
Normal file
BIN
tests/resources/media/mp4_file.mp4
Normal file
Binary file not shown.
BIN
tests/resources/media/mpg_file.mpg
Normal file
BIN
tests/resources/media/mpg_file.mpg
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user