From 44a523631ebc99d0937ba9fb5df5418ca0e8bd82 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Sun, 13 Dec 2015 21:35:23 +0100 Subject: [PATCH] Only import vlc in one place. Make it work with PyInstaller. --- openlp/core/ui/media/vlcplayer.py | 15 +++++++++++++-- .../media/forms/mediaclipselectorform.py | 18 +++++++----------- .../media/forms/test_mediaclipselectorform.py | 2 +- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index b560b20f8..280871cec 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -28,7 +28,7 @@ import logging import os import threading import sys - +import ctypes from PyQt4 import QtGui from openlp.core.common import Settings, is_win, is_macosx, is_linux @@ -71,8 +71,19 @@ def get_vlc(): if is_macosx(): # Newer versions of VLC on OS X need this. See https://forum.videolan.org/viewtopic.php?t=124521 os.environ['VLC_PLUGIN_PATH'] = '/Applications/VLC.app/Contents/MacOS/plugins' + # On Windows when frozen in PyInstaller, we need to blank SetDllDirectoryW to allow loading of the VLC dll. + # This is due to limitations (by desgin) in PyInstaller. SetDllDirectoryW original value is restored once + # VLC has been imported. + if is_win(): + buffer_size = 1024 + dll_directory = ctypes.create_unicode_buffer(buffer_size) + new_buffer_size = ctypes.windll.kernel32.GetDllDirectoryW(buffer_size, dll_directory) + dll_directory = ''.join(dll_directory[:new_buffer_size]).replace('\0', '') + log.debug('Original DllDirectory: %s' % dll_directory) + ctypes.windll.kernel32.SetDllDirectoryW(None) from openlp.core.ui.media.vendor import vlc - + if is_win(): + ctypes.windll.kernel32.SetDllDirectoryW(dll_directory) is_vlc_available = bool(vlc.get_default_instance()) except (ImportError, NameError, NotImplementedError): pass diff --git a/openlp/plugins/media/forms/mediaclipselectorform.py b/openlp/plugins/media/forms/mediaclipselectorform.py index 61d7a8455..a3ee8c2a5 100644 --- a/openlp/plugins/media/forms/mediaclipselectorform.py +++ b/openlp/plugins/media/forms/mediaclipselectorform.py @@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.common import translate, is_win, is_linux, is_macosx, RegistryProperties from openlp.plugins.media.forms.mediaclipselectordialog import Ui_MediaClipSelector from openlp.core.lib.ui import critical_error_message_box +from openlp.core.ui.media.vlcplayer import get_vlc if is_win(): from win32com.client import Dispatch @@ -38,17 +39,6 @@ if is_win(): if is_linux(): import dbus -try: - from openlp.core.ui.media.vendor import vlc -except (ImportError, NameError, NotImplementedError): - pass -except OSError as e: - if is_win(): - if not isinstance(e, WindowsError) and e.winerror != 126: - raise - else: - raise - log = logging.getLogger(__name__) @@ -126,6 +116,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector, RegistryPropert """ Setup VLC instance and mediaplayer """ + vlc = get_vlc() self.vlc_instance = vlc.Instance() # creating an empty vlc media player self.vlc_media_player = self.vlc_instance.media_player_new() @@ -160,6 +151,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector, RegistryPropert :param path: Path to the device to be tested. :return: True if it was an audio CD else False. """ + vlc = get_vlc() # Detect by trying to play it as a CD self.vlc_media = self.vlc_instance.media_new_location('cdda://' + path) self.vlc_media_player.set_media(self.vlc_media) @@ -193,6 +185,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector, RegistryPropert :param clicked: Given from signal, not used. """ log.debug('on_load_disc_button_clicked') + vlc = get_vlc() self.disable_all() self.application.set_busy_cursor() path = self.media_path_combobox.currentText() @@ -281,6 +274,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector, RegistryPropert :param clicked: Given from signal, not used. """ + vlc = get_vlc() if self.vlc_media_player.get_state() == vlc.State.Playing: self.vlc_media_player.pause() self.play_button.setIcon(self.play_icon) @@ -381,6 +375,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector, RegistryPropert :param index: The index of the newly chosen title track. """ log.debug('in on_titles_combo_box_changed, index: %d', index) + vlc = get_vlc() if not self.vlc_media_player: log.error('vlc_media_player was None') return @@ -619,6 +614,7 @@ class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector, RegistryPropert :param media_state: VLC media state to wait for. :return: True if state was reached within 15 seconds, False if not or error occurred. """ + vlc = get_vlc() start = datetime.now() while media_state != self.vlc_media_player.get_state(): if self.vlc_media_player.get_state() == vlc.State.Error: diff --git a/tests/interfaces/openlp_plugins/media/forms/test_mediaclipselectorform.py b/tests/interfaces/openlp_plugins/media/forms/test_mediaclipselectorform.py index 0fc66d1cb..68bf76fd6 100644 --- a/tests/interfaces/openlp_plugins/media/forms/test_mediaclipselectorform.py +++ b/tests/interfaces/openlp_plugins/media/forms/test_mediaclipselectorform.py @@ -51,7 +51,7 @@ class TestMediaClipSelectorForm(TestCase, TestMixin): self.main_window = QtGui.QMainWindow() Registry().register('main_window', self.main_window) # Mock VLC so we don't actually use it - self.vlc_patcher = patch('openlp.plugins.media.forms.mediaclipselectorform.vlc') + self.vlc_patcher = patch('openlp.plugins.media.forms.mediaclipselectorform.get_vlc') self.vlc_patcher.start() Registry().register('application', self.app) # Mock the media item