openlp/openlp/core/ui/media/mediacontroller.py

748 lines
32 KiB
Python
Raw Normal View History

2011-06-05 21:10:49 +00:00
# -*- coding: utf-8 -*-
2012-12-11 19:55:47 +00:00
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
2011-06-05 21:10:49 +00:00
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2012-10-21 13:16:22 +00:00
# Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
2012-11-11 21:16:14 +00:00
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
2012-10-21 13:16:22 +00:00
# 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 #
2011-06-05 21:10:49 +00:00
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import logging
2011-12-02 21:13:05 +00:00
import os
import sys
2011-12-02 21:13:05 +00:00
from PyQt4 import QtCore, QtGui
2011-06-05 21:10:49 +00:00
from openlp.core.lib import OpenLPToolbar, Receiver, translate
from openlp.core.lib.settings import Settings
2012-11-22 22:02:40 +00:00
from openlp.core.lib.ui import UiStrings, critical_error_message_box
2012-12-29 20:54:25 +00:00
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players
2012-09-09 06:06:44 +00:00
from openlp.core.ui.media.mediaplayer import MediaPlayer
2011-07-10 21:43:07 +00:00
from openlp.core.utils import AppLocation
2012-10-20 19:52:04 +00:00
from openlp.core.ui import DisplayControllerType
2011-06-05 21:10:49 +00:00
log = logging.getLogger(__name__)
2012-12-29 20:54:25 +00:00
class MediaSlider(QtGui.QSlider):
"""
Set up key bindings and mouse behaviour for the Qslider
Let's say the user clicks at (100, 50), and the slider geometry is (30, 40, 200, 60).
Then the slider width is 200-30=170px.
Now, clicking at 100 pixels(relative to the slider) means the knob should be moved at 58.82% from the slider value.
So if the slider value goes from 1 to 440, then you should use QSlider:setValue(440*58.82/100).
"""
def __init__(self, direction, manager, controller, parent=None):
QtGui.QSlider.__init__(self, direction)
self.manager = manager
self.controller = controller
def mouseMoveEvent(self, event):
#print "mme",self.sliderPosition()
QtGui.QSlider.mouseMoveEvent(self, event)
def mousePressEvent(self, event):
print "mpe",self.sliderPosition(), self.maximum(),self.minimum()
self.manager.media_seek(self.controller,self.sliderPosition())
QtGui.QSlider.mousePressEvent(self, event)
def mouseReleaseEvent(self, event):
#print "mre",self.sliderPosition()
QtGui.QSlider.mouseReleaseEvent(self, event)
def _calculate_position(self):
position = float(self.mapFromGlobal(QtGui.QCursor.pos()).x())
width = float(self.geometry().width() - self.geometry().x())
print position, width
percent = 0
if position > 0:
percent = position * (width / 100)
length = self.maximum() - self.minimum()
new_position = self.maximum()
if percent < 100:
new_position = int(length * (percent / 100) )
print length, percent, new_position, self.sliderPosition(), self.maximum()
#self.setSliderPosition(new_position)
self.manager.media_seek(self.controller, new_position)
2011-08-29 21:51:03 +00:00
class MediaController(object):
2011-06-05 21:10:49 +00:00
"""
2011-11-02 20:27:53 +00:00
The implementation of the Media Controller. The Media Controller adds an own
2012-08-05 18:17:52 +00:00
class for every Player. Currently these are QtWebkit, Phonon and Vlc.
2012-11-01 16:54:37 +00:00
displayControllers are an array of controllers keyed on the
slidecontroller or plugin which built them. ControllerType is the class
2012-11-01 18:45:12 +00:00
containing the key values.
2012-11-01 16:54:37 +00:00
2012-11-01 18:45:12 +00:00
mediaPlayers are an array of media players keyed on player name.
2012-11-16 21:46:17 +00:00
currentMediaPlayer is an array of player instances keyed on ControllerType.
2012-11-01 16:54:37 +00:00
2011-06-05 21:10:49 +00:00
"""
def __init__(self, parent):
2012-10-04 17:28:49 +00:00
self.mainWindow = parent
2011-11-11 16:45:25 +00:00
self.mediaPlayers = {}
2012-10-20 19:52:04 +00:00
self.displayControllers = {}
self.currentMediaPlayer = {}
2011-08-29 19:55:58 +00:00
# Timer for video state
2011-09-22 18:22:35 +00:00
self.timer = QtCore.QTimer()
self.timer.setInterval(200)
2011-08-29 19:55:58 +00:00
# Signals
2012-12-11 19:55:47 +00:00
QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.media_state)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackPlay'), self.media_play_msg)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackPause'), self.media_pause_msg)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackStop'), self.media_stop_msg)
2012-12-29 20:54:25 +00:00
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'seekSlider'), self.media_seek_msg)
2012-12-13 19:02:32 +00:00
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'volumeSlider'), self.media_volume_msg)
2012-12-11 19:55:47 +00:00
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_hide'), self.media_hide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_blank'), self.media_blank)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_unblank'), self.media_unblank)
2011-09-28 20:54:43 +00:00
# Signals for background video
2012-12-11 19:55:47 +00:00
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_hide'), self.media_hide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_unblank'), self.media_unblank)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_media_rebuild'),
self._set_active_players)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_suffixes'),
self._generate_extensions_lists)
2011-11-24 21:10:37 +00:00
2012-10-06 08:35:37 +00:00
def _set_active_players(self):
"""
Set the active players and available media files
"""
2012-03-16 21:52:15 +00:00
savedPlayers = get_media_players()[0]
2011-11-30 17:06:57 +00:00
for player in self.mediaPlayers.keys():
2012-04-28 11:13:16 +00:00
self.mediaPlayers[player].isActive = player in savedPlayers
2011-06-05 21:10:49 +00:00
def _generate_extensions_lists(self):
"""
Set the active players and available media files
"""
self.audio_extensions_list = []
for player in self.mediaPlayers.values():
if player.isActive:
for item in player.audio_extensions_list:
if not item in self.audio_extensions_list:
self.audio_extensions_list.append(item)
2012-12-11 19:55:47 +00:00
self.mainWindow.serviceManagerContents.supportedSuffixes(item[2:])
self.video_extensions_list = []
for player in self.mediaPlayers.values():
if player.isActive:
for item in player.video_extensions_list:
if item not in self.video_extensions_list:
self.video_extensions_list.extend(item)
2012-12-11 19:55:47 +00:00
self.mainWindow.serviceManagerContents.supportedSuffixes(item[2:])
2012-10-04 20:12:09 +00:00
def register_players(self, player):
2011-07-10 21:43:07 +00:00
"""
2012-10-20 19:52:04 +00:00
Register each media Player (Webkit, Phonon, etc) and store
2011-11-24 21:10:37 +00:00
for later use
2012-10-04 20:12:09 +00:00
``player``
Individual player class which has been enabled
2011-07-10 21:43:07 +00:00
"""
2012-10-04 20:12:09 +00:00
self.mediaPlayers[player.name] = player
2011-07-10 21:43:07 +00:00
def check_available_media_players(self):
2011-07-10 21:43:07 +00:00
"""
2012-10-20 19:52:04 +00:00
Check to see if we have any media Player's available.
2011-07-10 21:43:07 +00:00
"""
2012-10-06 08:35:37 +00:00
log.debug(u'_check_available_media_players')
2011-07-10 21:43:07 +00:00
controller_dir = os.path.join(
AppLocation.get_directory(AppLocation.AppDir),
u'core', u'ui', u'media')
for filename in os.listdir(controller_dir):
2012-12-11 19:55:47 +00:00
if filename.endswith(u'player.py') and not filename == 'mediaplayer.py':
2011-07-10 21:43:07 +00:00
path = os.path.join(controller_dir, filename)
if os.path.isfile(path):
2012-12-11 19:55:47 +00:00
modulename = u'openlp.core.ui.media.' + os.path.splitext(filename)[0]
2011-07-10 21:43:07 +00:00
log.debug(u'Importing controller %s', modulename)
try:
__import__(modulename, globals(), locals(), [])
# On some platforms importing vlc.py might cause
# also OSError exceptions. (e.g. Mac OS X)
except (ImportError, OSError):
2012-12-11 19:55:47 +00:00
log.warn(u'Failed to import %s on path %s', modulename, path)
2012-10-04 20:12:09 +00:00
player_classes = MediaPlayer.__subclasses__()
for player_class in player_classes:
player = player_class(self)
self.register_players(player)
2012-04-28 11:13:16 +00:00
if not self.mediaPlayers:
2011-07-10 21:43:07 +00:00
return False
2012-04-28 11:13:16 +00:00
savedPlayers, overriddenPlayer = get_media_players()
invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers
2012-12-11 19:55:47 +00:00
if not mediaPlayer in self.mediaPlayers or not self.mediaPlayers[mediaPlayer].check_available()]
2012-04-28 11:13:16 +00:00
if invalidMediaPlayers:
for invalidPlayer in invalidMediaPlayers:
savedPlayers.remove(invalidPlayer)
set_media_players(savedPlayers, overriddenPlayer)
2012-10-06 08:35:37 +00:00
self._set_active_players()
self._generate_extensions_lists()
2012-04-28 11:13:16 +00:00
return True
2011-07-10 21:43:07 +00:00
2012-10-15 18:38:58 +00:00
def media_state(self):
2011-06-05 21:10:49 +00:00
"""
2011-11-02 20:27:53 +00:00
Check if there is a running media Player and do updating stuff (e.g.
update the UI)
2011-06-05 21:10:49 +00:00
"""
if not self.currentMediaPlayer.keys():
2011-09-22 18:22:35 +00:00
self.timer.stop()
2011-06-05 21:10:49 +00:00
else:
any_active = False
2012-11-16 21:46:17 +00:00
for source in self.currentMediaPlayer.keys():
display = self._define_display(self.displayControllers[source])
self.currentMediaPlayer[source].resize(display)
self.currentMediaPlayer[source].update_ui(display)
2012-12-11 19:55:47 +00:00
if self.currentMediaPlayer[source].state == MediaState.Playing:
any_active = True
# There are still any active players - no need to stop timer.
if any_active:
return
# no players are active anymore
2012-11-16 21:46:17 +00:00
for source in self.currentMediaPlayer.keys():
if self.currentMediaPlayer[source].state != MediaState.Paused:
display = self._define_display(self.displayControllers[source])
display.controller.seekSlider.setSliderPosition(0)
2011-11-02 20:27:53 +00:00
self.timer.stop()
2011-06-05 21:10:49 +00:00
2011-08-29 19:55:58 +00:00
def get_media_display_css(self):
2011-06-08 13:18:05 +00:00
"""
Add css style sheets to htmlbuilder
"""
2011-10-24 20:04:29 +00:00
css = u''
2011-11-11 16:45:25 +00:00
for player in self.mediaPlayers.values():
2011-11-24 21:10:37 +00:00
if player.isActive:
css += player.get_media_display_css()
2011-06-08 13:18:05 +00:00
return css
2011-08-29 19:55:58 +00:00
def get_media_display_javascript(self):
2011-06-08 13:18:05 +00:00
"""
Add javascript functions to htmlbuilder
"""
js = u''
2011-11-11 16:45:25 +00:00
for player in self.mediaPlayers.values():
2011-11-24 21:10:37 +00:00
if player.isActive:
js += player.get_media_display_javascript()
2011-06-08 13:18:05 +00:00
return js
2011-08-29 19:55:58 +00:00
def get_media_display_html(self):
2011-06-08 13:18:05 +00:00
"""
Add html code to htmlbuilder
"""
html = u''
2011-11-11 16:45:25 +00:00
for player in self.mediaPlayers.values():
2011-11-24 21:10:37 +00:00
if player.isActive:
html += player.get_media_display_html()
2011-06-08 13:18:05 +00:00
return html
def register_controller(self, controller):
2012-10-04 20:12:09 +00:00
"""
Registers media controls where the players will be placed to run.
``controller``
The controller where a player will be placed
"""
self.displayControllers[controller.controllerType] = controller
self.setup_generic_controls(controller)
2011-06-05 21:10:49 +00:00
def setup_generic_controls(self, controller):
2011-11-02 20:27:53 +00:00
"""
2012-10-04 20:12:09 +00:00
Set up controls on the control_panel for a given controller
``controller``
First element is the controller which should be used
2011-11-02 20:27:53 +00:00
"""
2011-06-05 21:10:49 +00:00
controller.media_info = MediaInfo()
# Build a Media ToolBar
controller.mediabar = OpenLPToolbar(controller)
2012-12-11 19:55:47 +00:00
controller.mediabar.addToolbarAction(u'playbackPlay', text=u'media_playback_play',
icon=u':/slides/media_playback_start.png',
2012-12-11 19:55:47 +00:00
tooltip=translate('OpenLP.SlideController', 'Start playing media.'), triggers=controller.sendToPlugins)
controller.mediabar.addToolbarAction(u'playbackPause', text=u'media_playback_pause',
icon=u':/slides/media_playback_pause.png',
2012-12-11 19:55:47 +00:00
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'), triggers=controller.sendToPlugins)
controller.mediabar.addToolbarAction(u'playbackStop', text=u'media_playback_stop',
icon=u':/slides/media_playback_stop.png',
2012-12-11 19:55:47 +00:00
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'), triggers=controller.sendToPlugins)
2011-06-05 21:10:49 +00:00
# Build the seekSlider.
2012-12-29 20:54:25 +00:00
controller.seekSlider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
2011-06-05 21:10:49 +00:00
controller.seekSlider.setMaximum(1000)
2012-12-29 20:54:25 +00:00
controller.seekSlider.setTracking(True)
controller.seekSlider.setMouseTracking(True)
2012-12-11 19:55:47 +00:00
controller.seekSlider.setToolTip(translate('OpenLP.SlideController', 'Video position.'))
2011-10-17 21:35:44 +00:00
controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
controller.seekSlider.setObjectName(u'seekSlider')
controller.mediabar.addToolbarWidget(controller.seekSlider)
2011-06-05 21:10:49 +00:00
# Build the volumeSlider.
controller.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
controller.volumeSlider.setTickInterval(10)
controller.volumeSlider.setTickPosition(QtGui.QSlider.TicksAbove)
controller.volumeSlider.setMinimum(0)
controller.volumeSlider.setMaximum(100)
controller.volumeSlider.setTracking(True)
2012-12-11 19:55:47 +00:00
controller.volumeSlider.setToolTip(translate('OpenLP.SlideController', 'Audio Volume.'))
2011-06-05 21:10:49 +00:00
controller.volumeSlider.setValue(controller.media_info.volume)
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
controller.volumeSlider.setObjectName(u'volumeSlider')
controller.mediabar.addToolbarWidget(controller.volumeSlider)
controller.controllerLayout.addWidget(controller.mediabar)
2011-06-05 21:10:49 +00:00
controller.mediabar.setVisible(False)
2011-08-29 19:55:58 +00:00
# Signals
2012-12-11 19:55:47 +00:00
QtCore.QObject.connect(controller.seekSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
QtCore.QObject.connect(controller.volumeSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
2011-06-05 21:10:49 +00:00
2011-11-02 20:27:53 +00:00
2012-10-20 19:52:04 +00:00
def setup_display(self, display, preview):
2011-06-05 21:10:49 +00:00
"""
2011-12-03 20:35:53 +00:00
After a new display is configured, all media related widget will be
2011-11-02 20:27:53 +00:00
created too
2012-10-13 20:54:56 +00:00
``display``
Display on which the output is to be played
2012-10-20 19:52:04 +00:00
``preview``
Whether the display is a main or preview display
2011-06-05 21:10:49 +00:00
"""
2011-07-20 21:16:36 +00:00
# clean up possible running old media files
self.finalise()
2011-11-30 17:06:57 +00:00
# update player status
2012-10-06 08:35:37 +00:00
self._set_active_players()
2011-06-05 21:10:49 +00:00
display.hasAudio = True
2012-11-28 21:14:08 +00:00
if display.isLive and preview:
return
2012-10-20 19:52:04 +00:00
if preview:
2011-06-05 21:10:49 +00:00
display.hasAudio = False
2011-11-11 16:45:25 +00:00
for player in self.mediaPlayers.values():
2011-11-24 21:10:37 +00:00
if player.isActive:
player.setup(display)
2011-06-05 21:10:49 +00:00
def set_controls_visible(self, controller, value):
2012-10-13 20:54:56 +00:00
"""
After a new display is configured, all media related widget will be
created too
``controller``
The controller on which controls act.
``value``
control name to be changed.
"""
2011-06-05 21:10:49 +00:00
# Generic controls
controller.mediabar.setVisible(value)
2012-01-19 19:13:19 +00:00
if controller.isLive and controller.display:
if self.currentMediaPlayer and value:
2012-12-11 19:55:47 +00:00
if self.currentMediaPlayer[controller.controllerType] != self.mediaPlayers[u'webkit']:
2012-01-19 19:13:19 +00:00
controller.display.setTransparency(False)
2011-06-05 21:10:49 +00:00
2012-10-29 16:54:39 +00:00
def resize(self, display, player):
2011-06-05 21:10:49 +00:00
"""
2011-12-03 20:35:53 +00:00
After Mainwindow changes or Splitter moved all related media widgets
2011-11-02 20:27:53 +00:00
have to be resized
2012-10-13 20:54:56 +00:00
``display``
The display on which output is playing.
``player``
The player which is doing the playing.
2011-06-05 21:10:49 +00:00
"""
2011-11-11 16:45:25 +00:00
player.resize(display)
2011-06-05 21:10:49 +00:00
2012-10-25 21:03:12 +00:00
def video(self, source, serviceItem, hidden=False, videoBehindText=False):
2011-06-05 21:10:49 +00:00
"""
Loads and starts a video to run with the option of sound
2012-10-13 20:54:56 +00:00
2012-10-25 20:33:28 +00:00
``source``
Where the call originated form
2012-10-13 20:54:56 +00:00
2012-10-25 20:33:28 +00:00
``serviceItem``
2012-10-13 20:54:56 +00:00
The player which is doing the playing
``hidden``
The player which is doing the playing
2012-10-25 21:03:12 +00:00
``videoBehindText``
Is the video to be played behind text.
2011-06-05 21:10:49 +00:00
"""
log.debug(u'video')
isValid = False
controller = self.displayControllers[source]
2011-06-05 21:10:49 +00:00
# stop running videos
2012-10-15 18:38:58 +00:00
self.media_reset(controller)
2011-06-05 21:10:49 +00:00
controller.media_info = MediaInfo()
2012-12-13 18:55:11 +00:00
controller.media_info.volume = controller.volumeSlider.value()
controller.media_info.is_background = videoBehindText
2012-12-11 19:55:47 +00:00
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
2012-10-29 17:25:08 +00:00
display = self._define_display(controller)
2011-06-05 21:10:49 +00:00
if controller.isLive:
isValid = self._check_file_type(controller, display, serviceItem)
2011-07-20 21:16:36 +00:00
display.override[u'theme'] = u''
display.override[u'video'] = True
2011-12-06 21:42:34 +00:00
if controller.media_info.is_background:
# ignore start/end time
controller.media_info.start_time = 0
controller.media_info.end_time = 0
else:
2012-12-21 19:11:00 +00:00
controller.media_info.start_time = serviceItem.start_time
2012-09-14 16:35:07 +00:00
controller.media_info.end_time = serviceItem.end_time
2011-07-25 20:56:39 +00:00
elif controller.previewDisplay:
isValid = self._check_file_type(controller, display, serviceItem)
2011-06-05 21:10:49 +00:00
if not isValid:
2011-08-29 19:55:58 +00:00
# Media could not be loaded correctly
2012-12-11 19:55:47 +00:00
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
unicode(translate('MediaPlugin.MediaItem', 'Unsupported File')))
2011-07-18 21:25:10 +00:00
return False
2011-11-24 21:10:37 +00:00
# dont care about actual theme, set a black background
2012-04-28 11:13:16 +00:00
if controller.isLive and not controller.media_info.is_background:
2012-12-11 19:55:47 +00:00
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"visible");')
2012-09-07 16:58:13 +00:00
# now start playing - Preview is autoplay!
autoplay = False
# Preview requested
2012-12-21 19:11:00 +00:00
print serviceItem.will_auto_start
2012-09-07 16:58:13 +00:00
if not controller.isLive:
autoplay = True
2012-11-04 20:11:10 +00:00
# Visible or background requested or Service Item wants to autostart
2012-12-21 19:11:00 +00:00
elif serviceItem.will_auto_start:
autoplay = True
# Visible or background requested or Service Item wants to autostart
elif (not hidden or controller.media_info.is_background) and not serviceItem.will_auto_start:
2012-09-07 16:58:13 +00:00
autoplay = True
# Unblank on load set
2012-12-11 19:55:47 +00:00
elif Settings().value(u'general/auto unblank', QtCore.QVariant(False)).toBool():
2012-09-07 16:58:13 +00:00
autoplay = True
if autoplay:
2012-10-26 20:20:23 +00:00
if not self.media_play(controller):
2012-12-11 19:55:47 +00:00
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
unicode(translate('MediaPlugin.MediaItem', 'Unsupported File')))
2012-09-08 18:29:05 +00:00
return False
2011-12-01 18:07:15 +00:00
self.set_controls_visible(controller, True)
2012-12-11 19:55:47 +00:00
log.debug(u'use %s controller' % self.currentMediaPlayer[controller.controllerType])
2011-12-01 18:07:15 +00:00
return True
2011-06-05 21:10:49 +00:00
def media_length(self, serviceItem):
2012-09-09 06:54:09 +00:00
"""
2012-09-14 16:35:07 +00:00
Loads and starts a media item to obtain the media length
``serviceItem``
The ServiceItem containing the details to be played.
2012-09-09 06:54:09 +00:00
"""
controller = self.displayControllers[DisplayControllerType.Plugin]
2012-09-09 06:54:09 +00:00
log.debug(u'media_length')
# stop running videos
2012-10-15 18:38:58 +00:00
self.media_reset(controller)
2012-09-09 06:54:09 +00:00
controller.media_info = MediaInfo()
controller.media_info.volume = 0
2012-12-11 19:55:47 +00:00
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
2012-09-09 06:54:09 +00:00
display = controller.previewDisplay
if not self._check_file_type(controller, display, serviceItem):
2012-09-09 06:54:09 +00:00
# Media could not be loaded correctly
2012-12-11 19:55:47 +00:00
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
unicode(translate('MediaPlugin.MediaItem', 'Unsupported File')))
2012-09-09 06:54:09 +00:00
return False
2012-10-26 20:20:23 +00:00
if not self.media_play(controller):
2012-12-11 19:55:47 +00:00
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
unicode(translate('MediaPlugin.MediaItem', 'Unsupported File')))
2012-09-09 06:54:09 +00:00
return False
2012-09-14 16:35:07 +00:00
serviceItem.set_media_length(controller.media_info.length)
2012-10-26 20:20:23 +00:00
self.media_stop(controller)
2012-12-11 19:55:47 +00:00
log.debug(u'use %s controller' % self.currentMediaPlayer[controller.controllerType])
2012-09-09 06:54:09 +00:00
return True
def _check_file_type(self, controller, display, serviceItem):
2011-06-05 21:10:49 +00:00
"""
2011-12-02 21:13:05 +00:00
Select the correct media Player type from the prioritized Player list
2012-10-06 08:10:28 +00:00
``controller``
First element is the controller which should be used
``serviceItem``
The ServiceItem containing the details to be played.
2011-06-05 21:10:49 +00:00
"""
usedPlayers = get_media_players()[0]
2012-11-22 22:02:40 +00:00
if serviceItem.title != UiStrings().Automatic:
usedPlayers = [serviceItem.title.lower()]
2011-06-05 21:10:49 +00:00
if controller.media_info.file_info.isFile():
2012-12-11 19:55:47 +00:00
suffix = u'*.%s' % controller.media_info.file_info.suffix().toLower()
2011-11-11 16:45:25 +00:00
for title in usedPlayers:
player = self.mediaPlayers[title]
if suffix in player.video_extensions_list:
2012-12-11 19:55:47 +00:00
if not controller.media_info.is_background or controller.media_info.is_background and \
player.canBackground:
2012-10-29 16:54:39 +00:00
self.resize(display, player)
2011-12-02 21:13:05 +00:00
if player.load(display):
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType] = player
2011-12-02 21:13:05 +00:00
controller.media_info.media_type = MediaType.Video
return True
2011-11-11 16:45:25 +00:00
if suffix in player.audio_extensions_list:
if player.load(display):
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType] = player
2011-08-29 19:55:58 +00:00
controller.media_info.media_type = MediaType.Audio
return True
2011-09-22 18:22:35 +00:00
else:
2011-11-11 16:45:25 +00:00
for title in usedPlayers:
player = self.mediaPlayers[title]
if player.canFolder:
2012-11-01 18:45:12 +00:00
self.resize(display, player)
2011-11-11 16:45:25 +00:00
if player.load(display):
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType] = player
2011-09-22 18:22:35 +00:00
controller.media_info.media_type = MediaType.Video
return True
2011-11-11 16:45:25 +00:00
# no valid player found
2011-06-05 21:10:49 +00:00
return False
2012-10-26 20:20:23 +00:00
def media_play_msg(self, msg, status=True):
2011-06-05 21:10:49 +00:00
"""
Responds to the request to play a loaded video
2011-12-03 20:35:53 +00:00
2012-04-28 11:13:16 +00:00
``msg``
2011-11-24 21:10:37 +00:00
First element is the controller which should be used
2011-06-05 21:10:49 +00:00
"""
2012-10-26 20:20:23 +00:00
log.debug(u'media_play_msg')
self.media_play(msg[0],status)
def media_play(self, controller, status=True):
"""
Responds to the request to play a loaded video
``controller``
2012-10-29 17:25:08 +00:00
The controller to be played
2012-10-26 20:20:23 +00:00
"""
2012-10-15 18:38:58 +00:00
log.debug(u'media_play')
2012-12-21 19:11:00 +00:00
controller.seekSlider.blockSignals(True)
controller.volumeSlider.blockSignals(True)
2012-10-29 17:25:08 +00:00
display = self._define_display(controller)
2012-11-16 21:46:17 +00:00
if not self.currentMediaPlayer[controller.controllerType].play(display):
2012-12-24 21:04:52 +00:00
controller.seekSlider.blockSignals(False)
controller.volumeSlider.blockSignals(False)
2012-10-29 17:25:08 +00:00
return False
2012-12-13 18:55:11 +00:00
if controller.media_info.is_background:
self.media_volume(controller, 0)
else:
self.media_volume(controller, controller.media_info.volume)
2012-10-29 17:25:08 +00:00
if status:
display.frame.evaluateJavaScript(u'show_blank("desktop");')
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType].set_visible(display, True)
2012-12-03 19:18:28 +00:00
# Flash needs to be played and will not AutoPlay
if controller.media_info.is_flash:
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
controller.mediabar.actions[u'playbackPause'].setVisible(False)
else:
controller.mediabar.actions[u'playbackPlay'].setVisible(False)
controller.mediabar.actions[u'playbackPause'].setVisible(True)
2012-11-17 07:59:25 +00:00
controller.mediabar.actions[u'playbackStop'].setVisible(True)
2012-10-29 17:25:08 +00:00
if controller.isLive:
if controller.hideMenu.defaultAction().isChecked():
controller.hideMenu.defaultAction().trigger()
2011-06-05 21:10:49 +00:00
# Start Timer for ui updates
2011-09-22 18:22:35 +00:00
if not self.timer.isActive():
self.timer.start()
2012-12-21 19:11:00 +00:00
controller.seekSlider.blockSignals(False)
controller.volumeSlider.blockSignals(False)
2011-08-29 19:55:58 +00:00
return True
2011-06-05 21:10:49 +00:00
2012-10-26 20:20:23 +00:00
def media_pause_msg(self, msg):
"""
Responds to the request to pause a loaded video
``msg``
First element is the controller which should be used
"""
log.debug(u'media_pause_msg')
self.media_pause( msg[0])
def media_pause(self, controller):
2011-06-05 21:10:49 +00:00
"""
Responds to the request to pause a loaded video
2011-11-24 21:10:37 +00:00
2012-10-29 17:25:08 +00:00
``controller``
The Controller to be paused
2011-06-05 21:10:49 +00:00
"""
2012-10-15 18:38:58 +00:00
log.debug(u'media_pause')
2012-10-29 17:25:08 +00:00
display = self._define_display(controller)
2012-11-16 21:46:17 +00:00
self.currentMediaPlayer[controller.controllerType].pause(display)
2012-11-17 07:59:25 +00:00
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
controller.mediabar.actions[u'playbackStop'].setVisible(True)
controller.mediabar.actions[u'playbackPause'].setVisible(False)
2011-06-05 21:10:49 +00:00
2012-10-26 20:20:23 +00:00
def media_stop_msg(self, msg):
"""
Responds to the request to stop a loaded video
``msg``
First element is the controller which should be used
"""
log.debug(u'media_stop_msg')
self.media_stop(msg[0])
2012-10-26 20:20:23 +00:00
def media_stop(self, controller):
2011-06-05 21:10:49 +00:00
"""
Responds to the request to stop a loaded video
2011-11-24 21:10:37 +00:00
2012-10-29 17:25:08 +00:00
``controller``
The controller that needs to be stopped
2011-06-05 21:10:49 +00:00
"""
2012-10-15 18:38:58 +00:00
log.debug(u'media_stop')
2012-10-29 17:25:08 +00:00
display = self._define_display(controller)
2012-11-29 20:46:16 +00:00
if controller.controllerType in self.currentMediaPlayer:
2012-10-29 17:25:08 +00:00
display.frame.evaluateJavaScript(u'show_blank("black");')
2012-11-16 21:46:17 +00:00
self.currentMediaPlayer[controller.controllerType].stop(display)
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
2012-10-29 17:25:08 +00:00
controller.seekSlider.setSliderPosition(0)
2012-11-17 07:59:25 +00:00
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
controller.mediabar.actions[u'playbackStop'].setVisible(False)
controller.mediabar.actions[u'playbackPause'].setVisible(False)
2011-06-05 21:10:49 +00:00
2012-12-13 18:55:11 +00:00
def media_volume_msg(self, msg):
2011-06-05 21:10:49 +00:00
"""
Changes the volume of a running video
2011-11-24 21:10:37 +00:00
``msg``
First element is the controller which should be used
2011-06-05 21:10:49 +00:00
"""
controller = msg[0]
2011-06-08 14:49:48 +00:00
vol = msg[1][0]
2012-12-13 18:55:11 +00:00
self.media_volume(controller, vol)
def media_volume(self, controller, volume):
"""
Changes the volume of a running video
``msg``
First element is the controller which should be used
"""
log.debug(u'media_volume %d' % volume)
2012-10-29 17:25:08 +00:00
display = self._define_display(controller)
2012-12-13 18:55:11 +00:00
self.currentMediaPlayer[controller.controllerType].volume(display, volume)
controller.volumeSlider.setValue(volume)
2011-06-05 21:10:49 +00:00
2012-12-29 20:54:25 +00:00
def media_seek_msg(self, msg):
2011-06-05 21:10:49 +00:00
"""
Responds to the request to change the seek Slider of a loaded video
2011-11-24 21:10:37 +00:00
``msg``
First element is the controller which should be used
Second element is a list with the seek Value as first element
2011-06-05 21:10:49 +00:00
"""
2012-10-15 18:38:58 +00:00
log.debug(u'media_seek')
2011-06-05 21:10:49 +00:00
controller = msg[0]
2011-06-08 14:49:48 +00:00
seekVal = msg[1][0]
2012-12-29 20:54:25 +00:00
self.media_seek(controller, seekVal)
def media_seek(self, controller, seekVal):
"""
Responds to the request to change the seek Slider of a loaded video
``msg``
First element is the controller which should be used
Second element is a list with the seek Value as first element
"""
log.debug(u'media_seek')
2012-11-01 18:45:12 +00:00
display = self._define_display(controller)
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType].seek(display, seekVal)
2011-06-05 21:10:49 +00:00
2012-10-15 18:38:58 +00:00
def media_reset(self, controller):
2011-06-05 21:10:49 +00:00
"""
Responds to the request to reset a loaded video
"""
2012-10-15 18:38:58 +00:00
log.debug(u'media_reset')
2012-01-11 20:51:11 +00:00
self.set_controls_visible(controller, False)
2012-10-29 17:25:08 +00:00
display = self._define_display(controller)
2012-12-02 08:06:08 +00:00
if controller.controllerType in self.currentMediaPlayer:
2012-10-29 17:25:08 +00:00
display.override = {}
2012-11-16 21:46:17 +00:00
self.currentMediaPlayer[controller.controllerType].reset(display)
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"hidden");')
2012-11-16 21:46:17 +00:00
del self.currentMediaPlayer[controller.controllerType]
2011-06-05 21:10:49 +00:00
2012-10-15 18:38:58 +00:00
def media_hide(self, msg):
2011-06-05 21:10:49 +00:00
"""
Hide the related video Widget
2011-11-24 21:10:37 +00:00
``msg``
First element is the boolean for Live indication
2011-06-05 21:10:49 +00:00
"""
isLive = msg[1]
2012-04-28 11:13:16 +00:00
if not isLive:
return
2012-10-04 17:28:49 +00:00
controller = self.mainWindow.liveController
2012-10-31 18:27:24 +00:00
display = self._define_display(controller)
2012-12-11 19:55:47 +00:00
if self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
2012-11-16 21:46:17 +00:00
self.currentMediaPlayer[controller.controllerType].pause(display)
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
2011-06-05 21:10:49 +00:00
2012-10-15 18:38:58 +00:00
def media_blank(self, msg):
2011-06-05 21:10:49 +00:00
"""
Blank the related video Widget
2011-11-24 21:10:37 +00:00
``msg``
First element is the boolean for Live indication
Second element is the hide mode
2011-06-05 21:10:49 +00:00
"""
isLive = msg[1]
2011-10-24 20:04:29 +00:00
hide_mode = msg[2]
2012-04-28 11:13:16 +00:00
if not isLive:
return
Receiver.send_message(u'live_display_hide', hide_mode)
2012-10-04 17:28:49 +00:00
controller = self.mainWindow.liveController
2012-10-31 18:27:24 +00:00
display = self._define_display(controller)
2012-12-11 19:55:47 +00:00
if self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
2012-11-16 21:46:17 +00:00
self.currentMediaPlayer[controller.controllerType].pause(display)
2012-12-11 19:55:47 +00:00
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
2011-06-05 21:10:49 +00:00
2012-10-15 18:38:58 +00:00
def media_unblank(self, msg):
2011-06-05 21:10:49 +00:00
"""
Unblank the related video Widget
2011-11-24 21:10:37 +00:00
``msg``
First element is not relevant in this context
Second element is the boolean for Live indication
2011-06-05 21:10:49 +00:00
"""
2011-10-26 20:11:15 +00:00
Receiver.send_message(u'live_display_show')
2011-06-05 21:10:49 +00:00
isLive = msg[1]
2012-04-28 11:13:16 +00:00
if not isLive:
return
2012-10-04 17:28:49 +00:00
controller = self.mainWindow.liveController
2012-10-31 18:27:24 +00:00
display = self._define_display(controller)
2012-12-07 17:47:32 +00:00
if controller.controllerType in self.currentMediaPlayer and \
self.currentMediaPlayer[controller.controllerType].state != MediaState.Playing:
2012-11-16 21:46:17 +00:00
if self.currentMediaPlayer[controller.controllerType].play(display):
2012-12-07 17:47:32 +00:00
self.currentMediaPlayer[controller.controllerType].set_visible(display, True)
2012-04-28 11:13:16 +00:00
# Start Timer for ui updates
if not self.timer.isActive():
self.timer.start()
2011-06-05 21:10:49 +00:00
2011-07-20 21:16:36 +00:00
def finalise(self):
2011-09-22 18:22:35 +00:00
self.timer.stop()
2012-10-30 19:38:48 +00:00
for controller in self.displayControllers:
self.media_reset(self.displayControllers[controller])
2012-10-29 17:25:08 +00:00
def _define_display(self, controller):
"""
Extract the correct display for a given controller
2012-10-31 18:27:24 +00:00
``controller``
Controller to be used
2012-10-29 17:25:08 +00:00
"""
if controller.isLive:
return controller.display
return controller.previewDisplay