forked from openlp/openlp
Insert timeout on acquiring lock in slidecontroller to avoid hang. Fixes bug 1413324.
Run XInitThreads when using VLC to make it work correctly. Fixes bug 1433245. Disable the stop button in the slidecontroller mediaplayer buttons instead of hiding it to stop the position and audio slider resizing. Fixes bug 1431478. Fixed a webkit player exception. Fixes bug 1431476. Fix crash if presentation file in the mediamanger was removed bewteen sessions. Fixes bug 1432418. Updated the list of extensions supported by VLC. bzr-revno: 2524 Fixes: https://launchpad.net/bugs/1413324, https://launchpad.net/bugs/1433245, https://launchpad.net/bugs/1431478, https://launchpad.net/bugs/1431476, https://launchpad.net/bugs/1432418
This commit is contained in:
commit
41c695bbec
@ -589,7 +589,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
else:
|
||||
controller.mediabar.actions['playbackPlay'].setVisible(False)
|
||||
controller.mediabar.actions['playbackPause'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setDisabled(False)
|
||||
if controller.is_live:
|
||||
if controller.hide_menu.defaultAction().isChecked() and not controller.media_info.is_background:
|
||||
controller.hide_menu.defaultAction().trigger()
|
||||
@ -619,7 +619,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
display = self._define_display(controller)
|
||||
self.current_media_players[controller.controller_type].pause(display)
|
||||
controller.mediabar.actions['playbackPlay'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setDisabled(False)
|
||||
controller.mediabar.actions['playbackPause'].setVisible(False)
|
||||
|
||||
def media_stop_msg(self, msg):
|
||||
@ -645,7 +645,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
self.current_media_players[controller.controller_type].set_visible(display, False)
|
||||
controller.seek_slider.setSliderPosition(0)
|
||||
controller.mediabar.actions['playbackPlay'].setVisible(True)
|
||||
controller.mediabar.actions['playbackStop'].setVisible(False)
|
||||
controller.mediabar.actions['playbackStop'].setDisabled(True)
|
||||
controller.mediabar.actions['playbackPause'].setVisible(False)
|
||||
|
||||
def media_volume_msg(self, msg):
|
||||
|
@ -27,10 +27,11 @@ from distutils.version import LooseVersion
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import sys
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.common import Settings, is_win, is_macosx
|
||||
from openlp.core.common import Settings, is_win, is_macosx, is_linux
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.ui.media import MediaState, MediaType
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
@ -62,36 +63,30 @@ if VLC_AVAILABLE:
|
||||
if LooseVersion(VERSION.split()[0]) < LooseVersion('1.1.0'):
|
||||
VLC_AVAILABLE = False
|
||||
log.debug('VLC could not be loaded, because the vlc version is too old: %s' % VERSION)
|
||||
# On linux we need to initialise X threads, but not when running tests.
|
||||
if VLC_AVAILABLE and is_linux() and 'nose' not in sys.argv[0]:
|
||||
import ctypes
|
||||
try:
|
||||
x11 = ctypes.cdll.LoadLibrary('libX11.so')
|
||||
x11.XInitThreads()
|
||||
except:
|
||||
log.exception('Failed to run XInitThreads(), VLC might not work properly!')
|
||||
|
||||
AUDIO_EXT = ['*.mp3', '*.wav', '*.wma', '*.ogg']
|
||||
# Audio and video extensions copied from 'include/vlc_interface.h' from vlc 2.2.0 source
|
||||
AUDIO_EXT = ['*.3ga', '*.669', '*.a52', '*.aac', '*.ac3', '*.adt', '*.adts', '*.aif', '*.aifc', '*.aiff', '*.amr',
|
||||
'*.aob', '*.ape', '*.awb', '*.caf', '*.dts', '*.flac', '*.it', '*.kar', '*.m4a', '*.m4b', '*.m4p', '*.m5p',
|
||||
'*.mid', '*.mka', '*.mlp', '*.mod', '*.mpa', '*.mp1', '*.mp2', '*.mp3', '*.mpc', '*.mpga', '*.mus',
|
||||
'*.oga', '*.ogg', '*.oma', '*.opus', '*.qcp', '*.ra', '*.rmi', '*.s3m', '*.sid', '*.spx', '*.thd', '*.tta',
|
||||
'*.voc', '*.vqf', '*.w64', '*.wav', '*.wma', '*.wv', '*.xa', '*.xm']
|
||||
|
||||
VIDEO_EXT = [
|
||||
'*.3gp',
|
||||
'*.asf', '*.wmv',
|
||||
'*.au',
|
||||
'*.avi',
|
||||
'*.divx',
|
||||
'*.flv',
|
||||
'*.mov',
|
||||
'*.mp4', '*.m4v',
|
||||
'*.ogm', '*.ogv',
|
||||
'*.mkv', '*.mka',
|
||||
'*.ts', '*.mpg',
|
||||
'*.mpg', '*.mp2',
|
||||
'*.nsc',
|
||||
'*.nsv',
|
||||
'*.nut',
|
||||
'*.ra', '*.ram', '*.rm', '*.rv', '*.rmbv',
|
||||
'*.a52', '*.dts', '*.aac', '*.flac', '*.dv', '*.vid',
|
||||
'*.tta', '*.tac',
|
||||
'*.ty',
|
||||
'*.dts',
|
||||
'*.xa',
|
||||
'*.iso',
|
||||
'*.vob',
|
||||
'*.webm',
|
||||
'*.xvid'
|
||||
]
|
||||
VIDEO_EXT = ['*.3g2', '*.3gp', '*.3gp2', '*.3gpp', '*.amv', '*.asf', '*.avi', '*.bik', '*.divx', '*.drc', '*.dv',
|
||||
'*.f4v', '*.flv', '*.gvi', '*.gxf', '*.iso', '*.m1v', '*.m2v', '*.m2t', '*.m2ts', '*.m4v', '*.mkv',
|
||||
'*.mov', '*.mp2', '*.mp2v', '*.mp4', '*.mp4v', '*.mpe', '*.mpeg', '*.mpeg1', '*.mpeg2', '*.mpeg4', '*.mpg',
|
||||
'*.mpv2', '*.mts', '*.mtv', '*.mxf', '*.mxg', '*.nsv', '*.nuv', '*.ogg', '*.ogm', '*.ogv', '*.ogx', '*.ps',
|
||||
'*.rec', '*.rm', '*.rmvb', '*.rpl', '*.thp', '*.tod', '*.ts', '*.tts', '*.txd', '*.vob', '*.vro', '*.webm',
|
||||
'*.wm', '*.wmv', '*.wtv', '*.xesc',
|
||||
# These extensions was not in the official list, added manually.
|
||||
'*.nut', '*.rv', '*.xvid']
|
||||
|
||||
|
||||
class VlcPlayer(MediaPlayer):
|
||||
|
@ -375,7 +375,7 @@ class WebkitPlayer(MediaPlayer):
|
||||
# check if conversion was ok and value is not 'NaN'
|
||||
if length and length != float('inf'):
|
||||
length = int(length * 1000)
|
||||
if current_time:
|
||||
if current_time and length:
|
||||
controller.media_info.length = length
|
||||
controller.seek_slider.setMaximum(length)
|
||||
if not controller.seek_slider.isSliderDown():
|
||||
|
@ -1069,8 +1069,13 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
:param start:
|
||||
"""
|
||||
# Only one thread should be in here at the time. If already locked just skip, since the update will be
|
||||
# done by the thread holding the lock. If it is a "start" slide, we must wait for the lock.
|
||||
if not self.slide_selected_lock.acquire(start):
|
||||
# done by the thread holding the lock. If it is a "start" slide, we must wait for the lock, but only for 0.2
|
||||
# seconds, since we don't want to cause a deadlock
|
||||
timeout = 0.2 if start else -1
|
||||
if not self.slide_selected_lock.acquire(start, timeout):
|
||||
if start:
|
||||
self.log_debug('Could not get lock in slide_selected after waiting %f, skip to avoid deadlock.'
|
||||
% timeout)
|
||||
return
|
||||
row = self.preview_widget.current_slide_number()
|
||||
self.selected_row = 0
|
||||
|
@ -245,7 +245,8 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
doc = self.controllers[cidx].add_document(filepath)
|
||||
if clean_for_update:
|
||||
thumb_path = doc.get_thumbnail_path(1, True)
|
||||
if not thumb_path or os.path.getmtime(thumb_path) < os.path.getmtime(filepath):
|
||||
if not thumb_path or not os.path.exists(filepath) or os.path.getmtime(
|
||||
thumb_path) < os.path.getmtime(filepath):
|
||||
doc.presentation_deleted()
|
||||
else:
|
||||
doc.presentation_deleted()
|
||||
|
@ -87,7 +87,7 @@ class TestMediaItem(TestCase, TestMixin):
|
||||
|
||||
def clean_up_thumbnails_test(self):
|
||||
"""
|
||||
Test that the clean_up_thumbnails method works as expected.
|
||||
Test that the clean_up_thumbnails method works as expected when files exists.
|
||||
"""
|
||||
# GIVEN: A mocked controller, and mocked os.path.getmtime
|
||||
mocked_controller = MagicMock()
|
||||
@ -98,8 +98,10 @@ class TestMediaItem(TestCase, TestMixin):
|
||||
'Mocked': mocked_controller
|
||||
}
|
||||
presentation_file = 'file.tmp'
|
||||
with patch('openlp.plugins.presentations.lib.mediaitem.os.path.getmtime') as mocked_getmtime:
|
||||
with patch('openlp.plugins.presentations.lib.mediaitem.os.path.getmtime') as mocked_getmtime, \
|
||||
patch('openlp.plugins.presentations.lib.mediaitem.os.path.exists') as mocked_exists:
|
||||
mocked_getmtime.side_effect = [100, 200]
|
||||
mocked_exists.return_value = True
|
||||
|
||||
# WHEN: calling clean_up_thumbnails
|
||||
self.media_item.clean_up_thumbnails(presentation_file, True)
|
||||
@ -107,3 +109,25 @@ class TestMediaItem(TestCase, TestMixin):
|
||||
# THEN: doc.presentation_deleted should have been called since the thumbnails mtime will be greater than
|
||||
# the presentation_file's mtime.
|
||||
mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True)
|
||||
|
||||
def clean_up_thumbnails_missing_file_test(self):
|
||||
"""
|
||||
Test that the clean_up_thumbnails method works as expected when file is missing.
|
||||
"""
|
||||
# GIVEN: A mocked controller, and mocked os.path.exists
|
||||
mocked_controller = MagicMock()
|
||||
mocked_doc = MagicMock()
|
||||
mocked_controller.add_document.return_value = mocked_doc
|
||||
mocked_controller.supports = ['tmp']
|
||||
self.media_item.controllers = {
|
||||
'Mocked': mocked_controller
|
||||
}
|
||||
presentation_file = 'file.tmp'
|
||||
with patch('openlp.plugins.presentations.lib.mediaitem.os.path.exists') as mocked_exists:
|
||||
mocked_exists.return_value = False
|
||||
|
||||
# WHEN: calling clean_up_thumbnails
|
||||
self.media_item.clean_up_thumbnails(presentation_file, True)
|
||||
|
||||
# THEN: doc.presentation_deleted should have been called since the presentation file did not exists.
|
||||
mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True)
|
||||
|
Loading…
Reference in New Issue
Block a user