This is the fix for playback with vlc on osx. It also includes fix to get media length without starting playback of a video.

I tested it only on osx in one- and dual-screen setup so far.

Also controllersVisible is renamed to controlsVisible.

bzr-revno: 2104
This commit is contained in:
Martin Zibricky 2012-11-07 18:42:21 +00:00 committed by Tim Bentley
commit 72bb217749
4 changed files with 45 additions and 22 deletions

View File

@ -107,11 +107,6 @@ class MediaController(object):
AppLocation.get_directory(AppLocation.AppDir), AppLocation.get_directory(AppLocation.AppDir),
u'core', u'ui', u'media') u'core', u'ui', u'media')
for filename in os.listdir(controller_dir): for filename in os.listdir(controller_dir):
# TODO vlc backend is not yet working on Mac OS X.
# For now just ignore vlc backend on Mac OS X.
if sys.platform == 'darwin' and filename == 'vlcplayer.py':
log.warn(u'Disabling vlc media player')
continue
if filename.endswith(u'player.py'): if filename.endswith(u'player.py'):
path = os.path.join(controller_dir, filename) path = os.path.join(controller_dir, filename)
if os.path.isfile(path): if os.path.isfile(path):
@ -150,13 +145,18 @@ class MediaController(object):
if not self.curDisplayMediaPlayer.keys(): if not self.curDisplayMediaPlayer.keys():
self.timer.stop() self.timer.stop()
else: else:
any_active = False
for display in self.curDisplayMediaPlayer.keys(): for display in self.curDisplayMediaPlayer.keys():
self.curDisplayMediaPlayer[display].resize(display) self.curDisplayMediaPlayer[display].resize(display)
self.curDisplayMediaPlayer[display].update_ui(display) self.curDisplayMediaPlayer[display].update_ui(display)
if self.curDisplayMediaPlayer[display].state == \ if self.curDisplayMediaPlayer[display].state == \
MediaState.Playing: MediaState.Playing:
return any_active = True
# no players are active anymore # There are still any active players - no need to stop timer.
if any_active:
return
# No players are active anymore.
for display in self.curDisplayMediaPlayer.keys(): for display in self.curDisplayMediaPlayer.keys():
if self.curDisplayMediaPlayer[display].state != MediaState.Paused: if self.curDisplayMediaPlayer[display].state != MediaState.Paused:
display.controller.seekSlider.setSliderPosition(0) display.controller.seekSlider.setSliderPosition(0)
@ -295,7 +295,8 @@ class MediaController(object):
""" """
player.resize(display) player.resize(display)
def video(self, controller, file, muted, isBackground, hidden=False): def video(self, controller, file, muted, isBackground, hidden=False,
isInfo=False, controlsVisible=True):
""" """
Loads and starts a video to run with the option of sound Loads and starts a video to run with the option of sound
""" """
@ -353,14 +354,16 @@ class MediaController(object):
elif Settings().value(u'general/auto unblank', elif Settings().value(u'general/auto unblank',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
autoplay = True autoplay = True
if autoplay: # Start playback only for visible widgets. If we need just load a video
# and get video information, do not start playback.
if autoplay and not isInfo:
if not self.video_play([controller]): if not self.video_play([controller]):
critical_error_message_box( critical_error_message_box(
translate('MediaPlugin.MediaItem', 'Unsupported File'), translate('MediaPlugin.MediaItem', 'Unsupported File'),
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',
'Unsupported File'))) 'Unsupported File')))
return False return False
self.set_controls_visible(controller, True) self.set_controls_visible(controller, controlsVisible)
log.debug(u'use %s controller' % self.curDisplayMediaPlayer[display]) log.debug(u'use %s controller' % self.curDisplayMediaPlayer[display])
return True return True

View File

@ -53,7 +53,7 @@ ADDITIONAL_EXT = {
u'video/x-matroska': [u'.mpv', u'.mkv'], u'video/x-matroska': [u'.mpv', u'.mkv'],
u'video/x-wmv': [u'.wmv'], u'video/x-wmv': [u'.wmv'],
u'video/x-mpg': [u'.mpg'], u'video/x-mpg': [u'.mpg'],
u'video/mpeg' : [u'.mp4', u'.mts'], u'video/mpeg' : [u'.mp4', u'.mts', u'.mov'],
u'video/x-ms-wmv': [u'.wmv']} u'video/x-ms-wmv': [u'.wmv']}

