diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 8410d4d28..2bea463dc 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -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', 'Length: %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: diff --git a/openlp/core/ui/media/__init__.py b/openlp/core/ui/media/__init__.py index ecd4b98bd..e19967dde 100644 --- a/openlp/core/ui/media/__init__.py +++ b/openlp/core/ui/media/__init__.py @@ -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() diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index 343ce0dd4..1dca34566 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -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: diff --git a/openlp/core/ui/media/systemplayer.py b/openlp/core/ui/media/systemplayer.py index 79069f9c9..ac7a34eed 100644 --- a/openlp/core/ui/media/systemplayer.py +++ b/openlp/core/ui/media/systemplayer.py @@ -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): diff --git a/openlp/core/ui/media/vendor/mediainfoWrapper.py b/openlp/core/ui/media/vendor/mediainfoWrapper.py new file mode 100644 index 000000000..c77b47912 --- /dev/null +++ b/openlp/core/ui/media/vendor/mediainfoWrapper.py @@ -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 "".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()) \ No newline at end of file diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index 99f8c37fd..fb865f624 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -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. diff --git a/openlp/core/ui/media/webkitplayer.py b/openlp/core/ui/media/webkitplayer.py index 0a35fe085..8160d45f5 100644 --- a/openlp/core/ui/media/webkitplayer.py +++ b/openlp/core/ui/media/webkitplayer.py @@ -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(): diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 09b32b308..90aa9a542 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -272,11 +272,10 @@ 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 + if not self.media_controller.media_length(service_item): + return False service_item.add_capability(ItemCapabilities.CanAutoStartForLive) service_item.add_capability(ItemCapabilities.CanEditTitle) service_item.add_capability(ItemCapabilities.RequiresMedia) diff --git a/tests/interfaces/openlp_core_ul_media_vendor/__init__.py b/tests/interfaces/openlp_core_ul_media_vendor/__init__.py new file mode 100644 index 000000000..02bded5b0 --- /dev/null +++ b/tests/interfaces/openlp_core_ul_media_vendor/__init__.py @@ -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 # +############################################################################### diff --git a/tests/interfaces/openlp_core_ul_media_vendor/test_mediainfoWrapper.py b/tests/interfaces/openlp_core_ul_media_vendor/test_mediainfoWrapper.py new file mode 100644 index 000000000..acf17f581 --- /dev/null +++ b/tests/interfaces/openlp_core_ul_media_vendor/test_mediainfoWrapper.py @@ -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]) diff --git a/tests/resources/media/avi_file.avi b/tests/resources/media/avi_file.avi new file mode 100644 index 000000000..9a89932fe Binary files /dev/null and b/tests/resources/media/avi_file.avi differ diff --git a/tests/resources/media/mp3_file.mp3 b/tests/resources/media/mp3_file.mp3 new file mode 100644 index 000000000..2b5cc44f7 Binary files /dev/null and b/tests/resources/media/mp3_file.mp3 differ diff --git a/tests/resources/media/mp4_file.mp4 b/tests/resources/media/mp4_file.mp4 new file mode 100644 index 000000000..73abf10a0 Binary files /dev/null and b/tests/resources/media/mp4_file.mp4 differ diff --git a/tests/resources/media/mpg_file.mpg b/tests/resources/media/mpg_file.mpg new file mode 100644 index 000000000..af768c542 Binary files /dev/null and b/tests/resources/media/mpg_file.mpg differ