Merge branch 'issue-1187' into 'master'

Handle different versions of pymediainfo

Closes #1187

See merge request openlp/openlp!512
This commit is contained in:
Raoul Snyman 2022-11-30 14:37:27 +00:00
commit a9df04b796
2 changed files with 53 additions and 6 deletions

View File

@ -25,10 +25,11 @@ import logging
from pathlib import Path
try:
from pymediainfo import MediaInfo
from pymediainfo import MediaInfo, __version__ as pymediainfo_version
pymediainfo_available = True
except ImportError:
pymediainfo_available = False
pymediainfo_version = '0.0'
from PyQt5 import QtCore
@ -350,11 +351,16 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
:param media_path: The file path to be checked..
"""
if MediaInfo.can_parse():
# 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
if pymediainfo_version < '4.3':
# pymediainfo only introduced file objects in 4.3, so if this is an older version, we'll have to use
# the old method. See https://gitlab.com/openlp/openlp/-/issues/1187
media_data = MediaInfo.parse(str(media_path))
else:
# 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

@ -357,6 +357,47 @@ def test_media_length_duration_none(MockPath, mocked_parse, media_env):
assert duration == 0, 'The duration should be 0'
@patch('openlp.core.ui.media.mediacontroller.MediaInfo.parse')
def test_media_length_duration_old_version(mocked_parse, media_env):
"""
Test that when a version of MediaInfo < 4.3 is installed, a file name is passed directly to the parse method
"""
# GIVEN: A fake media file and a mocked MediaInfo.parse() function
from openlp.core.ui.media import mediacontroller
mediacontroller.pymediainfo_version = '4.0.1'
mocked_parse.return_value = MagicMock(tracks=[MagicMock(duration=10)])
file_path = 'path/to/fake/video.mkv'
# WHEN the media data is retrieved
duration = media_env.media_controller.media_length(file_path)
# THEN you can determine the run time
mocked_parse.assert_called_once_with('path/to/fake/video.mkv')
assert duration == 10, 'The duration should be 10'
@patch('openlp.core.ui.media.mediacontroller.Path')
@patch('openlp.core.ui.media.mediacontroller.MediaInfo.parse')
def test_media_length_duration_new_version(mocked_parse, MockPath, media_env):
"""
Test that when a version of MediaInfo > 4.3 is installed, a file OBJECT is passed to the parse method
"""
# GIVEN: A fake media file and a mocked MediaInfo.parse() function
from openlp.core.ui.media import mediacontroller
mediacontroller.pymediainfo_version = '5.0.3'
mocked_file = MagicMock()
MockPath.return_value.open.return_value.__enter__.return_value = mocked_file
mocked_parse.return_value = MagicMock(tracks=[MagicMock(duration=8)])
file_path = 'path/to/fake/video.mkv'
# WHEN the media data is retrieved
duration = media_env.media_controller.media_length(file_path)
# THEN you can determine the run time
mocked_parse.assert_called_once_with(mocked_file)
assert duration == 8, 'The duration should be 8'
@patch('openlp.core.ui.media.mediacontroller.MediaInfo.can_parse')
def test_media_length_no_can_parse(mocked_can_parse, media_env):
"""