Hello community, here is the log from the commit of package python-pymediainfo for openSUSE:Factory checked in at 2020-05-01 11:14:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pymediainfo (Old) and /work/SRC/openSUSE:Factory/.python-pymediainfo.new.2738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pymediainfo" Fri May 1 11:14:19 2020 rev:7 rq:799193 version:4.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pymediainfo/python-pymediainfo.changes 2019-09-23 12:37:50.473605778 +0200 +++ /work/SRC/openSUSE:Factory/.python-pymediainfo.new.2738/python-pymediainfo.changes 2020-05-01 11:14:24.307984707 +0200 @@ -1,0 +2,18 @@ +Thu Apr 30 08:34:28 UTC 2020 - Luigi Baldoni <[email protected]> + +- Update to version 4.2.1 + Bug fixes: + * Fix version detection for Read the Docs documentation builds + version 4.2 + New features: + * Add a new output option to the parse method, this deprecates + the old test option (#82) + * Add support for os.PathLike objects (#72) + Bug fixes: + * Close and delete handle on errors to avoid memory leaks (#79) + * Fix thread-safety that was broken since v4.1 (#76 and #83), + document multi-threading limitations + * Document Python 3.8 support + * Show the correct pymediainfo version in documentation builds + +------------------------------------------------------------------- Old: ---- pymediainfo-4.1.tar.gz New: ---- pymediainfo-4.2.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pymediainfo.spec ++++++ --- /var/tmp/diff_new_pack.PKtBU5/_old 2020-05-01 11:14:25.911988196 +0200 +++ /var/tmp/diff_new_pack.PKtBU5/_new 2020-05-01 11:14:25.911988196 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-pymediainfo # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python-pymediainfo -Version: 4.1 +Version: 4.2.1 Release: 0 Summary: Python wrapper for the mediainfo library License: MIT @@ -51,9 +51,7 @@ %check export LANG=en_US.UTF-8 -%{python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} %{_bindir}/py.test-%{$python_version} -v \ - -k 'not MediaInfoURLTest and not MediaInfoLibraryTest' -} +%pytest -k 'not test_parse_url and not test_thread_safety' %files %{python_files} %doc README.rst ++++++ pymediainfo-4.1.tar.gz -> pymediainfo-4.2.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/PKG-INFO new/pymediainfo-4.2.1/PKG-INFO --- old/pymediainfo-4.1/PKG-INFO 2019-09-18 14:58:03.000000000 +0200 +++ new/pymediainfo-4.2.1/PKG-INFO 2020-04-30 00:08:01.000000000 +0200 @@ -1,11 +1,13 @@ Metadata-Version: 1.1 Name: pymediainfo -Version: 4.1 +Version: 4.2.1 Summary: A Python wrapper for the mediainfo library. Home-page: https://github.com/sbraz/pymediainfo Author: Louis Sautier Author-email: [email protected] License: MIT +Project-URL: Documentation, https://pymediainfo.readthedocs.io/ +Project-URL: Bugs, https://github.com/sbraz/pymediainfo/issues Description: pymediainfo ----------- @@ -30,7 +32,7 @@ This small package is a wrapper around the MediaInfo library. - It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 3.4, 3.5, 3.6, 3.7, PyPy and PyPy3. + It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, PyPy and PyPy3. See https://pymediainfo.readthedocs.io/ for more information. @@ -41,6 +43,7 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Operating System :: POSIX :: Linux diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/README.rst new/pymediainfo-4.2.1/README.rst --- old/pymediainfo-4.1/README.rst 2019-09-18 14:57:58.000000000 +0200 +++ new/pymediainfo-4.2.1/README.rst 2020-04-30 00:07:55.000000000 +0200 @@ -22,6 +22,6 @@ This small package is a wrapper around the MediaInfo library. -It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 3.4, 3.5, 3.6, 3.7, PyPy and PyPy3. +It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, PyPy and PyPy3. See https://pymediainfo.readthedocs.io/ for more information. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/appveyor.yml new/pymediainfo-4.2.1/appveyor.yml --- old/pymediainfo-4.1/appveyor.yml 2019-09-18 14:57:58.000000000 +0200 +++ new/pymediainfo-4.2.1/appveyor.yml 2020-04-30 00:07:55.000000000 +0200 @@ -1,18 +1,18 @@ environment: - MEDIAINFO_VERSION: 19.09 + MEDIAINFO_VERSION: 20.03 TWINE_PASSWORD: secure: /EO8CxTxhQVNsGNZZvU51jjHwPW524rgddNlwOAyLoA= matrix: - PYTHON: "C:/Python27" - - PYTHON: "C:/Python34" - PYTHON: "C:/Python35" - PYTHON: "C:/Python36" - PYTHON: "C:/Python37" + - PYTHON: "C:/Python38" - PYTHON: "C:/Python27-x64" - - PYTHON: "C:/Python34-x64" - PYTHON: "C:/Python35-x64" - PYTHON: "C:/Python36-x64" - PYTHON: "C:/Python37-x64" + - PYTHON: "C:/Python38-x64" install: - "SET PATH=%PYTHON%;%PYTHON%/Scripts;%PATH%" - "python --version" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/docs/conf.py new/pymediainfo-4.2.1/docs/conf.py --- old/pymediainfo-4.1/docs/conf.py 2019-09-18 14:57:58.000000000 +0200 +++ new/pymediainfo-4.2.1/docs/conf.py 2020-04-30 00:07:55.000000000 +0200 @@ -15,6 +15,9 @@ import sys import os +import subprocess + +import pkg_resources # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -47,17 +50,27 @@ # General information about the project. project = 'pymediainfo' -copyright = '2016, Patrick Altman, Louis Sautier' +copyright = 'Patrick Altman, Louis Sautier' author = 'Patrick Altman, Louis Sautier' -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.0' +# We can't use setuptools_scm's version on Read the Docs because they alter +# conf.py before running Sphinx, dirtying the repository, which results in +# an incorrect version being computed. +# https://github.com/pypa/setuptools_scm/issues/84 +# https://github.com/readthedocs/readthedocs.org/issues/2144 +# Instead, follow setuptools_scm's recommendation and rely on the +# version of the installed package (which is correct because +# the repository hasn't been changed prior to installation). +# https://github.com/pypa/setuptools_scm#usage-from-sphinx +if os.environ.get("READTHEDOCS") == "True": + version = pkg_resources.get_distribution(project).version +else: + # The project root is the parent directory + root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + # Get the version from setup.py --version (inspired by jaraco.packaging) + version = subprocess.check_output([sys.executable, "setup.py", "--version"], cwd=root, universal_newlines=True).strip() # The full version, including alpha/beta/rc tags. -release = '1.0' +release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/pymediainfo/__init__.py new/pymediainfo-4.2.1/pymediainfo/__init__.py --- old/pymediainfo-4.1/pymediainfo/__init__.py 2019-09-18 14:57:58.000000000 +0200 +++ new/pymediainfo-4.2.1/pymediainfo/__init__.py 2020-04-30 00:07:55.000000000 +0200 @@ -160,6 +160,15 @@ for xml_track in xml_dom.iterfind(xpath): self.tracks.append(Track(xml_track)) @staticmethod + def _parse_filename(filename): + if hasattr(os, "PathLike") and isinstance(filename, os.PathLike): + return os.fspath(filename), False + elif pathlib is not None and isinstance(filename, pathlib.PurePath): + return str(filename), False + else: + url = urlparse.urlparse(filename) + return filename, bool(url.scheme) + @staticmethod def _get_library(library_file=None): os_is_nt = os.name in ("nt", "dos", "os2", "ce") if os_is_nt: @@ -200,11 +209,13 @@ lib.MediaInfo_Delete.restype = None lib.MediaInfo_Close.argtypes = [ctypes.c_void_p] lib.MediaInfo_Close.restype = None - # Obtain the library version - lib_version_str = lib.MediaInfo_Option(None, "Info_Version", "") + # Without a handle, there might be problems when using concurrent threads + # https://github.com/sbraz/pymediainfo/issues/76#issuecomment-574759621 + handle = lib.MediaInfo_New() + lib_version_str = lib.MediaInfo_Option(handle, "Info_Version", "") lib_version_str = re.search(r"^MediaInfoLib - v(\S+)", lib_version_str).group(1) lib_version = tuple(int(_) for _ in lib_version_str.split(".")) - return (lib, lib_version_str, lib_version) + return (lib, handle, lib_version_str, lib_version) except OSError: # If we've tried all possible filenames if i == len(library_names): @@ -217,20 +228,25 @@ :rtype: bool """ try: - cls._get_library(library_file) + lib, handle = cls._get_library(library_file)[:2] + lib.MediaInfo_Close(handle) + lib.MediaInfo_Delete(handle) return True except: return False @classmethod def parse(cls, filename, library_file=None, cover_data=False, encoding_errors="strict", parse_speed=0.5, text=False, - full=True, legacy_stream_display=False, mediainfo_options=None): + full=True, legacy_stream_display=False, mediainfo_options=None, + output=None): """ Analyze a media file using libmediainfo. - If libmediainfo is located in a non-standard location, the `library_file` parameter can be used: - >>> pymediainfo.MediaInfo.parse("tests/data/sample.mkv", - ... library_file="/path/to/libmediainfo.dylib") + .. note:: + Because of the way the underlying library works, this method should not + be called simultaneously from multiple threads *with different arguments*. + Doing so will cause inconsistencies or failures by changing + library options that are shared across threads. :param filename: path to the media file which will be analyzed. A URL can also be used if libmediainfo was compiled @@ -243,15 +259,29 @@ this option takes values between 0 and 1. A higher value will yield more precise results in some cases but will also increase parsing time. - :param bool text: if ``True``, MediaInfo's text output will be returned instead - of a :class:`MediaInfo` object. :param bool full: display additional tags, including computer-readable values for sizes and durations. :param bool legacy_stream_display: display additional information about streams. :param dict mediainfo_options: additional options that will be passed to the `MediaInfo_Option` function, - for example: ``{"Language": "raw"}`` - :type filename: str or pathlib.Path - :rtype: str if `text` is ``True``. + for example: ``{"Language": "raw"}``. Do not use this parameter when running the + method simultaneously from multiple threads, it will trigger a reset of all options + which will cause inconsistencies or failures. + :param str output: custom output format for MediaInfo, corresponds to the CLI's + ``--Output`` parameter. Setting this causes the method to + return a `str` instead of a :class:`MediaInfo` object. + + Useful values include: + * the empty `str` ``""`` (corresponds to the default + text output, obtained when running ``mediainfo`` with no + additional parameters) + + * ``"XML"`` + + * ``"JSON"`` + + * ``%``-delimited templates (see ``mediainfo --Info-Parameters``) + :type filename: str or pathlib.Path or os.PathLike + :rtype: str if `output` is set. :rtype: :class:`MediaInfo` otherwise. :raises FileNotFoundError: if passed a non-existent file (Python ≥ 3.3), does not work on Windows. @@ -259,21 +289,28 @@ does not work on Windows. :raises RuntimeError: if parsing fails, this should not happen unless libmediainfo itself fails. + + Examples: + >>> pymediainfo.MediaInfo.parse("tests/data/sample.mkv") + <pymediainfo.MediaInfo object at 0x7fa83a3db240> + + >>> import json + >>> mi = pymediainfo.MediaInfo.parse("tests/data/sample.mkv", + ... output="JSON") + >>> json.loads(mi)["media"]["track"][0] + {'@type': 'General', 'TextCount': '1', 'FileExtension': 'mkv', + 'FileSize': '5904', … } + + """ - lib, lib_version_str, lib_version = cls._get_library(library_file) - if pathlib is not None and isinstance(filename, pathlib.PurePath): - filename = str(filename) - url = False - else: - url = urlparse.urlparse(filename) + lib, handle, lib_version_str, lib_version = cls._get_library(library_file) + filename, is_url = cls._parse_filename(filename) # Try to open the file (if it's not a URL) # Doesn't work on Windows because paths are URLs - if not (url and url.scheme): + if not is_url: # Test whether the file is readable with open(filename, "rb"): pass - # Create a MediaInfo handle - handle = lib.MediaInfo_New() # The XML option was renamed starting with version 17.10 if lib_version >= (17, 10): xml_option = "OLDXML" @@ -290,7 +327,13 @@ if (sys.version_info < (3,) and os.name == "posix" and locale.getlocale() == (None, None)): locale.setlocale(locale.LC_CTYPE, locale.getdefaultlocale()) - lib.MediaInfo_Option(handle, "Inform", "" if text else xml_option) + if text: + warnings.warn('The "text" option is obsolete and will be removed ' + 'in the next major version. Use output="" instead.', + DeprecationWarning + ) + output = "" + lib.MediaInfo_Option(handle, "Inform", xml_option if output is None else output) lib.MediaInfo_Option(handle, "Complete", "1" if full else "") lib.MediaInfo_Option(handle, "ParseSpeed", str(parse_speed)) lib.MediaInfo_Option(handle, "LegacyStreamDisplay", "1" if legacy_stream_display else "") @@ -304,21 +347,25 @@ for option_name, option_value in mediainfo_options.items(): lib.MediaInfo_Option(handle, option_name, option_value) if lib.MediaInfo_Open(handle, filename) == 0: + lib.MediaInfo_Close(handle) + lib.MediaInfo_Delete(handle) raise RuntimeError("An eror occured while opening {}" " with libmediainfo".format(filename)) - output = lib.MediaInfo_Inform(handle, 0) + info = lib.MediaInfo_Inform(handle, 0) # Reset all options to their defaults so that they aren't # retained when the parse method is called several times # https://github.com/MediaArea/MediaInfoLib/issues/1128 - if lib_version > (19, 7): + # Do not call it when it is not required because it breaks threads + # https://github.com/sbraz/pymediainfo/issues/76#issuecomment-575245093 + if mediainfo_options is not None and lib_version >= (19, 9): lib.MediaInfo_Option(handle, "Reset", "") # Delete the handle lib.MediaInfo_Close(handle) lib.MediaInfo_Delete(handle) - if text: - return output + if output is None: + return cls(info, encoding_errors) else: - return cls(output, encoding_errors) + return info def to_data(self): """ Returns a dict representation of the object's :py:class:`Tracks <Track>`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/pymediainfo.egg-info/PKG-INFO new/pymediainfo-4.2.1/pymediainfo.egg-info/PKG-INFO --- old/pymediainfo-4.1/pymediainfo.egg-info/PKG-INFO 2019-09-18 14:58:02.000000000 +0200 +++ new/pymediainfo-4.2.1/pymediainfo.egg-info/PKG-INFO 2020-04-30 00:08:01.000000000 +0200 @@ -1,11 +1,13 @@ Metadata-Version: 1.1 Name: pymediainfo -Version: 4.1 +Version: 4.2.1 Summary: A Python wrapper for the mediainfo library. Home-page: https://github.com/sbraz/pymediainfo Author: Louis Sautier Author-email: [email protected] License: MIT +Project-URL: Documentation, https://pymediainfo.readthedocs.io/ +Project-URL: Bugs, https://github.com/sbraz/pymediainfo/issues Description: pymediainfo ----------- @@ -30,7 +32,7 @@ This small package is a wrapper around the MediaInfo library. - It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 3.4, 3.5, 3.6, 3.7, PyPy and PyPy3. + It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, PyPy and PyPy3. See https://pymediainfo.readthedocs.io/ for more information. @@ -41,6 +43,7 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Operating System :: POSIX :: Linux diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/setup.py new/pymediainfo-4.2.1/setup.py --- old/pymediainfo-4.1/setup.py 2019-09-18 14:57:58.000000000 +0200 +++ new/pymediainfo-4.2.1/setup.py 2020-04-30 00:07:55.000000000 +0200 @@ -36,6 +36,10 @@ author='Louis Sautier', author_email='[email protected]', url='https://github.com/sbraz/pymediainfo', + project_urls={ + "Documentation": "https://pymediainfo.readthedocs.io/", + "Bugs": "https://github.com/sbraz/pymediainfo/issues", + }, description="""A Python wrapper for the mediainfo library.""", long_description=long_description, packages=find_packages(), @@ -57,6 +61,7 @@ "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Operating System :: POSIX :: Linux", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymediainfo-4.1/tests/test_pymediainfo.py new/pymediainfo-4.2.1/tests/test_pymediainfo.py --- old/pymediainfo-4.1/tests/test_pymediainfo.py 2019-09-18 14:57:58.000000000 +0200 +++ new/pymediainfo-4.2.1/tests/test_pymediainfo.py 2020-04-30 00:07:55.000000000 +0200 @@ -5,6 +5,8 @@ import unittest import xml import pickle +import threading +import json import pytest @@ -19,6 +21,12 @@ data_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data") +def _get_library_version(): + lib, handle, lib_version_str, lib_version = MediaInfo._get_library() + lib.MediaInfo_Close(handle) + lib.MediaInfo_Delete(handle) + return lib_version_str, lib_version + class MediaInfoTest(unittest.TestCase): def setUp(self): with open(os.path.join(data_dir, 'sample.xml'), 'r') as f: @@ -96,7 +104,7 @@ class MediaInfoURLTest(unittest.TestCase): def setUp(self): - self.mi = MediaInfo.parse("https://github.com/sbraz/pymediainfo/blob/master/tests/data/sample.mkv?raw=true") + self.mi = MediaInfo.parse("https://github.com/sbraz/pymediainfo/raw/master/tests/data/sample.mkv") def test_parse_url(self): self.assertEqual(len(self.mi.tracks), 2) @@ -112,6 +120,33 @@ path = self.pathlib.Path(data_dir) / "this file does not exist" self.assertRaises(FileNotFoundError, MediaInfo.parse, path) +class MediaInfoFilenameTypesTest(unittest.TestCase): + def test_parse_filename_str(self): + path = os.path.join(data_dir, "test.txt") + filename, is_url = MediaInfo._parse_filename(path) + # Windows paths are URLs + if not os_is_nt: + self.assertFalse(is_url) + self.assertEqual(filename, path) + def test_parse_filename_pathlib(self): + pathlib = pytest.importorskip("pathlib") + path = pathlib.Path(data_dir, "test.txt") + filename, is_url = MediaInfo._parse_filename(path) + self.assertFalse(is_url) + self.assertEqual(filename, os.path.join(data_dir, "test.txt")) + @pytest.mark.skipif(sys.version_info < (3, 6), reason="os.PathLike requires Python 3.6") + def test_parse_filename_pathlike(self): + class PathLikeObject(os.PathLike): + def __fspath__(self): + return os.path.join(data_dir, "test.txt") + path = PathLikeObject() + filename, is_url = MediaInfo._parse_filename(path) + self.assertFalse(is_url) + self.assertEqual(filename, os.path.join(data_dir, "test.txt")) + def test_parse_filename_url(self): + filename, is_url = MediaInfo._parse_filename("https://localhost") + self.assertTrue(is_url) + class MediaInfoTestParseNonExistentFile(unittest.TestCase): @pytest.mark.skipif(os_is_nt, reason="Windows paths are URLs") def test_parse_non_existent_path(self): @@ -134,9 +169,9 @@ "AAAQCEeRdzAAAADUlEQVR4nGP4x8DwHwAE/AH+QSRCQgAAAABJRU5ErkJggg==" ) def test_parse_no_cover_data(self): - _, lib_version_str, lib_version = MediaInfo._get_library() + lib_version_str, lib_version = _get_library_version() if lib_version < (18, 3): - pytest.skip("Cover_Data option not supported by this library version " + pytest.skip("The Cover_Data option is not supported by this library version " "(v{} detected, v18.03 required)".format(lib_version_str) ) self.assertEqual(self.no_cover_mi.tracks[0].cover_data, None) @@ -194,9 +229,9 @@ class MediaInfoOptionsTest(unittest.TestCase): def setUp(self): - _, lib_version_str, lib_version = MediaInfo._get_library() + lib_version_str, lib_version = _get_library_version() if lib_version < (19, 9): - pytest.skip("Reset option not supported by this library version " + pytest.skip("The Reset option is not supported by this library version " "(v{} detected, v19.09 required)".format(lib_version_str) ) self.raw_language_mi = MediaInfo.parse( @@ -212,3 +247,56 @@ def test_mediainfo_options(self): self.assertEqual(self.normal_mi.tracks[1].other_language[0], "English") self.assertEqual(self.raw_language_mi.tracks[1].language, "en") + +# Unittests can't be parametrized +# https://github.com/pytest-dev/pytest/issues/541 [email protected]("test_file", ["sample.mkv", "sample.mp4", "sample_with_cover.mp3"]) +def test_thread_safety(test_file): + lib_version_str, lib_version = _get_library_version() + if lib_version < (20, 3): + pytest.skip("This version of the library is not thread-safe " + "(v{} detected, v20.03 required)".format(lib_version_str) + ) + expected_result = MediaInfo.parse(os.path.join(data_dir, test_file)) + results = [] + lock = threading.Lock() + def target(): + try: + result = MediaInfo.parse(os.path.join(data_dir, test_file)) + with lock: + results.append(result) + except: + pass + threads = [] + thread_count = 100 + for i in range(thread_count): + t = threading.Thread(target=target) + t.start() + threads.append(t) + for t in threads: + t.join() + # Each thread should have produced a result + assert len(results) == thread_count + maxDiff = None + for r in results: + # Test dicts first because they will show a diff + # in case they don't match + assert r.to_data() == expected_result.to_data() + assert r == expected_result + +class MediaInfoOutputTest(unittest.TestCase): + def test_text_output(self): + mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"), output="") + self.assertRegex(mi, r"Stream size\s+: 373836\b") + def test_json_output(self): + lib_version_str, lib_version = _get_library_version() + if lib_version < (18, 3): + pytest.skip("This version of the library does not support JSON output " + "(v{} detected, v18.03 required)".format(lib_version_str) + ) + mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"), output="JSON") + parsed = json.loads(mi) + self.assertEqual(parsed["media"]["track"][0]["FileSize"], "404567") + def test_parameter_output(self): + mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"), output="General;%FileSize%") + self.assertEqual(mi, "404567")
