def test_not_osx_fix_vlc_22_plugin_path(mocked_is_macosx): """ Test that on Linux or some other non-OS X we do not set the VLC plugin path """ # GIVEN: We're not on OS X and we don't have the VLC plugin path set mocked_is_macosx.return_value = False # WHEN: An checking if the player is available get_vlc() # THEN: The extra environment variable should NOT be there assert 'VLC_PLUGIN_PATH' not in os.environ, 'The plugin path should NOT be in the environment variables'
def test_not_osx_fix_vlc_22_plugin_path(self, mocked_is_macosx): """ Test that on Linux or some other non-OS X we do not set the VLC plugin path """ # GIVEN: We're not on OS X and we don't have the VLC plugin path set mocked_is_macosx.return_value = False # WHEN: An checking if the player is available get_vlc() # THEN: The extra environment variable should NOT be there self.assertNotIn('VLC_PLUGIN_PATH', os.environ, 'The plugin path should NOT be in the environment variables')
def test_get_vlc_fails_and_removes_module(self, mocked_vlc): """ Test that when the VLC import fails, it removes the module from sys.modules """ # GIVEN: We're on OS X and we don't have the VLC plugin path set mocked_vlc.Instance.side_effect = NameError mocked_vlc.libvlc_get_version.return_value = b'0.0.0' # WHEN: An checking if the player is available get_vlc() # THEN: The extra environment variable should be there self.assertNotIn('openlp.core.ui.media.vendor.vlc', sys.modules)
def fix_vlc_22_plugin_path_test(self, mocked_is_macosx): """ Test that on OS X we set the VLC plugin path to fix a bug in the VLC module """ # GIVEN: We're on OS X and we don't have the VLC plugin path set mocked_is_macosx.return_value = True # WHEN: An checking if the player is available get_vlc() # THEN: The extra environment variable should be there self.assertIn('VLC_PLUGIN_PATH', os.environ, 'The plugin path should be in the environment variables') self.assertEqual('/Applications/VLC.app/Contents/MacOS/plugins', os.environ['VLC_PLUGIN_PATH'])
def test_fix_vlc_22_plugin_path(self, mocked_is_macosx): """ Test that on OS X we set the VLC plugin path to fix a bug in the VLC module """ # GIVEN: We're on OS X and we don't have the VLC plugin path set mocked_is_macosx.return_value = True # WHEN: An checking if the player is available get_vlc() # THEN: The extra environment variable should be there assert 'VLC_PLUGIN_PATH' in os.environ, 'The plugin path should be in the environment variables' assert '/Applications/VLC.app/Contents/MacOS/plugins' == os.environ[ 'VLC_PLUGIN_PATH']
def setup_vlc(self): """ 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() # 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. win_id = int(self.preview_frame.winId()) if is_win(): self.vlc_media_player.set_hwnd(win_id) elif is_macosx(): # We have to use 'set_nsobject' since Qt5 on OSX uses Cocoa # framework and not the old Carbon. self.vlc_media_player.set_nsobject(win_id) else: # for Linux using the X Server self.vlc_media_player.set_xwindow(win_id) self.vlc_media = None # Setup timer every 100 ms to update position self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update_position) self.timer.start(100) self.find_optical_devices() self.audio_cd = False self.audio_cd_tracks = None
def detect_audio_cd(self, path): """ Detects is the given path is an audio CD :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) self.vlc_media_player.play() # Wait for media to start playing. In this case VLC actually returns an error. self.media_state_wait(vlc.State.Playing) self.vlc_media_player.set_pause(1) # If subitems exists, this is a CD self.audio_cd_tracks = self.vlc_media.subitems() if not self.audio_cd_tracks or self.audio_cd_tracks.count() < 1: return False # Insert into titles_combo_box self.titles_combo_box.clear() for i in range(self.audio_cd_tracks.count()): item = self.audio_cd_tracks.item_at_index(i) item_title = item.get_meta(vlc.Meta.Title) self.titles_combo_box.addItem(item_title, i) self.vlc_media_player.set_media(self.audio_cd_tracks.item_at_index(0)) self.audio_cd = True self.titles_combo_box.setDisabled(False) self.titles_combo_box.setCurrentIndex(0) self.on_titles_combo_box_currentIndexChanged(0) return True
def not_osx_fix_vlc_22_plugin_path_test(self, mocked_is_macosx): """ Test that on Linux or some other non-OS X we do not set the VLC plugin path """ # GIVEN: We're not on OS X and we don't have the VLC plugin path set mocked_is_macosx.return_value = False if 'VLC_PLUGIN_PATH' in os.environ: del os.environ['VLC_PLUGIN_PATH'] if 'openlp.core.ui.media.vendor.vlc' in sys.modules: del sys.modules['openlp.core.ui.media.vendor.vlc'] # WHEN: An checking if the player is available get_vlc() # THEN: The extra environment variable should NOT be there self.assertNotIn('VLC_PLUGIN_PATH', os.environ, 'The plugin path should NOT be in the environment variables')
def not_osx_fix_vlc_22_plugin_path_test(self, mocked_is_macosx): """ Test that on Linux or some other non-OS X we do not set the VLC plugin path """ # GIVEN: We're not on OS X and we don't have the VLC plugin path set mocked_is_macosx.return_value = False if 'VLC_PLUGIN_PATH' in os.environ: del os.environ['VLC_PLUGIN_PATH'] if 'openlp.core.ui.media.vendor.vlc' in sys.modules: del sys.modules['openlp.core.ui.media.vendor.vlc'] # WHEN: An checking if the player is available get_vlc() # THEN: The extra environment variable should NOT be there self.assertNotIn( 'VLC_PLUGIN_PATH', os.environ, 'The plugin path should NOT be in the environment variables')
def on_load_optical(self): """ When the load optical button is clicked, open the clip selector window. """ # self.media_clip_selector_form.exec() if get_vlc(): media_clip_selector_form = MediaClipSelectorForm(self, self.main_window, None) media_clip_selector_form.exec() del media_clip_selector_form else: QtWidgets.QMessageBox.critical(self, 'VLC is not available', 'VLC is not available')
def on_load_optical(self): """ When the load optical button is clicked, open the clip selector window. """ # self.media_clip_selector_form.exec_() if get_vlc(): media_clip_selector_form = MediaClipSelectorForm(self, self.main_window, None) media_clip_selector_form.exec_() del media_clip_selector_form else: QtGui.QMessageBox.critical(self, 'VLC is not available', 'VLC is not available')
def on_play_button_clicked(self, clicked): """ Toggle the playback :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) else: self.vlc_media_player.play() self.media_state_wait(vlc.State.Playing) self.play_button.setIcon(self.pause_icon)
def media_state_wait(self, media_state): """ Wait for the video to change its state Wait no longer than 15 seconds. (loading an optical disc takes some time) :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: return False if (datetime.now() - start).seconds > 15: return False return True
def bootstrap_initialise(self): """ Check to see if we have any media Player's available. """ self.setup() self.vlc_player = VlcPlayer(self) State().add_service('mediacontroller', 0) State().add_service('media_live', 0) has_vlc = get_vlc() if has_vlc and pymediainfo_available: State().update_pre_conditions('mediacontroller', True) State().update_pre_conditions('media_live', True) else: if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible(): self.main_window.splash.hide() generic_message = translate( 'OpenLP.MediaController', 'OpenLP requires the following libraries in order to show videos and other ' 'media, but they are not installed. Please install these libraries to enable ' 'media playback in OpenLP.') fedora_rpmfusion = translate( 'OpenLP.MediaController', 'To install these libraries, you will need to enable the RPMFusion ' 'repository: https://rpmfusion.org/') if is_macosx(): message = translate( 'OpenLP.MediaController', 'macOS is missing VLC. Please download and install from the VLC web site: ' 'https://www.videolan.org/vlc/') else: packages = [] if not has_vlc: packages.append('python3-vlc') if not pymediainfo_available: packages.append('python3-pymediainfo') message = generic_message + '\n\n' + ', '.join(packages) if not has_vlc and is_linux(distro='fedora'): message += '\n\n' + fedora_rpmfusion State().missing_text('media_live', message) return True
from openlp.core.common.applocation import AppLocation from openlp.core.common.i18n import UiStrings, translate, get_natural_key from openlp.core.common.mixins import RegistryProperties from openlp.core.common.path import Path, path_to_str, create_paths from openlp.core.common.registry import Registry from openlp.core.common.settings import Settings from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, ServiceItem, ServiceItemContext, \ check_item_selected from openlp.core.lib.ui import create_widget_action, critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.ui import DisplayControllerType from openlp.core.ui.icons import UiIcons from openlp.core.ui.media import get_media_players, set_media_players, parse_optical_path, format_milliseconds from openlp.core.ui.media.vlcplayer import get_vlc if get_vlc() is not None: from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorForm log = logging.getLogger(__name__) CLAPPERBOARD = UiIcons().clapperboard class MediaMediaItem(MediaManagerItem, RegistryProperties): """ This is the custom media manager item for Media Slides. """ media_go_live = QtCore.pyqtSignal(list) media_add_to_service = QtCore.pyqtSignal(list) log.info('{name} MediaMediaItem loaded'.format(name=__name__))
# 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 # ############################################################################### """ Module to test the MediaClipSelectorForm. """ import os from unittest import TestCase, SkipTest from openlp.core.ui.media.vlcplayer import get_vlc if os.name == 'nt' and not get_vlc(): raise SkipTest('Windows without VLC, skipping this test since it cannot run without vlc') from PyQt4 import QtGui, QtTest, QtCore from openlp.core.common import Registry from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorForm from tests.interfaces import MagicMock, patch from tests.helpers.testmixin import TestMixin class TestMediaClipSelectorForm(TestCase, TestMixin): """ Test the EditCustomSlideForm. """ def setUp(self):
def on_titles_combo_box_currentIndexChanged(self, index): """ When a new title is chosen, it is loaded by VLC and info about audio and subtitle tracks is reloaded :param index: The index of the newly chosen title track. """ log.debug('in on_titles_combo_box_changed, index: {index:d}'.format( index=index)) vlc = get_vlc() if not self.vlc_media_player: log.error('vlc_media_player was None') return self.application.set_busy_cursor() if self.audio_cd: self.vlc_media = self.audio_cd_tracks.item_at_index(index) self.vlc_media_player.set_media(self.vlc_media) self.vlc_media_player.set_time(0) self.vlc_media_player.play() if not self.media_state_wait(vlc.State.Playing): log.error( 'Could not start playing audio cd, needed to get track info' ) self.application.set_normal_cursor() return self.vlc_media_player.audio_set_mute(True) # pause self.vlc_media_player.set_time(0) self.vlc_media_player.set_pause(1) self.vlc_media_player.audio_set_mute(False) self.application.set_normal_cursor() self.toggle_disable_player(False) else: self.vlc_media_player.set_title(index) self.vlc_media_player.set_time(0) self.vlc_media_player.play() if not self.media_state_wait(vlc.State.Playing): log.error( 'Could not start playing dvd, needed to get track info') self.application.set_normal_cursor() return self.vlc_media_player.audio_set_mute(True) # Get audio tracks audio_tracks = self.vlc_media_player.audio_get_track_description() log.debug('number of audio tracks: {tracks:d}'.format( tracks=len(audio_tracks))) # Clear the audio track combobox, insert new tracks self.audio_tracks_combobox.clear() for audio_track in audio_tracks: self.audio_tracks_combobox.addItem(audio_track[1].decode(), audio_track[0]) # Enable audio track combobox if anything is in it if len(audio_tracks) > 0: self.audio_tracks_combobox.setDisabled(False) # First track is "deactivated", so set to next if it exists if len(audio_tracks) > 1: self.audio_tracks_combobox.setCurrentIndex(1) # Get subtitle tracks, insert in combobox subtitles_tracks = self.vlc_media_player.video_get_spu_description( ) self.subtitle_tracks_combobox.clear() for subtitle_track in subtitles_tracks: self.subtitle_tracks_combobox.addItem( subtitle_track[1].decode(), subtitle_track[0]) # Enable subtitle track combobox is anything in it if len(subtitles_tracks) > 0: self.subtitle_tracks_combobox.setDisabled(False) self.vlc_media_player.audio_set_mute(False) self.vlc_media_player.set_pause(1) # If a title or audio track is available the player is enabled if self.titles_combo_box.count() > 0 or len(audio_tracks) > 0: self.toggle_disable_player(False) # Set media length info self.playback_length = self.vlc_media_player.get_length() log.debug('playback_length: {length:d} ms'.format( length=self.playback_length)) # if length is 0, wait a bit, maybe vlc will change its mind... loop_count = 0 while self.playback_length == 0 and loop_count < 20: sleep(0.1) self.playback_length = self.vlc_media_player.get_length() loop_count += 1 log.debug('in loop, playback_length: {length:d} ms'.format( length=self.playback_length)) self.position_slider.setMaximum(self.playback_length) # setup start and end time rounded_vlc_ms_length = int( round(self.playback_length / 100.0) * 100.0) time = QtCore.QTime(0, 0, 0) playback_length_time = time.addMSecs(rounded_vlc_ms_length) self.start_position_edit.setMaximumTime(playback_length_time) self.end_timeedit.setMaximumTime(playback_length_time) self.end_timeedit.setTime(playback_length_time) # Pause once again, just to make sure loop_count = 0 while self.vlc_media_player.get_state( ) == vlc.State.Playing and loop_count < 20: sleep(0.1) self.vlc_media_player.set_pause(1) loop_count += 1 log.debug('titles_combo_box end - ' 'vlc_media_player state: {state}'.format( state=self.vlc_media_player.get_state())) self.application.set_normal_cursor()
def on_load_disc_button_clicked(self, clicked): """ Load the media when the load-button has been clicked :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() # Check if given path is non-empty and exists before starting VLC if not path: log.debug('no given path') critical_error_message_box(message=translate( 'MediaPlugin.MediaClipSelectorForm', 'No path was given')) self.toggle_disable_load_media(False) self.application.set_normal_cursor() return if not os.path.exists(path): log.debug('Given path does not exists') critical_error_message_box( message=translate('MediaPlugin.MediaClipSelectorForm', 'Given path does not exists')) self.toggle_disable_load_media(False) self.application.set_normal_cursor() return # VLC behaves a bit differently on windows and linux when loading, which creates problems when trying to # detect if we're dealing with a DVD or CD, so we use different loading approaches depending on the OS. if is_win(): # If the given path is in the format "D:\" or "D:", prefix it with "/" to make VLC happy pattern = re.compile(r'^\w:\\\\*$') if pattern.match(path): path = '/' + path self.vlc_media = self.vlc_instance.media_new_location('dvd://' + path) else: self.vlc_media = self.vlc_instance.media_new_path(path) if not self.vlc_media: log.debug('vlc media player is none') critical_error_message_box(message=translate( 'MediaPlugin.MediaClipSelectorForm', 'An error happened during initialization of VLC player')) self.toggle_disable_load_media(False) self.application.set_normal_cursor() return # put the media in the media player self.vlc_media_player.set_media(self.vlc_media) self.vlc_media_player.audio_set_mute(True) # start playback to get vlc to parse the media if self.vlc_media_player.play() < 0: log.debug('vlc play returned error') critical_error_message_box( message=translate('MediaPlugin.MediaClipSelectorForm', 'VLC player failed playing the media')) self.toggle_disable_load_media(False) self.application.set_normal_cursor() self.vlc_media_player.audio_set_mute(False) return self.vlc_media_player.audio_set_mute(True) if not self.media_state_wait(vlc.State.Playing): # Tests if this is an audio CD if not self.detect_audio_cd(path): critical_error_message_box( message=translate('MediaPlugin.MediaClipSelectorForm', 'VLC player failed playing the media')) self.toggle_disable_load_media(False) self.application.set_normal_cursor() self.vlc_media_player.audio_set_mute(False) return # pause self.vlc_media_player.set_time(0) self.vlc_media_player.set_pause(1) self.media_state_wait(vlc.State.Paused) self.toggle_disable_load_media(False) self.application.set_normal_cursor() self.vlc_media_player.audio_set_mute(False) if not self.audio_cd: # Temporarily disable signals self.blockSignals(True) # Get titles, insert in combobox titles = self.vlc_media_player.video_get_title_description() self.titles_combo_box.clear() for title in titles: self.titles_combo_box.addItem(title.name.decode(), title.id) # Re-enable signals self.blockSignals(False) # Main title is usually title #1 if len(titles) > 1: self.titles_combo_box.setCurrentIndex(1) # Enable audio track combobox if anything is in it if len(titles) > 0: self.titles_combo_box.setDisabled(False) log.debug('load_disc_button end - ' 'vlc_media_player state: {state}'.format( state=self.vlc_media_player.get_state()))
# 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 # ############################################################################### """ Module to test the MediaClipSelectorForm. """ import os from unittest import TestCase, SkipTest from unittest.mock import MagicMock, patch from openlp.core.ui.media.vlcplayer import get_vlc if os.name == 'nt' and not get_vlc(): raise SkipTest( 'Windows without VLC, skipping this test since it cannot run without vlc' ) from PyQt5 import QtTest, QtCore, QtWidgets from openlp.core.common.registry import Registry from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorForm from tests.helpers.testmixin import TestMixin class TestMediaClipSelectorForm(TestCase, TestMixin): """ Test the EditCustomSlideForm.
import logging import os from PyQt4 import QtCore, QtGui from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, UiStrings,\ translate from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, ServiceItem, ServiceItemContext, \ build_icon, check_item_selected from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.ui import DisplayController, Display, DisplayControllerType from openlp.core.ui.media import get_media_players, set_media_players, parse_optical_path, format_milliseconds from openlp.core.utils import get_locale_key from openlp.core.ui.media.vlcplayer import get_vlc if get_vlc() is not None: from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorForm log = logging.getLogger(__name__) CLAPPERBOARD = ':/media/slidecontroller_multimedia.png' OPTICAL = ':/media/media_optical.png' VIDEO_ICON = build_icon(':/media/media_video.png') AUDIO_ICON = build_icon(':/media/media_audio.png') OPTICAL_ICON = build_icon(OPTICAL) ERROR_ICON = build_icon(':/general/general_delete.png') class MediaMediaItem(MediaManagerItem, RegistryProperties):