Try to work around pymediainfo exception

This commit is contained in:
Raoul Snyman 2022-06-21 18:51:57 +00:00
parent 2464d83031
commit 3b38e5baa8
2 changed files with 20 additions and 14 deletions

View File

@ -22,6 +22,7 @@
The :mod:`~openlp.core.ui.media.mediacontroller` module is the control module for all media playing.
"""
import logging
from pathlib import Path
try:
from pymediainfo import MediaInfo
@ -252,7 +253,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
controller.media_info.media_type = MediaType.Stream
elif service_item.is_capable(ItemCapabilities.HasBackgroundVideo):
controller.media_info.file_info = [service_item.video_file_name]
service_item.media_length = self.media_length(path_to_str(service_item.video_file_name))
service_item.media_length = self.media_length(service_item.video_file_name)
controller.media_info.is_looping_playback = True
controller.media_info.is_background = True
else:
@ -349,7 +350,10 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
:param media_path: The file path to be checked..
"""
if MediaInfo.can_parse():
media_data = MediaInfo.parse(media_path)
# pymediainfo has an issue opening non-ascii file names, so pass it a file object instead
# See https://gitlab.com/openlp/openlp/-/issues/1041
with Path(media_path).open('rb') as media_file:
media_data = MediaInfo.parse(media_file)
# duration returns in milli seconds
return media_data.tracks[0].duration or 0
return 0

View File

@ -21,10 +21,11 @@
"""
Package to test the openlp.core.ui.media package.
"""
import pytest
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from openlp.core.common.registry import Registry
from openlp.core.ui import DisplayControllerType, HideMode
from openlp.core.ui.media.mediacontroller import MediaController
@ -324,23 +325,24 @@ def test_media_hide(media_env, registry):
assert 'media player' in media_env.media_controller.current_media_players
def test_media_length(media_env):
@pytest.mark.parametrize('file_name,media_length', TEST_MEDIA)
def test_media_length(file_name, media_length, media_env):
"""
Check the duration of a few different files via MediaInfo
"""
for test_data in TEST_MEDIA:
# GIVEN: a media file
full_path = str(TEST_PATH / test_data[0])
# GIVEN: a media file
full_path = TEST_PATH / file_name
# WHEN the media data is retrieved
results = media_env.media_controller.media_length(full_path)
# WHEN the media data is retrieved
results = media_env.media_controller.media_length(full_path)
# THEN you can determine the run time
assert results == test_data[1], 'The correct duration is returned for ' + test_data[0]
# THEN you can determine the run time
assert results == media_length, f'The correct duration for {file_name} should be {media_length}, was {results}'
@patch('openlp.core.ui.media.mediacontroller.MediaInfo.parse')
def test_media_length_duration_none(mocked_parse, media_env):
@patch('openlp.core.ui.media.mediacontroller.Path')
def test_media_length_duration_none(MockPath, mocked_parse, media_env):
"""
Test that when MediaInfo doesn't give us a duration, we default to 0
"""
@ -362,7 +364,7 @@ def test_media_length_no_can_parse(mocked_can_parse, media_env):
"""
# GIVEN: A fake media file and a mocked MediaInfo.can_parse() function
mocked_can_parse.return_value = False
file_path = 'path/to/fake/video.mkv'
file_path = Path('path/to/fake/video.mkv')
# WHEN the media data is retrieved
duration = media_env.media_controller.media_length(file_path)