View File

@ -125,18 +125,21 @@ class VlcPlayer(MediaPlayer):
display.vlcWidget.resize(display.size()) display.vlcWidget.resize(display.size())
display.vlcWidget.raise_() display.vlcWidget.raise_()
display.vlcWidget.hide() display.vlcWidget.hide()
# the media player has to be 'connected' to the QFrame # The media player has to be 'connected' to the QFrame.
# (otherwise a video would be displayed in it's own window) # (otherwise a video would be displayed in it's own window)
# this is platform specific! # This is platform specific!
# you have to give the id of the QFrame (or similar object) to # You have to give the id of the QFrame (or similar object)
# vlc, different platforms have different functions for this # to vlc, different platforms have different functions for this.
win_id = int(display.vlcWidget.winId())
if sys.platform == "win32": if sys.platform == "win32":
display.vlcMediaPlayer.set_hwnd(int(display.vlcWidget.winId())) display.vlcMediaPlayer.set_hwnd(win_id)
elif sys.platform == "darwin": elif sys.platform == "darwin":
display.vlcMediaPlayer.set_agl(int(display.vlcWidget.winId())) # We have to use 'set_nsobject' since Qt4 on OSX uses Cocoa
# framework and not the old Carbon.
display.vlcMediaPlayer.set_nsobject(win_id)
else: else:
# for Linux using the X Server # for Linux using the X Server
display.vlcMediaPlayer.set_xwindow(int(display.vlcWidget.winId())) display.vlcMediaPlayer.set_xwindow(win_id)
self.hasOwnWidget = True self.hasOwnWidget = True
def check_available(self): def check_available(self):
@ -156,6 +159,13 @@ class VlcPlayer(MediaPlayer):
# parse the metadata of the file # parse the metadata of the file
display.vlcMedia.parse() display.vlcMedia.parse()
self.volume(display, volume) self.volume(display, volume)
# We need to set media_info.length during load because we want
# to avoid start and stop the video twice. Once for real playback
# and once to just get media length.
#
# Media plugin depends on knowing media length before playback.
controller.media_info.length = \
int(display.vlcMediaPlayer.get_media().get_duration() / 1000)
return True return True
def media_state_wait(self, display, mediaState): def media_state_wait(self, display, mediaState):
@ -221,6 +231,7 @@ class VlcPlayer(MediaPlayer):
display.vlcWidget.setVisible(status) display.vlcWidget.setVisible(status)
def update_ui(self, display): def update_ui(self, display):
# Stop video if playback is finished.
if display.vlcMedia.get_state() == vlc.State.Ended: if display.vlcMedia.get_state() == vlc.State.Ended:
self.stop(display) self.stop(display)
controller = display.controller controller = display.controller

View File

@ -206,11 +206,20 @@ class MediaMediaItem(MediaManagerItem):
'The file %s no longer exists.')) % filename) 'The file %s no longer exists.')) % filename)
return False return False
self.mediaLength = 0 self.mediaLength = 0
if self.plugin.mediaController.video( \ # Get media information and its length.
self.mediaController, filename, False, False): #
# This code (mediaController.video()) starts playback but we
# need only media information not video to start. Otherwise
# video is played twice. Find another way to get media info
# without loading and starting video playback.
#
# TODO Test getting media length with other media backends
# Phonon/Webkit.
if self.plugin.mediaController.video(self.mediaController,
filename, muted=False, isBackground=False, isInfo=True,
controlsVisible=False):
self.mediaLength = self.mediaController.media_info.length self.mediaLength = self.mediaController.media_info.length
service_item.media_length = self.mediaLength service_item.media_length = self.mediaLength
self.plugin.mediaController.video_reset(self.mediaController)
if self.mediaLength > 0: if self.mediaLength > 0:
service_item.add_capability( service_item.add_capability(
ItemCapabilities.HasVariableStartTime) ItemCapabilities.HasVariableStartTime)