forked from openlp/openlp
update
This commit is contained in:
parent
4ab7f93044
commit
dbce448da1
@ -183,7 +183,8 @@ sup {
|
||||
case 'currentTime':
|
||||
return vid.currentTime;
|
||||
case 'seek':
|
||||
vid.currentTime = seekVal;
|
||||
// doesnt work curently
|
||||
//vid.currentTime = seekVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -327,20 +328,22 @@ sup {
|
||||
}
|
||||
}
|
||||
|
||||
function show_flash(state, path){
|
||||
// http://www.adobe.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html
|
||||
function show_flash(state, path, volume, seekVal){
|
||||
var text = document.getElementById('flash');
|
||||
var flashMovie = getFlashMovieObject("OpenLPFlashMovie");
|
||||
var src = "src = 'file:///" + path + "'";
|
||||
var view_parm = " wmode='opaque'" +
|
||||
" width='" + window.innerWidth + "'" +
|
||||
" height='" + window.innerHeight + "'";
|
||||
var swf_parm = " autostart='false' loop='false' play='false'" +
|
||||
" hidden='false' swliveconnect='true'" +
|
||||
" name='OpenLPFlashMovie'>";
|
||||
var swf_parm = " name='OpenLPFlashMovie'" +
|
||||
" autostart='true' loop='false' play='true'" +
|
||||
" hidden='false' swliveconnect='true' allowscriptaccess='always'" +
|
||||
" volume='" + volume + "'";
|
||||
|
||||
switch(state){
|
||||
case 'load':
|
||||
text.innerHTML = "<embed " + src + view_parm + swf_parm + ">";
|
||||
text.innerHTML = "<embed " + src + view_parm + swf_parm + "/>";
|
||||
flashMovie = getFlashMovieObject("OpenLPFlashMovie");
|
||||
text.style.visibility = 'visible';
|
||||
flashMovie.Play();
|
||||
@ -349,28 +352,29 @@ sup {
|
||||
text.style.visibility = 'visible';
|
||||
flashMovie.Play();
|
||||
break;
|
||||
case 'rewind':
|
||||
ret = 'rewind';
|
||||
alert(' Wert: ' + flashMovie.TGetProperty("/", 4));
|
||||
// flashMovie.TotalFrames()
|
||||
// PercentLoaded()
|
||||
// GotoFrame()
|
||||
break;
|
||||
case 'pause':
|
||||
flashMovie.StopPlay();
|
||||
text.style.visibility = 'hidden';
|
||||
break;
|
||||
case 'stop':
|
||||
flashMovie.StopPlay();
|
||||
// flashMovie.GotoFrame(0);
|
||||
text.style.visibility = 'hidden';
|
||||
tempHtml = text.innerHTML;
|
||||
text.innerHTML = '';
|
||||
text.innerHTML = tempHtml;
|
||||
break;
|
||||
case 'close':
|
||||
flashMovie.StopPlay();
|
||||
text.style.visibility = 'hidden';
|
||||
break;
|
||||
text.innerHTML = '';
|
||||
break;
|
||||
case 'length':
|
||||
return flashMovie.TotalFrames();
|
||||
case 'currentTime':
|
||||
return flashMovie.CurrentFrame();
|
||||
case 'seek':
|
||||
// flashMovie.GotoFrame(seekVal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,12 @@ class Plugin(QtCore.QObject):
|
||||
"""
|
||||
pass
|
||||
|
||||
def addControllerItems(self, controller, control_panel):
|
||||
"""
|
||||
Create items for all controller Panes
|
||||
"""
|
||||
pass
|
||||
|
||||
def getSettingsTab(self, parent):
|
||||
"""
|
||||
Create a tab for the settings window to display the configurable
|
||||
|
@ -187,6 +187,11 @@ class PluginManager(object):
|
||||
if plugin.status is not PluginStatus.Disabled:
|
||||
plugin.addToolsMenuItem(tools_menu)
|
||||
|
||||
def hook_controller_items(self, controller, control_panel):
|
||||
for plugin in self.plugins:
|
||||
if plugin.status is not PluginStatus.Disabled:
|
||||
plugin.addControllerItems(controller, control_panel)
|
||||
|
||||
def initialise_plugins(self):
|
||||
"""
|
||||
Loop through all the plugins and give them an opportunity to
|
||||
|
@ -580,6 +580,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.pluginManager.hook_export_menu(self.FileExportMenu)
|
||||
# Call the hook method to pull in tools menus.
|
||||
self.pluginManager.hook_tools_menu(self.ToolsMenu)
|
||||
# Call the hook method to pull in plugin Controller items
|
||||
self.pluginManager.hook_controller_items(
|
||||
self.previewController, self.previewController.getControlPanel())
|
||||
self.pluginManager.hook_controller_items(
|
||||
self.liveController, self.liveController.getControlPanel())
|
||||
# Call the initialise method to setup plugins.
|
||||
log.info(u'initialise plugins')
|
||||
self.pluginManager.initialise_plugins()
|
||||
|
@ -73,7 +73,6 @@ class SlideController(QtGui.QWidget):
|
||||
self.songEditList = [
|
||||
u'Edit Song',
|
||||
]
|
||||
self.volume = 10
|
||||
self.timer_id = 0
|
||||
self.songEdit = False
|
||||
self.selectedRow = 0
|
||||
@ -224,20 +223,6 @@ class SlideController(QtGui.QWidget):
|
||||
'Edit and reload song preview'),
|
||||
self.onEditSong)
|
||||
self.controllerLayout.addWidget(self.toolbar)
|
||||
# Build a Media ToolBar
|
||||
self.mediabar = OpenLPToolbar(self)
|
||||
self.mediabar.addToolbarButton(
|
||||
u'Media Start', u':/slides/media_playback_start.png',
|
||||
translate('OpenLP.SlideController', 'Start playing media'),
|
||||
self.onMediaPlay)
|
||||
self.mediabar.addToolbarButton(
|
||||
u'Media Pause', u':/slides/media_playback_pause.png',
|
||||
translate('OpenLP.SlideController', 'Start playing media'),
|
||||
self.onMediaPause)
|
||||
self.mediabar.addToolbarButton(
|
||||
u'Media Stop', u':/slides/media_playback_stop.png',
|
||||
translate('OpenLP.SlideController', 'Start playing media'),
|
||||
self.onMediaStop)
|
||||
if self.isLive:
|
||||
# Build the Song Toolbar
|
||||
self.songMenu = QtGui.QToolButton(self.toolbar)
|
||||
@ -247,22 +232,6 @@ class SlideController(QtGui.QWidget):
|
||||
self.songMenu.setMenu(QtGui.QMenu(
|
||||
translate('OpenLP.SlideController', 'Go To'), self.toolbar))
|
||||
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
||||
# Build the seekSlider.
|
||||
self.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
self.seekSlider.setMaximum(1000)
|
||||
# Build the volumeSlider.
|
||||
self.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
self.volumeSlider.setTickInterval(1)
|
||||
self.volumeSlider.setTickPosition(QtGui.QSlider.TicksAbove)
|
||||
self.volumeSlider.setMinimum(0)
|
||||
self.volumeSlider.setMaximum(10)
|
||||
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
|
||||
self.seekSlider.setObjectName(u'seekSlider')
|
||||
self.mediabar.addToolbarWidget(u'Seek Slider', self.seekSlider)
|
||||
self.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
||||
self.volumeSlider.setObjectName(u'volumeSlider')
|
||||
self.mediabar.addToolbarWidget(u'Audio Volume', self.volumeSlider)
|
||||
self.controllerLayout.addWidget(self.mediabar)
|
||||
# Screen preview area
|
||||
self.previewFrame = QtGui.QFrame(self.splitter)
|
||||
self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
|
||||
@ -302,10 +271,6 @@ class SlideController(QtGui.QWidget):
|
||||
# Signals
|
||||
QtCore.QObject.connect(self.previewListWidget,
|
||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
|
||||
QtCore.QObject.connect(self.seekSlider,
|
||||
QtCore.SIGNAL(u'sliderMoved(int)'), self.mediaSeek)
|
||||
QtCore.QObject.connect(self.volumeSlider,
|
||||
QtCore.SIGNAL(u'sliderMoved(int)'), self.mediaVolume)
|
||||
if self.isLive:
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'maindisplay_active'), self.updatePreview)
|
||||
@ -319,7 +284,6 @@ class SlideController(QtGui.QWidget):
|
||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
||||
self.onGoLiveClick)
|
||||
self.toolbar.makeWidgetsInvisible(self.songEditList)
|
||||
self.mediabar.setVisible(False)
|
||||
if self.isLive:
|
||||
self.setLiveHotkeys(self)
|
||||
self.__addActionsToWidget(self.previewListWidget)
|
||||
@ -366,6 +330,19 @@ class SlideController(QtGui.QWidget):
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_text_request' % self.typePrefix),
|
||||
self.onTextRequest)
|
||||
|
||||
def getControlPanel(self):
|
||||
return self.controllerLayout
|
||||
|
||||
def sendToPlugins(self, v1=None, v2=None, v3=None, v4=None, v5=None):
|
||||
"""
|
||||
This is the generic function to send signal for control widgets,
|
||||
created from within other plugins
|
||||
This function is needed to catch the current controller
|
||||
"""
|
||||
sender = self.sender().objectName() or self.sender().text()
|
||||
controller = self
|
||||
Receiver.send_message('%s' % sender, [controller, v1, v2, v3, v4, v5])
|
||||
|
||||
def setPreviewHotkeys(self, parent=None):
|
||||
self.previousItem.setObjectName(u'previousItemPreview')
|
||||
self.nextItem.setObjectName(u'nextItemPreview')
|
||||
@ -523,14 +500,9 @@ class SlideController(QtGui.QWidget):
|
||||
Allows the Preview toolbar to be customised
|
||||
"""
|
||||
self.toolbar.setVisible(True)
|
||||
self.mediabar.setVisible(False)
|
||||
self.toolbar.makeWidgetsInvisible(self.songEditList)
|
||||
if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin:
|
||||
self.toolbar.makeWidgetsVisible(self.songEditList)
|
||||
elif item.is_media():
|
||||
#self.toolbar.setVisible(False)
|
||||
self.mediabar.setVisible(True)
|
||||
# self.volumeSlider.setAudioOutput(self.audio)
|
||||
|
||||
def refreshServiceItem(self):
|
||||
"""
|
||||
@ -1089,58 +1061,15 @@ class SlideController(QtGui.QWidget):
|
||||
"""
|
||||
log.debug(u'SlideController onMediaStart')
|
||||
file = os.path.join(item.get_frame_path(), item.get_frame_title())
|
||||
Receiver.send_message(u'media_video', [self, file, self.volume, False])
|
||||
self.volumeSlider.setValue(self.volume)
|
||||
Receiver.send_message(u'media_video', [self, file, False])
|
||||
self.slidePreview.hide()
|
||||
|
||||
def mediaSeek(self):
|
||||
"""
|
||||
Respond to the release of Seek Slider
|
||||
"""
|
||||
log.debug(u'SlideController mediaSeek')
|
||||
self.seekPos = self.seekSlider.value()
|
||||
Receiver.send_message(u'media_seek', [self, self.seekPos])
|
||||
|
||||
def mediaVolume(self):
|
||||
"""
|
||||
Respond to the release of Volume Slider
|
||||
"""
|
||||
log.debug(u'SlideController mediaVolume')
|
||||
self.volume = self.volumeSlider.value()
|
||||
Receiver.send_message(u'media_volume', [self, self.volume])
|
||||
|
||||
|
||||
def onMediaPause(self):
|
||||
"""
|
||||
Respond to the Pause from the media Toolbar
|
||||
"""
|
||||
log.debug(u'SlideController onMediaPause')
|
||||
Receiver.send_message(u'media_pause', self)
|
||||
|
||||
def onMediaPlay(self):
|
||||
"""
|
||||
Respond to the Play from the media Toolbar
|
||||
"""
|
||||
log.debug(u'SlideController onMediaPlay')
|
||||
Receiver.send_message(u'media_play', self)
|
||||
self.slidePreview.hide()
|
||||
|
||||
def onMediaStop(self):
|
||||
"""
|
||||
Respond to the Stop from the media Toolbar
|
||||
"""
|
||||
log.debug(u'SlideController onMediaStop')
|
||||
Receiver.send_message(u'media_stop', self)
|
||||
self.slidePreview.clear()
|
||||
self.slidePreview.show()
|
||||
|
||||
def onMediaClose(self):
|
||||
"""
|
||||
Respond to a request to close the Video
|
||||
"""
|
||||
log.debug(u'SlideController onMediaClose')
|
||||
Receiver.send_message(u'media_reset', self)
|
||||
self.slidePreview.clear()
|
||||
self.slidePreview.show()
|
||||
|
||||
def _resetBlank(self):
|
||||
|
@ -24,9 +24,9 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
class MediaBackends(object):
|
||||
class MediaAPIs(object):
|
||||
"""
|
||||
An enumeration for possible Backends.
|
||||
An enumeration for possible APIs.
|
||||
"""
|
||||
Webkit = 0
|
||||
Phonon = 1
|
||||
@ -43,10 +43,32 @@ class MediaState(object):
|
||||
Paused = 4
|
||||
Off = 6
|
||||
|
||||
class MediaController(object):
|
||||
class MediaType(object):
|
||||
"""
|
||||
Specialiced MediaController class
|
||||
to reflect Features of the related backend
|
||||
"""
|
||||
Audio = 0
|
||||
Video = 1
|
||||
Cd = 3
|
||||
Dvd = 4
|
||||
|
||||
class MediaInfo(object):
|
||||
"""
|
||||
This class hold the media related infos
|
||||
"""
|
||||
file_info = None
|
||||
volume = 100
|
||||
isFlash = False
|
||||
is_background = False
|
||||
length = 0
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
media_type = MediaType()
|
||||
|
||||
|
||||
class MediaAPI(object):
|
||||
"""
|
||||
Specialiced Media API class
|
||||
to reflect Features of the related API
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
@ -57,19 +79,19 @@ class MediaController(object):
|
||||
self.audio_extensions_list = []
|
||||
self.video_extensions_list = []
|
||||
|
||||
def setup(self, display, hasAudio):
|
||||
def setup(self, display):
|
||||
"""
|
||||
Create the related widgets for the current display
|
||||
"""
|
||||
pass
|
||||
|
||||
def load(self, display, path, volume, isBackground):
|
||||
def load(self, display):
|
||||
"""
|
||||
Load a new media file and check if it is valid
|
||||
"""
|
||||
return True
|
||||
|
||||
def resize(self, display, controller):
|
||||
def resize(self, display):
|
||||
"""
|
||||
If the main display size or position is changed,
|
||||
the media widgets should also resized
|
||||
@ -118,7 +140,7 @@ class MediaController(object):
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_ui(self, controller, display):
|
||||
def update_ui(self, display):
|
||||
"""
|
||||
Do some ui related stuff
|
||||
(e.g. update the seek slider)
|
||||
@ -128,7 +150,7 @@ class MediaController(object):
|
||||
@staticmethod
|
||||
def is_available():
|
||||
"""
|
||||
Check availability of the related backend
|
||||
Check availability of the related API
|
||||
"""
|
||||
return False
|
||||
|
||||
@ -143,6 +165,6 @@ class MediaController(object):
|
||||
|
||||
from mediaitem import MediaMediaItem
|
||||
from mediatab import MediaTab
|
||||
from mediacontroller import MediaManager
|
||||
from mediamanager import MediaManager
|
||||
|
||||
__all__ = ['MediaMediaItem']
|
||||
|
@ -1,356 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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
|
||||
|
||||
import sys, os
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.plugins.media.lib import MediaBackends, MediaState
|
||||
from webkitcontroller import WebkitController
|
||||
from phononcontroller import PhononController
|
||||
from vlccontroller import VlcController
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class MediaManager(object):
|
||||
"""
|
||||
The implementation of a Media Manager
|
||||
The idea is to separate the media related implementation
|
||||
into the plugin files and unify the access from other parts of code
|
||||
The media manager adds an own class for every type of backend
|
||||
Currently these are QtWebkit, Phonon and planed Vlc.
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
self.backends = {}
|
||||
self.curDisplayMediaController = {}
|
||||
#Create Backend Controllers
|
||||
if WebkitController.is_available():
|
||||
self.backends[u'Webkit'] = WebkitController(self)
|
||||
if PhononController.is_available():
|
||||
self.backends[u'Phonon'] = PhononController(self)
|
||||
if VlcController.is_available():
|
||||
self.backends[u'Vlc'] = VlcController(self)
|
||||
#Timer for video state
|
||||
self.Timer = QtCore.QTimer()
|
||||
self.Timer.setInterval(200)
|
||||
self.withLivePreview = False
|
||||
#Signals
|
||||
QtCore.QObject.connect(self.Timer,
|
||||
QtCore.SIGNAL("timeout()"), self.video_state)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'setup_display'), self.setup_display)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_video'), self.video)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_play'), self.video_play)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_pause'), self.video_pause)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_stop'), self.video_stop)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_seek'), self.video_seek)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_volume'), self.video_volume)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_reset'), self.video_reset)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_hide'), self.video_hide)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_blank'), self.video_blank)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_unblank'), self.video_unblank)
|
||||
|
||||
def video_state(self):
|
||||
"""
|
||||
Check if there is an assigned media backend and do some
|
||||
updating stuff (e.g. update the UI)
|
||||
"""
|
||||
isAnyonePlaying = False
|
||||
if len(self.curDisplayMediaController.keys()) == 0:
|
||||
self.Timer.stop()
|
||||
else:
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display == self.parent.previewController.previewDisplay or \
|
||||
display == self.parent.previewController.display:
|
||||
self.curDisplayMediaController[display] \
|
||||
.update_ui(self.parent.previewController, display)
|
||||
else:
|
||||
self.curDisplayMediaController[display] \
|
||||
.update_ui(self.parent.liveController, display)
|
||||
if self.curDisplayMediaController[display] \
|
||||
.state == MediaState.Playing:
|
||||
isAnyonePlaying = True
|
||||
if not isAnyonePlaying:
|
||||
self.Timer.stop()
|
||||
|
||||
def setup_display(self, display):
|
||||
"""
|
||||
After a new display is configured, all media related widget
|
||||
will be created too
|
||||
"""
|
||||
hasAudio = True
|
||||
if not self.withLivePreview and \
|
||||
display == self.parent.liveController.previewDisplay:
|
||||
return
|
||||
if display == self.parent.previewController.previewDisplay or \
|
||||
display == self.parent.liveController.previewDisplay:
|
||||
hasAudio = False
|
||||
for backend in self.backends.values():
|
||||
backend.setup(display, hasAudio)
|
||||
|
||||
def resize(self, controller):
|
||||
"""
|
||||
After Mainwindow changes or Splitter moved all related media
|
||||
widgets have to be resized
|
||||
"""
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display == self.parent.previewController.previewDisplay or \
|
||||
display == self.parent.liveController.previewDisplay:
|
||||
display.resize(display.parent.slidePreview.size())
|
||||
self.curDisplayMediaController[display].resize(display, controller)
|
||||
|
||||
def video(self, msg):
|
||||
"""
|
||||
Loads and starts a video to run with the option of sound
|
||||
"""
|
||||
controller = msg[0]
|
||||
videoPath = os.path.abspath(msg[1])
|
||||
volume = msg[2]
|
||||
isBackground = msg[3]
|
||||
log.debug(u'video')
|
||||
vol = float(volume) / float(10)
|
||||
isValid = False
|
||||
#stop running videos
|
||||
self.video_reset(controller)
|
||||
if controller.isLive:
|
||||
if self.withLivePreview:
|
||||
display = controller.previewDisplay
|
||||
if self.check_file_type(display, videoPath, False):
|
||||
#check size of all media_widgets
|
||||
self.resize(controller)
|
||||
self.curDisplayMediaController[display] \
|
||||
.load(display, videoPath, volume, isBackground)
|
||||
display = controller.display
|
||||
if self.check_file_type(display, videoPath, isBackground):
|
||||
#check size of all media_widgets
|
||||
self.resize(controller)
|
||||
isValid = self.curDisplayMediaController[display] \
|
||||
.load(display, videoPath, volume, isBackground)
|
||||
else:
|
||||
display = controller.previewDisplay
|
||||
if self.check_file_type(display, videoPath, isBackground):
|
||||
#check size of all media_widgets
|
||||
self.resize(controller)
|
||||
isValid = self.curDisplayMediaController[display] \
|
||||
.load(display, videoPath, volume, isBackground)
|
||||
if not isValid:
|
||||
#Media could not be loaded correctly
|
||||
critical_error_message_box(
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
unicode(translate('MediaPlugin.MediaItem',
|
||||
'Unsupported File')))
|
||||
return
|
||||
# controller.display.webLoaded = True
|
||||
#now start playing
|
||||
self.video_play(controller)
|
||||
|
||||
def check_file_type(self, display, videoPath, isBackground):
|
||||
"""
|
||||
Used to choose the right media backend type
|
||||
from the prioritized backend list
|
||||
"""
|
||||
usedBackends = QtCore.QSettings().value(u'media/backends',
|
||||
QtCore.QVariant(u'Webkit')).toString().split(u',')
|
||||
media_path = QtCore.QFileInfo(videoPath)
|
||||
if media_path.isFile():
|
||||
suffix = u'*.%s' % media_path.suffix()
|
||||
for title in usedBackends:
|
||||
backend = self.backends[str(title)]
|
||||
if suffix in backend.video_extensions_list:
|
||||
if isBackground:
|
||||
if backend.canBackground:
|
||||
self.curDisplayMediaController[display] = backend
|
||||
return True
|
||||
else:
|
||||
self.curDisplayMediaController[display] = backend
|
||||
return True
|
||||
return False
|
||||
# # Special FileType Check
|
||||
# if videoPath.endswith(u'.swf') or isBackground:
|
||||
# self.curDisplayMediaController[display] = self.backends[u'Webkit']
|
||||
# else:
|
||||
# # search extension in available backends
|
||||
# # currently only use the first available backend
|
||||
# self.curDisplayMediaController[display] = self.backends[str(usedBackends[0])]
|
||||
# return True
|
||||
|
||||
def video_play(self, controller):
|
||||
"""
|
||||
Responds to the request to play a loaded video
|
||||
"""
|
||||
log.debug(u'video_play')
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaController[display].play(display)
|
||||
# show screen
|
||||
if not self.Timer.isActive():
|
||||
self.Timer.start()
|
||||
|
||||
def video_pause(self, controller):
|
||||
"""
|
||||
Responds to the request to pause a loaded video
|
||||
"""
|
||||
log.debug(u'videoPause')
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaController[display].pause(display)
|
||||
|
||||
def video_stop(self, controller):
|
||||
"""
|
||||
Responds to the request to stop a loaded video
|
||||
"""
|
||||
log.debug(u'video_stop')
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaController[display].stop(display)
|
||||
self.curDisplayMediaController[display].set_visible(display, False)
|
||||
|
||||
def video_volume(self, msg):
|
||||
"""
|
||||
Changes the volume of a running video
|
||||
"""
|
||||
controller = msg[0]
|
||||
volume = msg[1]
|
||||
log.debug(u'video_volume %d' % volume)
|
||||
vol = float(volume) / float(10)
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaController[display].volume(display, vol)
|
||||
|
||||
def video_finished(self):
|
||||
"""
|
||||
Blank the Video when it has finished so the final frame is not left
|
||||
hanging
|
||||
"""
|
||||
display.videoStop()
|
||||
display.hideDisplay(HideMode.Blank)
|
||||
display.videoHide = True
|
||||
|
||||
def video_tick(self, tick):
|
||||
"""
|
||||
Triggered on video tick every 200 milli seconds
|
||||
"""
|
||||
if tick > display.serviceItem.end_time * 1000:
|
||||
display.videoFinished()
|
||||
|
||||
def video_seek(self, msg):
|
||||
"""
|
||||
Responds to the request to change the seek Slider of a loaded video
|
||||
"""
|
||||
log.debug(u'video_seek')
|
||||
controller = msg[0]
|
||||
seekVal = msg[1]
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaController[display].seek(display, seekVal)
|
||||
|
||||
def video_reset(self, controller):
|
||||
"""
|
||||
Responds to the request to reset a loaded video
|
||||
"""
|
||||
log.debug(u'video_reset')
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaController[display].reset(display)
|
||||
del self.curDisplayMediaController[display]
|
||||
|
||||
def video_hide(self, msg):
|
||||
"""
|
||||
Hide the related video Widget
|
||||
"""
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
if self.curDisplayMediaController[display] \
|
||||
.state == MediaState.Playing:
|
||||
self.curDisplayMediaController[display].pause(display)
|
||||
self.curDisplayMediaController[display] \
|
||||
.set_visible(display, False)
|
||||
|
||||
def video_blank(self, msg):
|
||||
"""
|
||||
Blank the related video Widget
|
||||
"""
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
if self.curDisplayMediaController[display] \
|
||||
.state == MediaState.Playing:
|
||||
self.curDisplayMediaController[display].pause(display)
|
||||
self.curDisplayMediaController[display] \
|
||||
.set_visible(display, False)
|
||||
|
||||
def video_unblank(self, msg):
|
||||
"""
|
||||
Unblank the related video Widget
|
||||
"""
|
||||
Receiver.send_message(u'maindisplay_show')
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaController.keys():
|
||||
if display.parent == controller:
|
||||
if self.curDisplayMediaController[display] \
|
||||
.state == MediaState.Paused:
|
||||
self.curDisplayMediaController[display].play(display)
|
||||
self.curDisplayMediaController[display] \
|
||||
.set_visible(display, True)
|
||||
|
||||
def get_audio_extensions_list(self):
|
||||
audio_list = []
|
||||
for backend in self.backends.values():
|
||||
for item in backend.audio_extensions_list:
|
||||
if not item in audio_list:
|
||||
audio_list.append(item)
|
||||
return audio_list
|
||||
|
||||
def get_video_extensions_list(self):
|
||||
video_list = []
|
||||
for backend in self.backends.values():
|
||||
for item in backend.video_extensions_list:
|
||||
if not item in video_list:
|
||||
video_list.append(item)
|
||||
return video_list
|
@ -137,7 +137,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
ItemCapabilities.AllowsVariableStartTime)
|
||||
service_item.title = unicode(self.plugin.nameStrings[u'singular'])
|
||||
service_item.add_capability(ItemCapabilities.RequiresMedia)
|
||||
#Receiver.send_message(u'media_video', [self.parent.liveController, filename, 0, False])
|
||||
#Receiver.send_message(u'media_video', [self.parent.liveController, filename, False])
|
||||
# force a non-existent theme
|
||||
service_item.theme = -1
|
||||
frame = u':/media/image_clapperboard.png'
|
||||
|
385
openlp/plugins/media/lib/mediamanager.py
Normal file
385
openlp/plugins/media/lib/mediamanager.py
Normal file
@ -0,0 +1,385 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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
|
||||
|
||||
import sys, os,time
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, Receiver, translate
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.plugins.media.lib import MediaAPI, MediaState, MediaInfo
|
||||
from webkitapi import WebkitAPI
|
||||
from phononapi import PhononAPI
|
||||
from vlcapi import VlcAPI
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class MediaManager(object):
|
||||
"""
|
||||
The implementation of a Media Manager
|
||||
The idea is to separate the media related implementation
|
||||
into the plugin files and unify the access from other parts of code
|
||||
The media manager adds an own class for every API
|
||||
Currently these are QtWebkit, Phonon and planed Vlc.
|
||||
Manager
|
||||
- different API classes with specialised Access functions
|
||||
|
||||
Controller
|
||||
- have general and API specific control Elements
|
||||
- have one or more displays (Preview, Live, ...) with different settings
|
||||
|
||||
Display
|
||||
- have API-Specific Display Elements
|
||||
- have media info for current media
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
self.APIs = {}
|
||||
self.controller = []
|
||||
self.curDisplayMediaAPI = {}
|
||||
#Create API Controllers
|
||||
if WebkitAPI.is_available():
|
||||
self.APIs[u'Webkit'] = WebkitAPI(self)
|
||||
if PhononAPI.is_available():
|
||||
self.APIs[u'Phonon'] = PhononAPI(self)
|
||||
if VlcAPI.is_available():
|
||||
self.APIs[u'Vlc'] = VlcAPI(self)
|
||||
#Timer for video state
|
||||
self.Timer = QtCore.QTimer()
|
||||
self.Timer.setInterval(200)
|
||||
self.withLivePreview = False
|
||||
#Signals
|
||||
QtCore.QObject.connect(self.Timer,
|
||||
QtCore.SIGNAL("timeout()"), self.video_state)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'setup_display'), self.setup_display)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_video'), self.video)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'Media Start'), self.video_play)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'Media Pause'), self.video_pause)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'Media Stop'), self.video_stop)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'seekSlider'), self.video_seek)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'volumeSlider'), self.video_volume)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_reset'), self.video_reset)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_hide'), self.video_hide)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_blank'), self.video_blank)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_unblank'), self.video_unblank)
|
||||
|
||||
def video_state(self):
|
||||
"""
|
||||
Check if there is an assigned media API and do some
|
||||
updating stuff (e.g. update the UI)
|
||||
"""
|
||||
isAnyonePlaying = False
|
||||
if len(self.curDisplayMediaAPI.keys()) == 0:
|
||||
self.Timer.stop()
|
||||
else:
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
self.curDisplayMediaAPI[display].update_ui(display)
|
||||
if self.curDisplayMediaAPI[display] \
|
||||
.state == MediaState.Playing:
|
||||
isAnyonePlaying = True
|
||||
if not isAnyonePlaying:
|
||||
self.Timer.stop()
|
||||
|
||||
def addControllerItems(self, controller, control_panel):
|
||||
self.controller.append(controller)
|
||||
self.setup_generic_controls(controller, control_panel)
|
||||
for api in self.APIs.values():
|
||||
api.setup_controls(controller, control_panel)
|
||||
|
||||
def setup_generic_controls(self, controller, control_panel):
|
||||
controller.media_info = MediaInfo()
|
||||
# Build a Media ToolBar
|
||||
controller.mediabar = OpenLPToolbar(controller)
|
||||
controller.mediabar.addToolbarButton(
|
||||
u'Media Start', u':/slides/media_playback_start.png',
|
||||
translate('OpenLP.SlideController', 'Start playing media'),
|
||||
controller.sendToPlugins)
|
||||
controller.mediabar.addToolbarButton(
|
||||
u'Media Pause', u':/slides/media_playback_pause.png',
|
||||
translate('OpenLP.SlideController', 'Start playing media'),
|
||||
controller.sendToPlugins)
|
||||
controller.mediabar.addToolbarButton(
|
||||
u'Media Stop', u':/slides/media_playback_stop.png',
|
||||
translate('OpenLP.SlideController', 'Start playing media'),
|
||||
controller.sendToPlugins)
|
||||
# Build the seekSlider.
|
||||
controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
controller.seekSlider.setMaximum(1000)
|
||||
# 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.setValue(controller.media_info.volume)
|
||||
controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
|
||||
controller.seekSlider.setObjectName(u'seekSlider')
|
||||
controller.mediabar.addToolbarWidget(u'Seek Slider', controller.seekSlider)
|
||||
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
||||
controller.volumeSlider.setObjectName(u'volumeSlider')
|
||||
controller.mediabar.addToolbarWidget(u'Audio Volume', controller.volumeSlider)
|
||||
control_panel.addWidget(controller.mediabar)
|
||||
controller.mediabar.setVisible(False)
|
||||
#Signals
|
||||
QtCore.QObject.connect(controller.seekSlider,
|
||||
QtCore.SIGNAL(u'sliderMoved(int)'), controller.sendToPlugins)
|
||||
QtCore.QObject.connect(controller.volumeSlider,
|
||||
QtCore.SIGNAL(u'sliderMoved(int)'), controller.sendToPlugins)
|
||||
|
||||
def setup_display(self, display):
|
||||
"""
|
||||
After a new display is configured, all media related widget
|
||||
will be created too
|
||||
"""
|
||||
display.hasAudio = True
|
||||
if not self.withLivePreview and \
|
||||
display == self.parent.liveController.previewDisplay:
|
||||
return
|
||||
if display == self.parent.previewController.previewDisplay or \
|
||||
display == self.parent.liveController.previewDisplay:
|
||||
display.hasAudio = False
|
||||
for api in self.APIs.values():
|
||||
api.setup(display)
|
||||
|
||||
def set_controls_visible(self, controller, value):
|
||||
# Generic controls
|
||||
controller.mediabar.setVisible(value)
|
||||
# Special controls
|
||||
# for api in self.APIs.values():
|
||||
# api.setup_controls(controller, control_panel)
|
||||
|
||||
def resize(self, display, api):
|
||||
"""
|
||||
After Mainwindow changes or Splitter moved all related media
|
||||
widgets have to be resized
|
||||
"""
|
||||
if display == self.parent.previewController.previewDisplay or \
|
||||
display == self.parent.liveController.previewDisplay:
|
||||
display.resize(display.parent.slidePreview.size())
|
||||
api.resize(display)
|
||||
|
||||
def video(self, msg):
|
||||
"""
|
||||
Loads and starts a video to run with the option of sound
|
||||
"""
|
||||
log.debug(u'video')
|
||||
controller = msg[0]
|
||||
isValid = False
|
||||
# stop running videos
|
||||
self.video_reset(controller)
|
||||
controller.media_info = MediaInfo()
|
||||
controller.media_info.volume = controller.volumeSlider.value()
|
||||
controller.media_info.file_info = QtCore.QFileInfo(msg[1])
|
||||
controller.media_info.is_background = msg[2]
|
||||
if controller.isLive:
|
||||
if self.withLivePreview:
|
||||
display = controller.previewDisplay
|
||||
isValid = self.check_file_type(display)
|
||||
display = controller.display
|
||||
isValid = self.check_file_type(display)
|
||||
else:
|
||||
display = controller.previewDisplay
|
||||
isValid = self.check_file_type(display)
|
||||
if not isValid:
|
||||
#Media could not be loaded correctly
|
||||
critical_error_message_box(
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
unicode(translate('MediaPlugin.MediaItem',
|
||||
'Unsupported File')))
|
||||
return
|
||||
#now start playing
|
||||
self.video_play([controller])
|
||||
# self.video_pause([controller])
|
||||
# self.video_seek([controller, 0])
|
||||
# self.video_play([controller])
|
||||
self.set_controls_visible(controller, True)
|
||||
|
||||
def check_file_type(self, display):
|
||||
"""
|
||||
Used to choose the right media API type
|
||||
from the prioritized API list
|
||||
"""
|
||||
controller = display.parent
|
||||
apiSettings = str(QtCore.QSettings().value(u'media/apis',
|
||||
QtCore.QVariant(u'Webkit')).toString())
|
||||
usedAPIs = apiSettings.split(u',')
|
||||
if controller.media_info.file_info.isFile():
|
||||
suffix = u'*.%s' % controller.media_info.file_info.suffix()
|
||||
for title in usedAPIs:
|
||||
api = self.APIs[title]
|
||||
if suffix in api.video_extensions_list:
|
||||
if not controller.media_info.is_background or \
|
||||
controller.media_info.is_background and api.canBackground:
|
||||
self.resize(display, api)
|
||||
if api.load(display):
|
||||
print api
|
||||
self.curDisplayMediaAPI[display] = api
|
||||
return True
|
||||
# no valid api found
|
||||
return False
|
||||
|
||||
def video_play(self, msg):
|
||||
"""
|
||||
Responds to the request to play a loaded video
|
||||
"""
|
||||
log.debug(u'video_play')
|
||||
controller = msg[0]
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaAPI[display].play(display)
|
||||
# Start Timer for ui updates
|
||||
if not self.Timer.isActive():
|
||||
self.Timer.start()
|
||||
|
||||
def video_pause(self, msg):
|
||||
"""
|
||||
Responds to the request to pause a loaded video
|
||||
"""
|
||||
log.debug(u'videoPause')
|
||||
controller = msg[0]
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaAPI[display].pause(display)
|
||||
|
||||
def video_stop(self, msg):
|
||||
"""
|
||||
Responds to the request to stop a loaded video
|
||||
"""
|
||||
log.debug(u'video_stop')
|
||||
controller = msg[0]
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaAPI[display].stop(display)
|
||||
self.curDisplayMediaAPI[display].set_visible(display, False)
|
||||
|
||||
def video_volume(self, msg):
|
||||
"""
|
||||
Changes the volume of a running video
|
||||
"""
|
||||
controller = msg[0]
|
||||
vol = msg[1]
|
||||
log.debug(u'video_volume %d' % vol)
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaAPI[display].volume(display, vol)
|
||||
|
||||
def video_seek(self, msg):
|
||||
"""
|
||||
Responds to the request to change the seek Slider of a loaded video
|
||||
"""
|
||||
log.debug(u'video_seek')
|
||||
controller = msg[0]
|
||||
seekVal = msg[1]
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaAPI[display].seek(display, seekVal)
|
||||
|
||||
def video_reset(self, controller):
|
||||
"""
|
||||
Responds to the request to reset a loaded video
|
||||
"""
|
||||
log.debug(u'video_reset')
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
self.curDisplayMediaAPI[display].reset(display)
|
||||
del self.curDisplayMediaAPI[display]
|
||||
self.set_controls_visible(controller, False)
|
||||
|
||||
def video_hide(self, msg):
|
||||
"""
|
||||
Hide the related video Widget
|
||||
"""
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
if self.curDisplayMediaAPI[display] \
|
||||
.state == MediaState.Playing:
|
||||
self.curDisplayMediaAPI[display].pause(display)
|
||||
self.curDisplayMediaAPI[display] \
|
||||
.set_visible(display, False)
|
||||
|
||||
def video_blank(self, msg):
|
||||
"""
|
||||
Blank the related video Widget
|
||||
"""
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
if self.curDisplayMediaAPI[display] \
|
||||
.state == MediaState.Playing:
|
||||
self.curDisplayMediaAPI[display].pause(display)
|
||||
self.curDisplayMediaAPI[display] \
|
||||
.set_visible(display, False)
|
||||
|
||||
def video_unblank(self, msg):
|
||||
"""
|
||||
Unblank the related video Widget
|
||||
"""
|
||||
Receiver.send_message(u'maindisplay_show')
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaAPI.keys():
|
||||
if display.parent == controller:
|
||||
if self.curDisplayMediaAPI[display] \
|
||||
.state == MediaState.Paused:
|
||||
self.curDisplayMediaAPI[display].play(display)
|
||||
self.curDisplayMediaAPI[display] \
|
||||
.set_visible(display, True)
|
||||
|
||||
def get_audio_extensions_list(self):
|
||||
audio_list = []
|
||||
for api in self.APIs.values():
|
||||
for item in api.audio_extensions_list:
|
||||
if not item in audio_list:
|
||||
audio_list.append(item)
|
||||
return audio_list
|
||||
|
||||
def get_video_extensions_list(self):
|
||||
video_list = []
|
||||
for api in self.APIs.values():
|
||||
for item in api.video_extensions_list:
|
||||
if not item in video_list:
|
||||
video_list.append(item)
|
||||
return video_list
|
@ -38,52 +38,52 @@ class MediaTab(SettingsTab):
|
||||
def setupUi(self):
|
||||
self.setObjectName(u'MediaTab')
|
||||
SettingsTab.setupUi(self)
|
||||
self.mediaBackendsGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.mediaBackendsGroupBox.setObjectName(u'mediaBackendsGroupBox')
|
||||
self.mediaBackendLayout = QtGui.QVBoxLayout(self.mediaBackendsGroupBox)
|
||||
self.mediaBackendLayout.setObjectName(u'mediaBackendLayout')
|
||||
self.usePhononCheckBox = QtGui.QCheckBox(self.mediaBackendsGroupBox)
|
||||
self.mediaAPIsGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.mediaAPIsGroupBox.setObjectName(u'mediaAPIsGroupBox')
|
||||
self.mediaApiLayout = QtGui.QVBoxLayout(self.mediaAPIsGroupBox)
|
||||
self.mediaApiLayout.setObjectName(u'mediaApiLayout')
|
||||
self.usePhononCheckBox = QtGui.QCheckBox(self.mediaAPIsGroupBox)
|
||||
self.usePhononCheckBox.setObjectName(u'usePhononCheckBox')
|
||||
self.mediaBackendLayout.addWidget(self.usePhononCheckBox)
|
||||
self.useVlcCheckBox = QtGui.QCheckBox(self.mediaBackendsGroupBox)
|
||||
self.mediaApiLayout.addWidget(self.usePhononCheckBox)
|
||||
self.useVlcCheckBox = QtGui.QCheckBox(self.mediaAPIsGroupBox)
|
||||
self.useVlcCheckBox.setObjectName(u'useVlcCheckBox')
|
||||
self.mediaBackendLayout.addWidget(self.useVlcCheckBox)
|
||||
self.leftLayout.addWidget(self.mediaBackendsGroupBox)
|
||||
self.mediaApiLayout.addWidget(self.useVlcCheckBox)
|
||||
self.leftLayout.addWidget(self.mediaAPIsGroupBox)
|
||||
|
||||
self.backendOrderGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.backendOrderGroupBox.setObjectName(u'backendOrderGroupBox')
|
||||
self.backendOrderLayout = QtGui.QVBoxLayout(self.backendOrderGroupBox)
|
||||
self.backendOrderLayout.setObjectName(u'backendOrderLayout')
|
||||
self.backendOrderlistWidget = QtGui.QListWidget( \
|
||||
self.backendOrderGroupBox)
|
||||
self.apiOrderGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.apiOrderGroupBox.setObjectName(u'apiOrderGroupBox')
|
||||
self.apiOrderLayout = QtGui.QVBoxLayout(self.apiOrderGroupBox)
|
||||
self.apiOrderLayout.setObjectName(u'apiOrderLayout')
|
||||
self.apiOrderlistWidget = QtGui.QListWidget( \
|
||||
self.apiOrderGroupBox)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum,
|
||||
QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.backendOrderlistWidget. \
|
||||
sizePolicy.setHeightForWidth(self.apiOrderlistWidget. \
|
||||
sizePolicy().hasHeightForWidth())
|
||||
self.backendOrderlistWidget.setSizePolicy(sizePolicy)
|
||||
self.apiOrderlistWidget.setSizePolicy(sizePolicy)
|
||||
|
||||
self.backendOrderlistWidget.setVerticalScrollBarPolicy( \
|
||||
self.apiOrderlistWidget.setVerticalScrollBarPolicy( \
|
||||
QtCore.Qt.ScrollBarAsNeeded)
|
||||
self.backendOrderlistWidget.setHorizontalScrollBarPolicy( \
|
||||
self.apiOrderlistWidget.setHorizontalScrollBarPolicy( \
|
||||
QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self.backendOrderlistWidget.setEditTriggers( \
|
||||
self.apiOrderlistWidget.setEditTriggers( \
|
||||
QtGui.QAbstractItemView.NoEditTriggers)
|
||||
self.backendOrderlistWidget.setObjectName(u'backendOrderlistWidget')
|
||||
self.backendOrderLayout.addWidget(self.backendOrderlistWidget)
|
||||
self.orderingButtonsWidget = QtGui.QWidget(self.backendOrderGroupBox)
|
||||
self.apiOrderlistWidget.setObjectName(u'apiOrderlistWidget')
|
||||
self.apiOrderLayout.addWidget(self.apiOrderlistWidget)
|
||||
self.orderingButtonsWidget = QtGui.QWidget(self.apiOrderGroupBox)
|
||||
self.orderingButtonsWidget.setObjectName(u'orderingButtonsWidget')
|
||||
self.orderingButtonLayout = QtGui.QHBoxLayout(self.orderingButtonsWidget)
|
||||
self.orderingButtonLayout.setObjectName(u'orderingButtonLayout')
|
||||
self.orderingDownButton = QtGui.QPushButton(self.orderingButtonsWidget)
|
||||
self.orderingDownButton.setObjectName(u'orderingDownButton')
|
||||
self.orderingButtonLayout.addWidget(self.orderingDownButton)
|
||||
self.orderingUpButton = QtGui.QPushButton(self.backendOrderGroupBox)
|
||||
self.orderingUpButton = QtGui.QPushButton(self.apiOrderGroupBox)
|
||||
self.orderingUpButton.setObjectName(u'orderingUpButton')
|
||||
self.orderingButtonLayout.addWidget(self.orderingUpButton)
|
||||
self.backendOrderLayout.addWidget(self.orderingButtonsWidget)
|
||||
self.leftLayout.addWidget(self.backendOrderGroupBox)
|
||||
self.apiOrderLayout.addWidget(self.orderingButtonsWidget)
|
||||
self.leftLayout.addWidget(self.apiOrderGroupBox)
|
||||
self.leftLayout.addStretch()
|
||||
self.rightLayout.addStretch()
|
||||
QtCore.QObject.connect(self.usePhononCheckBox,
|
||||
@ -98,14 +98,14 @@ class MediaTab(SettingsTab):
|
||||
QtCore.SIGNAL(u'pressed()'), self.onOrderingDownButtonPressed)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.mediaBackendsGroupBox.setTitle(
|
||||
translate('MediaPlugin.MediaTab', 'Media Backends'))
|
||||
self.mediaAPIsGroupBox.setTitle(
|
||||
translate('MediaPlugin.MediaTab', 'Media APIs'))
|
||||
self.usePhononCheckBox.setText(
|
||||
translate('MediaPlugin.MediaTab', 'use Phonon'))
|
||||
self.useVlcCheckBox.setText(
|
||||
translate('MediaPlugin.MediaTab', 'use Vlc'))
|
||||
self.backendOrderGroupBox.setTitle(
|
||||
translate('MediaPlugin.MediaTab', 'Backends Order'))
|
||||
self.apiOrderGroupBox.setTitle(
|
||||
translate('MediaPlugin.MediaTab', 'API Order'))
|
||||
self.orderingDownButton.setText(
|
||||
translate('MediaPlugin.MediaTab', 'Down'))
|
||||
self.orderingUpButton.setText(
|
||||
@ -114,61 +114,61 @@ class MediaTab(SettingsTab):
|
||||
def onUsePhononCheckBoxChanged(self, check_state):
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
self.usePhonon = True
|
||||
if u'Phonon' not in self.usedBackends:
|
||||
self.usedBackends.append(u'Phonon')
|
||||
if u'Phonon' not in self.usedAPIs:
|
||||
self.usedAPIs.append(u'Phonon')
|
||||
else:
|
||||
self.usePhonon = False
|
||||
self.usedBackends.takeAt(self.usedBackends.indexOf(u'Phonon'))
|
||||
self.updateBackendList()
|
||||
self.usedAPIs.takeAt(self.usedAPIs.indexOf(u'Phonon'))
|
||||
self.updateApiList()
|
||||
|
||||
def onUseVlcCheckBoxChanged(self, check_state):
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
self.useVlc = True
|
||||
if u'Vlc' not in self.usedBackends:
|
||||
self.usedBackends.append(u'Vlc')
|
||||
if u'Vlc' not in self.usedAPIs:
|
||||
self.usedAPIs.append(u'Vlc')
|
||||
else:
|
||||
self.useVlc = False
|
||||
self.usedBackends.takeAt(self.usedBackends.indexOf(u'Vlc'))
|
||||
self.updateBackendList()
|
||||
self.usedAPIs.takeAt(self.usedAPIs.indexOf(u'Vlc'))
|
||||
self.updateApiList()
|
||||
|
||||
def updateBackendList(self):
|
||||
self.backendOrderlistWidget.clear()
|
||||
for backend in self.usedBackends:
|
||||
self.backendOrderlistWidget.addItem(backend)
|
||||
def updateApiList(self):
|
||||
self.apiOrderlistWidget.clear()
|
||||
for api in self.usedAPIs:
|
||||
self.apiOrderlistWidget.addItem(api)
|
||||
|
||||
def onOrderingUpButtonPressed(self):
|
||||
currentRow = self.backendOrderlistWidget.currentRow()
|
||||
currentRow = self.apiOrderlistWidget.currentRow()
|
||||
if currentRow > 0:
|
||||
item = self.backendOrderlistWidget.takeItem(currentRow)
|
||||
self.backendOrderlistWidget.insertItem(currentRow-1, item)
|
||||
self.backendOrderlistWidget.setCurrentRow(currentRow-1)
|
||||
self.usedBackends.move(currentRow, currentRow-1)
|
||||
item = self.apiOrderlistWidget.takeItem(currentRow)
|
||||
self.apiOrderlistWidget.insertItem(currentRow-1, item)
|
||||
self.apiOrderlistWidget.setCurrentRow(currentRow-1)
|
||||
self.usedAPIs.move(currentRow, currentRow-1)
|
||||
|
||||
def onOrderingDownButtonPressed(self):
|
||||
currentRow = self.backendOrderlistWidget.currentRow()
|
||||
if currentRow < self.backendOrderlistWidget.count()-1:
|
||||
item = self.backendOrderlistWidget.takeItem(currentRow)
|
||||
self.backendOrderlistWidget.insertItem(currentRow+1, item)
|
||||
self.backendOrderlistWidget.setCurrentRow(currentRow+1)
|
||||
self.usedBackends.move(currentRow, currentRow+1)
|
||||
currentRow = self.apiOrderlistWidget.currentRow()
|
||||
if currentRow < self.apiOrderlistWidget.count()-1:
|
||||
item = self.apiOrderlistWidget.takeItem(currentRow)
|
||||
self.apiOrderlistWidget.insertItem(currentRow+1, item)
|
||||
self.apiOrderlistWidget.setCurrentRow(currentRow+1)
|
||||
self.usedAPIs.move(currentRow, currentRow+1)
|
||||
|
||||
def load(self):
|
||||
self.usedBackends = QtCore.QSettings().value(
|
||||
self.settingsSection + u'/backends',
|
||||
self.usedAPIs = QtCore.QSettings().value(
|
||||
self.settingsSection + u'/apis',
|
||||
QtCore.QVariant(u'Webkit')).toString().split(u',')
|
||||
self.useWebkit = u'Webkit' in self.usedBackends
|
||||
self.usePhonon = u'Phonon' in self.usedBackends
|
||||
self.useVlc = u'Vlc' in self.usedBackends
|
||||
self.useWebkit = u'Webkit' in self.usedAPIs
|
||||
self.usePhonon = u'Phonon' in self.usedAPIs
|
||||
self.useVlc = u'Vlc' in self.usedAPIs
|
||||
self.usePhononCheckBox.setChecked(self.usePhonon)
|
||||
self.useVlcCheckBox.setChecked(self.useVlc)
|
||||
self.updateBackendList()
|
||||
self.updateApiList()
|
||||
|
||||
def save(self):
|
||||
oldBackendString = QtCore.QSettings().value(
|
||||
self.settingsSection + u'/backends',
|
||||
oldApiString = QtCore.QSettings().value(
|
||||
self.settingsSection + u'/apis',
|
||||
QtCore.QVariant(u'Webkit')).toString()
|
||||
newBackendString = self.usedBackends.join(u',')
|
||||
if oldBackendString != newBackendString:
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/backends',
|
||||
QtCore.QVariant(newBackendString))
|
||||
newApiString = self.usedAPIs.join(u',')
|
||||
if oldApiString != newApiString:
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/apis',
|
||||
QtCore.QVariant(newApiString))
|
||||
Receiver.send_message(u'config_screen_changed')
|
||||
|
@ -33,18 +33,18 @@ from PyQt4 import QtCore, QtGui
|
||||
from PyQt4.phonon import Phonon
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
from openlp.plugins.media.lib import MediaController, MediaState
|
||||
from openlp.plugins.media.lib import MediaAPI, MediaState
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class PhononController(MediaController):
|
||||
class PhononAPI(MediaAPI):
|
||||
"""
|
||||
Specialiced MediaController class
|
||||
to reflect Features of the Phonon backend
|
||||
Specialiced MediaAPI class
|
||||
to reflect Features of the Phonon API
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
MediaController.__init__(self, parent)
|
||||
MediaAPI.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.additional_extensions = {
|
||||
u'audio/ac3': [u'.ac3'],
|
||||
@ -59,6 +59,7 @@ class PhononController(MediaController):
|
||||
u'video/x-flv': [u'.flv'],
|
||||
u'video/x-matroska': [u'.mpv', u'.mkv'],
|
||||
u'video/x-wmv': [u'.wmv'],
|
||||
u'video/x-mpg': [u'.mpg'],
|
||||
u'video/x-ms-wmv': [u'.wmv']}
|
||||
mimetypes.init()
|
||||
for mimetype in Phonon.BackendCapabilities.availableMimeTypes():
|
||||
@ -90,7 +91,10 @@ class PhononController(MediaController):
|
||||
log.info(u'MediaPlugin: %s additional extensions: %s' % (mimetype,
|
||||
u' '.join(self.additional_extensions[mimetype])))
|
||||
|
||||
def setup(self, display, hasAudio):
|
||||
def setup_controls(self, controller, control_panel):
|
||||
pass
|
||||
|
||||
def setup(self, display):
|
||||
display.phononWidget = Phonon.VideoWidget(display)
|
||||
display.phononWidget.setVisible(False)
|
||||
display.phononWidget.resize(display.size())
|
||||
@ -126,13 +130,18 @@ class PhononController(MediaController):
|
||||
u'video/x-wmv': [u'.wmv'],
|
||||
u'video/x-ms-wmv': [u'.wmv']}
|
||||
|
||||
def load(self, display, path, volume, isBackground):
|
||||
def load(self, display):
|
||||
log.debug(u'load vid in Phonon Controller')
|
||||
controller = display.parent
|
||||
volume = controller.media_info.volume
|
||||
path = controller.media_info.file_info.absoluteFilePath()
|
||||
display.mediaObject.setCurrentSource(Phonon.MediaSource(path))
|
||||
if not self.mediaStateWait(display, Phonon.StoppedState):
|
||||
return False
|
||||
vol = float(volume) / float(10)
|
||||
display.audio.setVolume(vol)
|
||||
#self.info.start_time = 10000
|
||||
#self.info.end_time = 20000
|
||||
return True
|
||||
|
||||
def mediaStateWait(self, display, mediaState):
|
||||
@ -149,12 +158,13 @@ class PhononController(MediaController):
|
||||
return False
|
||||
return True
|
||||
|
||||
def resize(self, display, controller):
|
||||
def resize(self, display):
|
||||
display.phononWidget.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
self.set_visible(display, True)
|
||||
vol = float(display.parent.volume) / float(10)
|
||||
#self.set_visible(display, True)
|
||||
controller = display.parent
|
||||
vol = float(controller.media_info.volume) / float(10)
|
||||
display.audio.setVolume(vol)
|
||||
display.mediaObject.play()
|
||||
self.state = MediaState.Playing
|
||||
@ -168,6 +178,8 @@ class PhononController(MediaController):
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
# 1.0 is the highest value
|
||||
vol = float(vol) / float(100)
|
||||
display.audio.setVolume(vol)
|
||||
|
||||
def seek(self, display, seekVal):
|
||||
@ -183,16 +195,20 @@ class PhononController(MediaController):
|
||||
if self.hasOwnWidget:
|
||||
display.phononWidget.setVisible(status)
|
||||
|
||||
def update_ui(self, controller, display):
|
||||
controller.seekSlider.setMaximum(display.mediaObject.totalTime())
|
||||
if display.serviceItem.end_time > 0:
|
||||
if display.mediaObject.currentTime() > \
|
||||
display.serviceItem.end_time:
|
||||
self.stop(display)
|
||||
if display.serviceItem.start_time > 0:
|
||||
def update_ui(self, display):
|
||||
controller = display.parent
|
||||
controller.media_info.length = display.mediaObject.totalTime()
|
||||
controller.seekSlider.setMaximum(controller.media_info.length)
|
||||
if controller.media_info.start_time > 0:
|
||||
if display.mediaObject.currentTime() < \
|
||||
display.serviceItem.start_time:
|
||||
self.seek(display, self.serviceItem.start_time * 1000)
|
||||
controller.media_info.start_time:
|
||||
self.seek(display, controller.media_info.start_time)
|
||||
self.set_visible(display, True)
|
||||
if controller.media_info.end_time > 0:
|
||||
if display.mediaObject.currentTime() > \
|
||||
controller.media_info.end_time:
|
||||
self.stop(display)
|
||||
self.set_visible(display, False)
|
||||
if not controller.seekSlider.isSliderDown():
|
||||
controller.seekSlider.setSliderPosition( \
|
||||
display.mediaObject.currentTime())
|
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import sys, os
|
||||
from datetime import datetime
|
||||
try:
|
||||
import vlc
|
||||
@ -34,17 +34,17 @@ except:
|
||||
pass
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from openlp.core.lib import Receiver
|
||||
from openlp.plugins.media.lib import MediaController, MediaState
|
||||
from openlp.plugins.media.lib import MediaAPI, MediaState
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class VlcController(MediaController):
|
||||
class VlcAPI(MediaAPI):
|
||||
"""
|
||||
Specialiced MediaController class
|
||||
to reflect Features of the Vlc backend
|
||||
Specialiced MediaAPI class
|
||||
to reflect Features of the Vlc API
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
MediaController.__init__(self, parent)
|
||||
MediaAPI.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.video_extensions_list = [
|
||||
u'*.3gp'
|
||||
@ -70,10 +70,13 @@ class VlcController(MediaController):
|
||||
, u'*.iso'
|
||||
]
|
||||
|
||||
def setup(self, display, hasAudio):
|
||||
def setup_controls(self, controller, control_panel):
|
||||
pass
|
||||
|
||||
def setup(self, display):
|
||||
display.vlcWidget = QtGui.QFrame(display)
|
||||
# creating a basic vlc instance
|
||||
if hasAudio:
|
||||
if display.hasAudio:
|
||||
display.vlcInstance = vlc.Instance()
|
||||
else:
|
||||
display.vlcInstance = vlc.Instance('--no-audio')
|
||||
@ -121,26 +124,28 @@ class VlcController(MediaController):
|
||||
u'video/x-wmv': [u'.wmv'],
|
||||
u'video/x-ms-wmv': [u'.wmv']}
|
||||
|
||||
def load(self, display, path, volume, isBackground):
|
||||
def load(self, display):
|
||||
log.debug(u'load vid in Vlc Controller')
|
||||
vol = float(volume) / float(10)
|
||||
controller = display.parent
|
||||
volume = controller.media_info.volume
|
||||
file_path = str(
|
||||
controller.media_info.file_info.absoluteFilePath().toUtf8())
|
||||
path = os.path.normcase(file_path)
|
||||
# create the media
|
||||
display.vlcMedia = display.vlcInstance.media_new_path(unicode(path))
|
||||
display.vlcMedia = display.vlcInstance.media_new_path(path)
|
||||
# put the media in the media player
|
||||
display.vlcMediaPlayer.set_media(display.vlcMedia)
|
||||
# parse the metadata of the file
|
||||
display.vlcMedia.parse()
|
||||
if not self.mediaStateWait(display):
|
||||
return False
|
||||
return True
|
||||
|
||||
def mediaStateWait(self, display):
|
||||
def mediaStateWait(self, display, mediaState):
|
||||
"""
|
||||
Wait for the video to change its state
|
||||
Wait no longer than 5 seconds.
|
||||
"""
|
||||
start = datetime.now()
|
||||
while not display.vlcMedia.is_parsed():
|
||||
while not mediaState == display.vlcMedia.get_state():
|
||||
if display.vlcMedia.get_state() == vlc.State.Error:
|
||||
return False
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
@ -148,16 +153,18 @@ class VlcController(MediaController):
|
||||
return False
|
||||
return True
|
||||
|
||||
def resize(self, display, controller):
|
||||
def resize(self, display):
|
||||
display.vlcWidget.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
self.set_visible(display, True)
|
||||
display.vlcMediaPlayer.play()
|
||||
if self.mediaStateWait(display, vlc.State.Playing):
|
||||
self.state = MediaState.Playing
|
||||
|
||||
def pause(self, display):
|
||||
display.vlcMediaPlayer.pause()
|
||||
if self.mediaStateWait(display, vlc.State.Paused):
|
||||
self.state = MediaState.Paused
|
||||
|
||||
def stop(self, display):
|
||||
@ -165,7 +172,7 @@ class VlcController(MediaController):
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
pass
|
||||
display.vlcMediaPlayer.audio_set_volume(vol)
|
||||
|
||||
def seek(self, display, seekVal):
|
||||
if display.vlcMediaPlayer.is_seekable():
|
||||
@ -180,7 +187,8 @@ class VlcController(MediaController):
|
||||
if self.hasOwnWidget:
|
||||
display.vlcWidget.setVisible(status)
|
||||
|
||||
def update_ui(self, controller, display):
|
||||
def update_ui(self, display):
|
||||
controller = display.parent
|
||||
controller.seekSlider.setMaximum(1000)
|
||||
if not controller.seekSlider.isSliderDown():
|
||||
currentPos = display.vlcMediaPlayer.get_position() * 1000
|
@ -28,20 +28,21 @@
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||
from openlp.plugins.media.lib import MediaController, MediaState
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, translate
|
||||
from openlp.plugins.media.lib import MediaAPI, MediaState
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class WebkitController(MediaController):
|
||||
class WebkitAPI(MediaAPI):
|
||||
"""
|
||||
Specialiced MediaController class
|
||||
to reflect Features of the QtWebkit backend
|
||||
Specialiced MediaAPI class
|
||||
to reflect Features of the QtWebkit API
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
MediaController.__init__(self, parent)
|
||||
MediaAPI.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.isFlash = False
|
||||
self.canBackground = True
|
||||
self.video_extensions_list = [
|
||||
u'*.3gp'
|
||||
@ -68,7 +69,11 @@ class WebkitController(MediaController):
|
||||
, u'*.swf', u'*.mpg', u'*.wmv', u'*.mpeg', u'*.avi'
|
||||
]
|
||||
|
||||
def setup(self, display, hasAudio):
|
||||
def setup_controls(self, controller, control_panel):
|
||||
# no special controls
|
||||
pass
|
||||
|
||||
def setup(self, display):
|
||||
display.webView.raise_()
|
||||
self.hasOwnWidget = False
|
||||
|
||||
@ -79,68 +84,83 @@ class WebkitController(MediaController):
|
||||
def get_supported_file_types(self):
|
||||
pass
|
||||
|
||||
def load(self, display, path, volume, isBackground):
|
||||
def load(self, display):
|
||||
log.debug(u'load vid in Webkit Controller')
|
||||
vol = float(volume) / float(10)
|
||||
if isBackground:
|
||||
controller = display.parent
|
||||
volume = controller.media_info.volume
|
||||
vol = float(volume) / float(100)
|
||||
path = controller.media_info.file_info.absoluteFilePath()
|
||||
if controller.media_info.is_background:
|
||||
loop = u'true'
|
||||
else:
|
||||
loop = u'false'
|
||||
display.webView.setVisible(True)
|
||||
if path.endswith(u'.swf'):
|
||||
if controller.media_info.file_info.suffix() == u'swf':
|
||||
controller.media_info.isFlash = True
|
||||
js = u'show_flash("load","%s");' % \
|
||||
(path.replace(u'\\', u'\\\\'))
|
||||
self.isFlash = True
|
||||
else:
|
||||
js = u'show_video("init", "%s", %s, %s);' % \
|
||||
(path.replace(u'\\', u'\\\\'), str(vol), loop)
|
||||
self.isFlash = False
|
||||
display.frame.evaluateJavaScript(js)
|
||||
return True
|
||||
|
||||
def resize(self, display, controller):
|
||||
def resize(self, display):
|
||||
controller = display.parent
|
||||
if display == controller.previewDisplay:
|
||||
display.webView.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
display.override[u'theme'] = u''
|
||||
display.override[u'video'] = True
|
||||
controller = display.parent
|
||||
#display.override[u'theme'] = u''
|
||||
#display.override[u'video'] = True
|
||||
display.webLoaded = True
|
||||
self.set_visible(display, True)
|
||||
if self.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("play","");')
|
||||
if controller.media_info.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("play");')
|
||||
else:
|
||||
display.frame.evaluateJavaScript(u'show_video("play");')
|
||||
self.state = MediaState.Playing
|
||||
|
||||
def pause(self, display):
|
||||
if self.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("pause","");')
|
||||
controller = display.parent
|
||||
if controller.media_info.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("pause");')
|
||||
else:
|
||||
display.frame.evaluateJavaScript(u'show_video("pause");')
|
||||
self.state = MediaState.Paused
|
||||
|
||||
def stop(self, display):
|
||||
if self.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("stop","");')
|
||||
controller = display.parent
|
||||
if controller.media_info.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("stop");')
|
||||
else:
|
||||
display.frame.evaluateJavaScript(u'show_video("stop");')
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
if not self.isFlash:
|
||||
controller = display.parent
|
||||
# 1.0 is the highest value
|
||||
vol = float(vol) / float(100)
|
||||
if not controller.media_info.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
|
||||
str(vol))
|
||||
|
||||
def seek(self, display, seekVal):
|
||||
if not self.isFlash:
|
||||
controller = display.parent
|
||||
if controller.media_info.isFlash:
|
||||
seek = seekVal
|
||||
display.frame.evaluateJavaScript( \
|
||||
u'show_flash("seek", null, null, "%s");' % (seek))
|
||||
else:
|
||||
seek = float(seekVal)/1000
|
||||
display.frame.evaluateJavaScript( \
|
||||
u'show_video("seek", null, null, null, "%f");' % (seek))
|
||||
|
||||
def reset(self, display):
|
||||
if self.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("close","");')
|
||||
controller = display.parent
|
||||
if controller.media_info.isFlash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("close");')
|
||||
else:
|
||||
display.frame.evaluateJavaScript(u'show_video("close");')
|
||||
self.state = MediaState.Off
|
||||
@ -149,16 +169,26 @@ class WebkitController(MediaController):
|
||||
if self.hasOwnWidget:
|
||||
display.webView.setVisible(status)
|
||||
|
||||
def update_ui(self, controller, display):
|
||||
if not self.isFlash:
|
||||
def update_ui(self, display):
|
||||
controller = display.parent
|
||||
if controller.media_info.isFlash:
|
||||
currentTime = display.frame.evaluateJavaScript( \
|
||||
u'show_video("currentTime");')
|
||||
length = display.frame.evaluateJavaScript(u'show_video("length");')
|
||||
if int(currentTime.toFloat()[0]*1000) > 0:
|
||||
controller.seekSlider.setMaximum(int(length.toFloat()[0]*1000))
|
||||
u'show_flash("currentTime");').toInt()[0]
|
||||
length = display.frame.evaluateJavaScript( \
|
||||
u'show_flash("length");').toInt()[0]
|
||||
else:
|
||||
(currentTime, ok) = display.frame.evaluateJavaScript( \
|
||||
u'show_video("currentTime");').toFloat()
|
||||
if ok:
|
||||
currentTime = int(currentTime*1000)
|
||||
(length, ok) = display.frame.evaluateJavaScript( \
|
||||
u'show_video("length");').toFloat()
|
||||
if ok:
|
||||
length = int(length*1000)
|
||||
if currentTime > 0:
|
||||
controller.seekSlider.setMaximum(length)
|
||||
if not controller.seekSlider.isSliderDown():
|
||||
controller.seekSlider.setSliderPosition( \
|
||||
int(currentTime.toFloat()[0]*1000))
|
||||
controller.seekSlider.setSliderPosition(currentTime)
|
||||
|
||||
def get_supported_file_types(self):
|
||||
pass
|
@ -53,6 +53,9 @@ class MediaPlugin(Plugin):
|
||||
'<br />The media plugin provides playback of audio and video.')
|
||||
return about_text
|
||||
|
||||
def addControllerItems(self, controller, control_panel):
|
||||
self.mediaManager.addControllerItems(controller, control_panel)
|
||||
|
||||
def setPluginTextStrings(self):
|
||||
"""
|
||||
Called to define all translatable texts of the plugin
|
||||
|
Loading…
Reference in New Issue
Block a user