Video reimplementations issues

This commit is contained in:
rimach crichter@web.de 2011-04-18 21:50:12 +02:00
parent 85da3e53c3
commit 50ff8438a0
11 changed files with 6921 additions and 186 deletions

View File

@ -71,6 +71,9 @@ body {
#video2 { #video2 {
z-index:3; z-index:3;
} }
#flash {
z-index:4;
}
#alert { #alert {
position: absolute; position: absolute;
left: 0px; left: 0px;
@ -303,6 +306,63 @@ sup {
function show_text_complete(){ function show_text_complete(){
return (text_opacity()==1); return (text_opacity()==1);
} }
function getFlashMovieObject(movieName)
{
if (window.document[movieName])
{
return window.document[movieName];
}
if (navigator.appName.indexOf("Microsoft Internet")==-1)
{
if (document.embeds && document.embeds[movieName])
return document.embeds[movieName];
}
else // if (navigator.appName.indexOf("Microsoft Internet")!=-1)
{
return document.getElementById(movieName);
}
}
function show_flash(state, path){
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'>";
switch(state){
case 'load':
text.innerHTML = "<embed " + src + view_parm + swf_parm + ">";
flashMovie = getFlashMovieObject("OpenLPFlashMovie");
text.style.visibility = 'visible';
flashMovie.Play();
break;
case 'play':
text.style.visibility = 'visible';
flashMovie.Play();
break;
case 'rewind':
ret = 'rewind';
alert(' Wert: ' + flashMovie.TGetProperty("/", 4));
// flashMovie.TotalFrames()
// PercentLoaded()
// GotoFrame()
break;
case 'stop':
flashMovie.StopPlay();
text.innerHTML = ''
text.style.visibility = 'hidden';
break;
}
}
</script> </script>
</head> </head>
<body> <body>
@ -312,6 +372,7 @@ sup {
</video> </video>
<video id="video2" class="size" style="visibility:hidden" autobuffer preload> <video id="video2" class="size" style="visibility:hidden" autobuffer preload>
</video> </video>
<div id="flash" class="size" style="visibility:hidden"></div>
%s %s
<div id="footer" class="footer"></div> <div id="footer" class="footer"></div>
<div id="black" class="size"></div> <div id="black" class="size"></div>

View File

@ -99,28 +99,30 @@ class MainDisplay(DisplayWidget):
self.screen = self.screens.current self.screen = self.screens.current
self.setVisible(False) self.setVisible(False)
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
self.videoWidget = Phonon.VideoWidget(self) # self.videoWidget = Phonon.VideoWidget(self)
self.videoWidget.setVisible(False) # self.videoWidget.setVisible(False)
self.videoWidget.setGeometry(QtCore.QRect(0, 0, # self.videoWidget.setGeometry(QtCore.QRect(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height())) # self.screen[u'size'].width(), self.screen[u'size'].height()))
log.debug(u'Setup Phonon for monitor %s' % self.screens.monitor_number) # log.debug(u'Setup Phonon for monitor %s' % self.screens.monitor_number)
self.mediaObject = Phonon.MediaObject(self) # self.mediaObject = Phonon.MediaObject(self)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) # self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.videoWidget) # Phonon.createPath(self.mediaObject, self.videoWidget)
Phonon.createPath(self.mediaObject, self.audio) # Phonon.createPath(self.mediaObject, self.audio)
QtCore.QObject.connect(self.mediaObject, # QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'), # QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
self.videoState) # self.videoState)
QtCore.QObject.connect(self.mediaObject, # QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), # QtCore.SIGNAL(u'finished()'),
self.videoFinished) # self.videoFinished)
QtCore.QObject.connect(self.mediaObject, # QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'tick(qint64)'), # QtCore.SIGNAL(u'tick(qint64)'),
self.videoTick) # self.videoTick)
log.debug(u'Setup webView for monitor %s' % self.screens.monitor_number) log.debug(u'Setup webView for monitor %s' % self.screens.monitor_number)
self.webView = QtWebKit.QWebView(self) self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0, self.webView.setGeometry(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height()) self.screen[u'size'].width(), self.screen[u'size'].height())
self.webView.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled,True)
self.page = self.webView.page() self.page = self.webView.page()
self.frame = self.page.mainFrame() self.frame = self.page.mainFrame()
QtCore.QObject.connect(self.webView, QtCore.QObject.connect(self.webView,
@ -173,9 +175,17 @@ class MainDisplay(DisplayWidget):
self.primary = False self.primary = False
else: else:
self.primary = True self.primary = True
Receiver.send_message(u'media_set_display', self)
log.debug( log.debug(
u'Finished setup for monitor %s' % self.screens.monitor_number) u'Finished setup for monitor %s' % self.screens.monitor_number)
def videoHelper(self, newState, oldState):
"""
Start the video at a predetermined point.
"""
if type(newState) == Phonon.State:
print "Phonon State alt:%d, neu:%d" % (oldState, newState)
def text(self, slide): def text(self, slide):
""" """
Add the slide text from slideController Add the slide text from slideController
@ -201,7 +211,7 @@ class MainDisplay(DisplayWidget):
""" """
log.debug(u'alert to display') log.debug(u'alert to display')
if self.height() != self.screen[u'size'].height() \ if self.height() != self.screen[u'size'].height() \
or not self.isVisible() or self.videoWidget.isVisible(): or not self.isVisible():# or self.videoWidget.isVisible():
shrink = True shrink = True
else: else:
shrink = False shrink = False
@ -282,129 +292,107 @@ class MainDisplay(DisplayWidget):
if self.isLive: if self.isLive:
Receiver.send_message(u'maindisplay_active') Receiver.send_message(u'maindisplay_active')
def resetVideo(self): # def resetVideo(self):
""" # """
Used after Video plugin has changed the background # Used after Video plugin has changed the background
""" # """
log.debug(u'resetVideo') # log.debug(u'resetVideo')
if self.phononActive: # if self.phononActive:
self.mediaObject.stop() # self.mediaObject.stop()
self.mediaObject.clearQueue() # self.mediaObject.clearQueue()
self.webView.setVisible(True) # self.webView.setVisible(True)
self.videoWidget.setVisible(False) # self.videoWidget.setVisible(False)
self.phononActive = False # self.phononActive = False
else: # else:
self.frame.evaluateJavaScript(u'show_video("close");') # self.frame.evaluateJavaScript(u'show_video("close");')
self.override = {} # self.override = {}
# Update the preview frame. # # Update the preview frame.
if self.isLive: # if self.isLive:
Receiver.send_message(u'maindisplay_active') # Receiver.send_message(u'maindisplay_active')
#
def videoPlay(self): # def videoPlay(self):
""" # """
Responds to the request to play a loaded video # Responds to the request to play a loaded video
""" # """
log.debug(u'videoPlay') # log.debug(u'videoPlay')
if self.phononActive: # self.frame.evaluateJavaScript(u'show_flash("play","");')
self.mediaObject.play() # self.frame.evaluateJavaScript(u'show_video("stop");')
else: # return
self.frame.evaluateJavaScript(u'show_video("play");') # if self.phononActive:
# show screen # self.mediaObject.play()
if self.isLive: # else:
self.setVisible(True) # self.frame.evaluateJavaScript(u'show_video("play");')
# # show screen
def videoPause(self): # if self.isLive:
""" # self.setVisible(True)
Responds to the request to pause a loaded video #
""" # def videoPause(self):
log.debug(u'videoPause') # """
if self.phononActive: # Responds to the request to pause a loaded video
self.mediaObject.pause() # """
else: # log.debug(u'videoPause')
self.frame.evaluateJavaScript(u'show_video("pause");') # if self.phononActive:
# self.mediaObject.pause()
def videoStop(self): # else:
""" # self.frame.evaluateJavaScript(u'show_video("pause");')
Responds to the request to stop a loaded video #
""" # def videoStop(self):
log.debug(u'videoStop') # """
if self.phononActive: # Responds to the request to stop a loaded video
self.mediaObject.stop() # """
else: # log.debug(u'videoStop')
self.frame.evaluateJavaScript(u'show_video("stop");') # if self.phononActive:
# self.mediaObject.stop()
def videoVolume(self, volume): # else:
""" # self.frame.evaluateJavaScript(u'show_video("stop");')
Changes the volume of a running video #
""" # def videoVolume(self, volume):
log.debug(u'videoVolume %d' % volume) # """
vol = float(volume) / float(10) # Changes the volume of a running video
if self.phononActive: # """
self.audio.setVolume(vol) # log.debug(u'videoVolume %d' % volume)
else: # vol = float(volume) / float(10)
self.frame.evaluateJavaScript(u'show_video(null, null, %s);' % # if self.phononActive:
str(vol)) # self.audio.setVolume(vol)
# else:
def video(self, videoPath, volume, isBackground=False): # self.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
""" # str(vol))
Loads and starts a video to run with the option of sound #
""" # def video(self, videoPath, volume, isBackground=False):
log.debug(u'video') # """
self.webLoaded = True # Loads and starts a video to run with the option of sound
self.setGeometry(self.screen[u'size']) # """
# We are running a background theme # log.debug(u'video')
self.override[u'theme'] = u'' # Receiver.send_message(u'media_video', [self, videoPath, volume, isBackground])
self.override[u'video'] = True # return self.preview()
vol = float(volume) / float(10) #
if isBackground or not self.usePhonon: # def videoState(self, newState, oldState):
js = u'show_video("init", "%s", %s, true); show_video("play");' % \ # """
(videoPath.replace(u'\\', u'\\\\'), str(vol)) # Start the video at a predetermined point.
self.frame.evaluateJavaScript(js) # """
else: # if newState == Phonon.PlayingState \
self.phononActive = True # and oldState != Phonon.PausedState \
self.mediaObject.stop() # and self.serviceItem.start_time > 0:
self.mediaObject.clearQueue() # # set start time in milliseconds
self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath)) # self.mediaObject.seek(self.serviceItem.start_time * 1000)
# Need the timer to trigger set the trigger to 200ms #
# Value taken from web documentation. # def videoFinished(self):
if self.serviceItem.end_time != 0: # """
self.mediaObject.setTickInterval(200) # Blank the Video when it has finished so the final frame is not left
self.mediaObject.play() # hanging
self.webView.setVisible(False) # """
self.videoWidget.setVisible(True) # self.videoStop()
self.audio.setVolume(vol) # self.hideDisplay(HideMode.Blank)
# Update the preview frame. # self.phononActive = False
if self.isLive: # self.videoHide = True
Receiver.send_message(u'maindisplay_active') #
return self.preview() # def videoTick(self, tick):
# """
def videoState(self, newState, oldState): # Triggered on video tick every 200 milli seconds
""" # """
Start the video at a predetermined point. # if tick > self.serviceItem.end_time * 1000:
""" # self.videoFinished()
if newState == Phonon.PlayingState \ #
and oldState != Phonon.PausedState \
and self.serviceItem.start_time > 0:
# set start time in milliseconds
self.mediaObject.seek(self.serviceItem.start_time * 1000)
def videoFinished(self):
"""
Blank the Video when it has finished so the final frame is not left
hanging
"""
self.videoStop()
self.hideDisplay(HideMode.Blank)
self.phononActive = False
self.videoHide = True
def videoTick(self, tick):
"""
Triggered on video tick every 200 milli seconds
"""
if tick > self.serviceItem.end_time * 1000:
self.videoFinished()
def isWebLoaded(self): def isWebLoaded(self):
""" """
Called by webView event to show display is fully loaded Called by webView event to show display is fully loaded
@ -515,8 +503,9 @@ class MainDisplay(DisplayWidget):
Store the images so they can be replaced when required Store the images so they can be replaced when required
""" """
log.debug(u'hideDisplay mode = %d', mode) log.debug(u'hideDisplay mode = %d', mode)
if self.phononActive: # if self.phononActive:
self.videoPause() # self.videoPause()
Receiver.send_message(u'media_pause', self)
if mode == HideMode.Screen: if mode == HideMode.Screen:
self.frame.evaluateJavaScript(u'show_blank("desktop");') self.frame.evaluateJavaScript(u'show_blank("desktop");')
self.setVisible(False) self.setVisible(False)
@ -543,7 +532,8 @@ class MainDisplay(DisplayWidget):
self.setVisible(True) self.setVisible(True)
if self.phononActive: if self.phononActive:
self.webView.setVisible(False) self.webView.setVisible(False)
self.videoPlay() #self.videoPlay()
Receiver.send_message(u'media_play', self)
self.hideMode = None self.hideMode = None
# Trigger actions when display is active again # Trigger actions when display is active again
if self.isLive: if self.isLive:

View File

@ -225,6 +225,9 @@ class SlideController(QtGui.QWidget):
self.songMenu.setMenu(QtGui.QMenu( self.songMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Go To'), self.toolbar)) translate('OpenLP.SlideController', 'Go To'), self.toolbar))
self.toolbar.makeWidgetsInvisible([u'Song Menu']) self.toolbar.makeWidgetsInvisible([u'Song Menu'])
# Build the seekSlider.
self.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
self.seekSlider.setMaximum(1000)
# Build the volumeSlider. # Build the volumeSlider.
self.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal) self.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
self.volumeSlider.setTickInterval(1) self.volumeSlider.setTickInterval(1)
@ -234,11 +237,11 @@ class SlideController(QtGui.QWidget):
else: else:
# Build the seekSlider. # Build the seekSlider.
self.seekSlider = Phonon.SeekSlider() self.seekSlider = Phonon.SeekSlider()
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.seekSlider.setObjectName(u'seekSlider')
self.mediabar.addToolbarWidget(u'Seek Slider', self.seekSlider)
self.volumeSlider = Phonon.VolumeSlider() self.volumeSlider = Phonon.VolumeSlider()
self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) 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.volumeSlider.setObjectName(u'volumeSlider')
self.mediabar.addToolbarWidget(u'Audio Volume', self.volumeSlider) self.mediabar.addToolbarWidget(u'Audio Volume', self.volumeSlider)
self.controllerLayout.addWidget(self.mediabar) self.controllerLayout.addWidget(self.mediabar)
@ -297,6 +300,8 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'triggered(bool)'), self.onThemeDisplay) QtCore.SIGNAL(u'triggered(bool)'), self.onThemeDisplay)
QtCore.QObject.connect(self.desktopScreen, QtCore.QObject.connect(self.desktopScreen,
QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay) QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay)
QtCore.QObject.connect(self.seekSlider,
QtCore.SIGNAL(u'sliderReleased()'), self.mediaSeek)
QtCore.QObject.connect(self.volumeSlider, QtCore.QObject.connect(self.volumeSlider,
QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume) QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -392,7 +397,8 @@ class SlideController(QtGui.QWidget):
def liveEscape(self): def liveEscape(self):
self.display.setVisible(False) self.display.setVisible(False)
self.display.videoStop() #self.display.videoStop()
Receiver.send_message('media_stop', self.display)
def servicePrevious(self): def servicePrevious(self):
Receiver.send_message('servicemanager_previous_item') Receiver.send_message('servicemanager_previous_item')
@ -496,7 +502,7 @@ class SlideController(QtGui.QWidget):
len(item.get_frames()) > 1: len(item.get_frames()) > 1:
self.toolbar.makeWidgetsVisible(self.loopList) self.toolbar.makeWidgetsVisible(self.loopList)
if item.is_media(): if item.is_media():
self.toolbar.setVisible(False) #self.toolbar.setVisible(False)
self.mediabar.setVisible(True) self.mediabar.setVisible(True)
def enablePreviewToolBar(self, item): def enablePreviewToolBar(self, item):
@ -509,7 +515,7 @@ class SlideController(QtGui.QWidget):
if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin: if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin:
self.toolbar.makeWidgetsVisible(self.songEditList) self.toolbar.makeWidgetsVisible(self.songEditList)
elif item.is_media(): elif item.is_media():
self.toolbar.setVisible(False) #self.toolbar.setVisible(False)
self.mediabar.setVisible(True) self.mediabar.setVisible(True)
self.volumeSlider.setAudioOutput(self.audio) self.volumeSlider.setAudioOutput(self.audio)
@ -1028,7 +1034,8 @@ class SlideController(QtGui.QWidget):
log.debug(u'SlideController onMediaStart') log.debug(u'SlideController onMediaStart')
file = os.path.join(item.get_frame_path(), item.get_frame_title()) file = os.path.join(item.get_frame_path(), item.get_frame_title())
if self.isLive: if self.isLive:
self.display.video(file, self.volume) #self.display.video(file, self.volume)
Receiver.send_message(u'media_video', [self.display, file, self.volume, False])
self.volumeSlider.setValue(self.volume) self.volumeSlider.setValue(self.volume)
else: else:
self.mediaObject.stop() self.mediaObject.stop()
@ -1038,13 +1045,24 @@ class SlideController(QtGui.QWidget):
self.seekSlider.show() self.seekSlider.show()
self.onMediaPlay() self.onMediaPlay()
def mediaSeek(self):
"""
Respond to the release of Seek Slider
"""
log.debug(u'SlideController mediaSeek')
self.seekPos = self.seekSlider.value()
#self.display.videoVolume(self.volume)
Receiver.send_message(u'media_seek', [self.display, self.seekPos])
def mediaVolume(self): def mediaVolume(self):
""" """
Respond to the release of Volume Slider Respond to the release of Volume Slider
""" """
log.debug(u'SlideController mediaVolume') log.debug(u'SlideController mediaVolume')
self.volume = self.volumeSlider.value() self.volume = self.volumeSlider.value()
self.display.videoVolume(self.volume) #self.display.videoVolume(self.volume)
Receiver.send_message(u'media_volume', [self.display, self.volume])
def onMediaPause(self): def onMediaPause(self):
""" """
@ -1052,7 +1070,8 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'SlideController onMediaPause') log.debug(u'SlideController onMediaPause')
if self.isLive: if self.isLive:
self.display.videoPause() #self.display.videoPause()
Receiver.send_message(u'media_pause', self.display)
else: else:
self.mediaObject.pause() self.mediaObject.pause()
@ -1062,7 +1081,8 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'SlideController onMediaPlay') log.debug(u'SlideController onMediaPlay')
if self.isLive: if self.isLive:
self.display.videoPlay() Receiver.send_message(u'media_play', self.display)
#self.display.videoPlay()
else: else:
self.slidePreview.hide() self.slidePreview.hide()
self.video.show() self.video.show()
@ -1074,7 +1094,8 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'SlideController onMediaStop') log.debug(u'SlideController onMediaStop')
if self.isLive: if self.isLive:
self.display.videoStop() #self.display.videoStop()
Receiver.send_message(u'media_stop', self.display)
else: else:
self.mediaObject.stop() self.mediaObject.stop()
self.video.hide() self.video.hide()
@ -1085,9 +1106,10 @@ class SlideController(QtGui.QWidget):
""" """
Respond to a request to close the Video Respond to a request to close the Video
""" """
log.debug(u'SlideController onMediaStop') log.debug(u'SlideController onMediaClose')
if self.isLive: if self.isLive:
self.display.resetVideo() #self.display.resetVideo()
Receiver.send_message(u'media_reset', self.display)
else: else:
self.mediaObject.stop() self.mediaObject.stop()
self.mediaObject.clearQueue() self.mediaObject.clearQueue()

View File

@ -24,7 +24,53 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from PyQt4 import QtCore
class MediaBackends(object):
"""
An enumeration for possible Backends.
"""
Webkit = 0
Phonon = 1
Vlc = 2
class MediaController(object):
"""
"""
def __init__(self, parent):
self.parent = parent
self.state = 0
self.Timer = QtCore.QTimer()
QtCore.QObject.connect(self.Timer,
QtCore.SIGNAL("timeout()"), self.updatePlayer)
def load(self, display, path, volume):
pass
def play(self, display):
pass
def pause(self, display):
pass
def stop(self, display):
pass
def seek(self, display, seekVal):
pass
def reset(self, display):
pass
def updatePlayer(self):
pass
from mediaitem import MediaMediaItem from mediaitem import MediaMediaItem
from mediatab import MediaTab from mediatab import MediaTab
from mediacontroller import MediaManager
from webkitcontroller import WebkitController
#from phononcontroller import PhononController
#from vlccontroller import VlcController
__all__ = ['MediaMediaItem'] __all__ = ['MediaMediaItem']

View File

@ -0,0 +1,300 @@
#!/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, types
from PyQt4 import QtCore
import vlc
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver
from openlp.plugins.media.lib import MediaBackends
from webkitcontroller import WebkitController
from phononcontroller import PhononController
log = logging.getLogger(__name__)
class MediaManager(object):
"""
"""
def __init__(self, parent):
self.parent = parent
self.availableBackends = [
MediaBackends.Webkit,
MediaBackends.Phonon,
MediaBackends.Vlc]
self.curDisplayMediaController = {}
self.displayWebkitController = WebkitController(self)
self.displayPhononController = PhononController(self)
#self.displayVlcController = VlcController(self)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_set_display'), self.setDisplay)
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.videoPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_pause'), self.videoPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.videoStop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_seek'), self.videoSeek)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_volume'), self.videoVolume)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_reset'), self.videoReset)
def setDisplay(self, display):
print display
#self.setupVlcController(display)
self.setupPhononController(display)
self.setupWebkitController(display)
def setupWebkitController(self, display):
#self.displayWebkitController[display] = display.webView
display.webView.raise_()
def setupPhononController(self, display):
display.phononWidget = Phonon.VideoWidget(display)
display.phononWidget.setVisible(False)
display.phononWidget.setGeometry(QtCore.QRect(0, 0,
display.screen[u'size'].width(), display.screen[u'size'].height()))
display.mediaObject = Phonon.MediaObject(display)
display.audio = Phonon.AudioOutput(Phonon.VideoCategory, display.mediaObject)
Phonon.createPath(display.mediaObject, display.phononWidget)
Phonon.createPath(display.mediaObject, display.audio)
display.phononWidget.raise_()
QtCore.QObject.connect(display.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
display.videoHelper)
# display.mediaObject.stateChanged.connect(self.videoState)
# QtCore.QObject.connect(display.mediaObject,
# QtCore.SIGNAL(u'finished()'),
# self.videoFinished)
# QtCore.QObject.connect(display.mediaObject,
# QtCore.SIGNAL(u'tick(qint64)'),
# self.videoTick)
#self.displayPhononController[display] = display.mediaObject
def setupVlcController(self, display):
display.vlcWidget = QtGui.QWidget(display)
instance=vlc.Instance()
self.movieName = None
player=instance.media_player_new(self.movieName)
# the media player has to be 'connected' to the QFrame
# (otherwise a video would be displayed in it's own window)
# this is platform specific!
# you have to give the id of the QFrame (or similar object) to
# vlc, different platforms have different functions for this
if sys.platform == "linux2": # for Linux using the X Server
player.set_xwindow(self.hwnd)
elif sys.platform == "win32": # for Windows
player.set_hwnd(self.hwnd)
elif sys.platform == "darwin": # for MacOS
player.set_agl(self.hwnd)
display.vlcWidget.setGeometry(QtCore.QRect(0, 0,
display.screen[u'size'].width(), display.screen[u'size'].height()))
display.vlcWidget.raise_()
#self.displayVlcController[display] = player
def video(self, msg):
"""
Loads and starts a video to run with the option of sound
"""
display = msg[0]
videoPath = msg[1]
volume = msg[2]
isBackground = msg[3]
log.debug(u'video')
display.webLoaded = True
display.setGeometry(display.screen[u'size'])
# We are running a background theme
display.override[u'theme'] = u''
display.override[u'video'] = True
vol = float(volume) / float(10)
usePhonon = QtCore.QSettings().value(
u'media/use phonon', QtCore.QVariant(True)).toBool()
if usePhonon:
self.curDisplayMediaController[display] = self.displayPhononController
display.phononWidget.setVisible(True)
display.webView.setVisible(False)
else:
self.curDisplayMediaController[display] = self.displayWebkitController
display.phononWidget.setVisible(False)
display.webView.setVisible(True)
self.curDisplayMediaController[display].load(display, videoPath, volume)
if display.isLive:
Receiver.send_message(u'maindisplay_active')
return
if isBackground or not display.usePhonon:
if videoPath.endswith(u'.swf'):
js = u'show_flash("load","%s");' % \
(videoPath.replace(u'\\', u'\\\\'))
else:
js = u'show_video("init", "%s", %s, true); show_video("play");' % \
(videoPath.replace(u'\\', u'\\\\'), str(vol))
display.frame.evaluateJavaScript(js)
else:
display.phononActive = True
display.mediaObject.stop()
display.mediaObject.clearQueue()
display.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath))
# Need the timer to trigger set the trigger to 200ms
# Value taken from web documentation.
if display.serviceItem.end_time != 0:
display.mediaObject.setTickInterval(200)
display.mediaObject.play()
display.webView.setVisible(False)
display.phononWidget.setVisible(True)
display.audio.setVolume(vol)
# Update the preview frame.
if display.isLive:
Receiver.send_message(u'maindisplay_active')
def resetVideo(self):
"""
Used after Video plugin has changed the background
"""
log.debug(u'resetVideo')
if display.phononActive:
display.mediaObject.stop()
display.mediaObject.clearQueue()
display.webView.setVisible(True)
display.phononWidget.setVisible(False)
display.phononActive = False
else:
display.frame.evaluateJavaScript(u'show_video("close");')
display.override = {}
# Update the preview frame.
if display.isLive:
Receiver.send_message(u'maindisplay_active')
def videoPlay(self, display):
"""
Responds to the request to play a loaded video
"""
log.debug(u'videoPlay')
self.curDisplayMediaController[display].play(display)
# show screen
if display.isLive:
display.setVisible(True)
def videoPause(self, display):
"""
Responds to the request to pause a loaded video
"""
log.debug(u'videoPause')
if display in self.curDisplayMediaController:
self.curDisplayMediaController[display].pause(display)
return
def videoStop(self, display):
"""
Responds to the request to stop a loaded video
"""
log.debug(u'videoStop')
print type(display)
if type(display) is types.ListType:
return
print display, self.curDisplayMediaController
if display in self.curDisplayMediaController:
self.curDisplayMediaController[display].stop(display)
if display.isLive:
display.setVisible(False)
def videoVolume(self, msg):
"""
Changes the volume of a running video
"""
display = msg[0]
volume = msg[1]
log.debug(u'videoVolume %d' % volume)
vol = float(volume) / float(10)
if display.phononActive:
display.audio.setVolume(vol)
else:
display.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
str(vol))
def videoState(self, newState, oldState):
"""
Start the video at a predetermined point.
"""
print "display", self.sender()
# if newState == Phonon.PlayingState \
# and oldState != Phonon.PausedState \
# and self.serviceItem.start_time > 0:
# # set start time in milliseconds
# self.mediaObject.seek(self.serviceItem.start_time * 1000)
def videoFinished(self):
"""
Blank the Video when it has finished so the final frame is not left
hanging
"""
display.videoStop()
display.hideDisplay(HideMode.Blank)
display.phononActive = False
display.videoHide = True
def videoTick(self, tick):
"""
Triggered on video tick every 200 milli seconds
"""
if tick > display.serviceItem.end_time * 1000:
display.videoFinished()
def videoSeek(self, msg):
"""
Responds to the request to change the seek Slider of a loaded video
"""
log.debug(u'videoSeek')
display = msg[0]
seekVal = msg[1]
if display in self.curDisplayMediaController:
self.curDisplayMediaController[display].seek(display, seekVal)
def videoReset(self, display):
"""
Responds to the request to reset a loaded video
"""
log.debug(u'videoReset')
if display in self.curDisplayMediaController:
self.curDisplayMediaController[display].reset(display)

View File

@ -108,7 +108,9 @@ class MediaMediaItem(MediaManagerItem):
filename = unicode(item.data(QtCore.Qt.UserRole).toString()) filename = unicode(item.data(QtCore.Qt.UserRole).toString())
if os.path.exists(filename): if os.path.exists(filename):
(path, name) = os.path.split(filename) (path, name) = os.path.split(filename)
self.parent.liveController.display.video(filename, 0, True) #self.parent.liveController.display.video(filename, 0, True)
Receiver.send_message(u'media_video',
[self.parent.liveController.display, filename, 0, True])
self.resetAction.setVisible(True) self.resetAction.setVisible(True)
else: else:
critical_error_message_box(UiStrings.LiveBGError, critical_error_message_box(UiStrings.LiveBGError,
@ -129,35 +131,35 @@ class MediaMediaItem(MediaManagerItem):
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',
'The file %s no longer exists.')) % filename) 'The file %s no longer exists.')) % filename)
return False return False
self.mediaObject.stop() # self.mediaObject.stop()
self.mediaObject.clearQueue() # self.mediaObject.clearQueue()
self.mediaObject.setCurrentSource(Phonon.MediaSource(filename)) # self.mediaObject.setCurrentSource(Phonon.MediaSource(filename))
if not self.mediaStateWait(Phonon.StoppedState): # if not self.mediaStateWait(Phonon.StoppedState):
# Due to string freeze, borrow a message from presentations # Due to string freeze, borrow a message from presentations
# This will be corrected in 1.9.6 # This will be corrected in 1.9.6
critical_error_message_box( # critical_error_message_box(
translate('PresentationPlugin.MediaItem', 'Unsupported File'), # translate('PresentationPlugin.MediaItem', 'Unsupported File'),
unicode(translate('PresentationPlugin.MediaItem', # unicode(translate('PresentationPlugin.MediaItem',
'Unsupported File'))) # 'Unsupported File')))
return False #return False
# File too big for processing # File too big for processing
if os.path.getsize(filename) <= 52428800: # 50MiB if os.path.getsize(filename) <= 52428800: # 50MiB
self.mediaObject.play() # self.mediaObject.play()
if not self.mediaStateWait(Phonon.PlayingState) \ # if not self.mediaStateWait(Phonon.PlayingState) \
or self.mediaObject.currentSource().type() \ # or self.mediaObject.currentSource().type() \
== Phonon.MediaSource.Invalid: # == Phonon.MediaSource.Invalid:
# Due to string freeze, borrow a message from presentations # # Due to string freeze, borrow a message from presentations
# This will be corrected in 1.9.6 # # This will be corrected in 1.9.6
self.mediaObject.stop() # self.mediaObject.stop()
critical_error_message_box( # critical_error_message_box(
translate('PresentationPlugin.MediaItem', # translate('PresentationPlugin.MediaItem',
'Unsupported File'), # 'Unsupported File'),
unicode(translate('PresentationPlugin.MediaItem', # unicode(translate('PresentationPlugin.MediaItem',
'Unsupported File'))) # 'Unsupported File')))
return False # #return False
self.mediaLength = self.mediaObject.totalTime() / 1000 # self.mediaLength = self.mediaObject.totalTime() / 1000
self.mediaObject.stop() # self.mediaObject.stop()
service_item.media_length = self.mediaLength # service_item.media_length = self.mediaLength
service_item.add_capability( service_item.add_capability(
ItemCapabilities.AllowsVariableStartTime) ItemCapabilities.AllowsVariableStartTime)
service_item.title = unicode(self.plugin.nameStrings[u'singular']) service_item.title = unicode(self.plugin.nameStrings[u'singular'])

View File

@ -0,0 +1,81 @@
#!/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 #
###############################################################################
from PyQt4.phonon import Phonon
from openlp.plugins.media.lib import MediaController
class PhononController(MediaController):
"""
"""
def __init__(self, parent):
self.parent = parent
MediaController.__init__(self, parent)
def load(self, display, path, volume):
display.phononActive = True
display.mediaObject.stop()
display.mediaObject.clearQueue()
display.mediaObject.setCurrentSource(Phonon.MediaSource(path))
# Need the timer to trigger set the trigger to 200ms
# Value taken from web documentation.
vol = float(volume) / float(10)
if display.serviceItem.end_time != 0:
display.mediaObject.setTickInterval(200)
display.mediaObject.play()
display.audio.setVolume(vol)
self.Timer.setInterval(200)
def play(self, display):
display.mediaObject.play()
display.parent.seekSlider.setMaximum(display.mediaObject.totalTime())
def pause(self, display):
display.mediaObject.pause()
self.Timer.stop()
def stop(self, display):
display.mediaObject.stop()
self.Timer.stop()
def seek(self, display, seekVal):
print "seek"
display.mediaObject.seek(seekVal)
def reset(self, display):
display.mediaObject.stop()
display.mediaObject.clearQueue()
display.webView.setVisible(True)
display.phononWidget.setVisible(False)
display.phononActive = False
self.Timer.stop()
def updatePlayer(self):
for controller in self.parent.curDisplayMediaController:
if controller.getState() == 1:
pass

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
#!/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 #
###############################################################################
from openlp.plugins.media.lib import MediaController
class WebkitController(MediaController):
"""
"""
def __init__(self):
pass
def load(self, display, path, volume):
pass
def play(self, display):
self.display[u'live']
def pause(self):
pass
def stop(self):
pass
def seek(self):
pass

View File

@ -0,0 +1,77 @@
#!/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 #
###############################################################################
from openlp.plugins.media.lib import MediaController
class WebkitController(MediaController):
"""
"""
def __init__(self, parent):
self.parent = parent
MediaController.__init__(self, parent)
self.isFlash = False
def load(self, display, path, volume):
vol = float(volume) / float(10)
display.webView.setVisible(True)
display.phononWidget.setVisible(False)
if path.endswith(u'.swf'):
js = u'show_flash("load","%s");' % \
(path.replace(u'\\', u'\\\\'))
self.isFlash = True
else:
js = u'show_video("init", "%s", %s, false); show_video("play");' % \
(path.replace(u'\\', u'\\\\'), str(vol))
self.isFlash = False
display.frame.evaluateJavaScript(js)
def play(self, display):
if self.isFlash:
display.frame.evaluateJavaScript(u'show_flash("play","");')
# display.frame.evaluateJavaScript(u'show_video("stop");')
else:
# display.frame.evaluateJavaScript(u'show_flash("stop","");')
display.frame.evaluateJavaScript(u'show_video("play");')
def pause(self, display):
if self.isFlash:
display.frame.evaluateJavaScript(u'show_flash("pause","");')
else:
display.frame.evaluateJavaScript(u'show_video("pause");')
def stop(self, display):
if self.isFlash:
display.frame.evaluateJavaScript(u'show_flash("stop","");')
else:
display.frame.evaluateJavaScript(u'show_video("stop");')
def seek(self, display):
pass
def reset(self, display):
display.frame.evaluateJavaScript(u'show_video("close");')

View File

@ -30,7 +30,7 @@ import mimetypes
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.plugins.media.lib import MediaMediaItem, MediaTab from openlp.plugins.media.lib import MediaMediaItem, MediaTab, MediaManager
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -68,6 +68,7 @@ class MediaPlugin(Plugin):
self._addToList(self.audio_extensions_list, mimetype) self._addToList(self.audio_extensions_list, mimetype)
elif mimetype.startswith(u'video/'): elif mimetype.startswith(u'video/'):
self._addToList(self.video_extensions_list, mimetype) self._addToList(self.video_extensions_list, mimetype)
self.mediaManager = MediaManager(self)
def _addToList(self, list, mimetype): def _addToList(self, list, mimetype):
# Add all extensions which mimetypes provides us for supported types. # Add all extensions which mimetypes provides us for supported types.