Hello community,
here is the log from the commit of package python-pymediainfo for
openSUSE:Leap:15.2 checked in at 2020-02-19 18:49:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-pymediainfo (Old)
and /work/SRC/openSUSE:Leap:15.2/.python-pymediainfo.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pymediainfo"
Wed Feb 19 18:49:21 2020 rev:11 rq:776988 version:4.1
Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/python-pymediainfo/python-pymediainfo.changes
2020-01-15 15:52:01.571549166 +0100
+++
/work/SRC/openSUSE:Leap:15.2/.python-pymediainfo.new.26092/python-pymediainfo.changes
2020-02-19 18:49:23.123074265 +0100
@@ -1,0 +2,50 @@
+Wed Sep 18 14:25:50 UTC 2019 - Luigi Baldoni <[email protected]>
+
+- Update to version 4.1
+ * Added an argument to pass custom options to the parse method
+ (#71)
+
+-------------------------------------------------------------------
+Sat Sep 14 07:30:51 UTC 2019 - Luigi Baldoni <[email protected]>
+
+- Fixed tests in Factory
+
+-------------------------------------------------------------------
+Mon Apr 22 13:56:26 UTC 2019 - Luigi Baldoni <[email protected]>
+
+- Update to version 4.0
+ * Drop Python 2.6 compatibility
+ * Allow pickling of Track instances (#68)
+ * Remove xml attributes from Track and MediaInfo objects,
+ populate the tracks attribute immediately (03f6242)
+ * Implement __eq__ forTrack and MediaInfo objects
+ * Add an option to obtain MediaInfo's text output (#66)
+ * Add an option to return non-complete MediaInfo (#66)
+ * Disable LegacyStreamDisplay explicitly by default, make it
+ configurable (see 9aa65d8 for details)
+ version 3.2.1:
+ * Generate sdists on Linux instead of OSX (#67)
+ version 3.2:
+ * Publish wheels containing libmediainfo (#59, thanks to
+ @bgermann)
+ version 3.1:
+ * Add an option to control parsing speed (#65)
+ version 3.0:
+ * Do not ignore exceptions when invalid XML is passed (#53)
+ * Raise RuntimeError if parsing fails
+ * Add an option to ignore UTF-8 encoding errors, fixes (#54)
+ * Use proper XPath to detect track elements in XML (#55)
+ * Fix handling of non-existent files
+ * Fix tests with libmediainfo ≥ 18.08 (#58)
+ * Try to load libmediainfo from the module folder
+
+-------------------------------------------------------------------
+Wed Sep 12 07:12:47 UTC 2018 - [email protected]
+
+- Update to version 2.3.0
+ * Add setuptools to install_requires (#50)
+ * Add an option to extract cover_data for libmediainfo ≥ 18.03
+ (#51)
+ * Get version from setuptools_scm
+
+-------------------------------------------------------------------
Old:
----
pymediainfo-2.2.0.tar.gz
New:
----
pymediainfo-4.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pymediainfo.spec ++++++
--- /var/tmp/diff_new_pack.nQ1Ag2/_old 2020-02-19 18:49:23.423074584 +0100
+++ /var/tmp/diff_new_pack.nQ1Ag2/_new 2020-02-19 18:49:23.427074588 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-pymediainfo
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -12,27 +12,26 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pymediainfo
-Version: 2.2.0
+Version: 4.1
Release: 0
Summary: Python wrapper for the mediainfo library
License: MIT
Group: Development/Languages/Python
-Url: https://github.com/sbraz/pymediainfo
+URL: https://github.com/sbraz/pymediainfo
Source0:
https://files.pythonhosted.org/packages/source/p/pymediainfo/pymediainfo-%{version}.tar.gz
Source99: %{name}-rpmlintrc
BuildRequires: %{python_module pytest}
+BuildRequires: %{python_module setuptools_scm}
BuildRequires: %{python_module setuptools}
BuildRequires: libmediainfo0
Requires: libmediainfo0
BuildRequires: fdupes
BuildRequires: python-rpm-macros
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
%python_subpackages
@@ -52,11 +51,13 @@
%check
export LANG=en_US.UTF-8
-%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} $python
%{_bindir}/py.test -v -k 'not MediaInfoURLTest'
+%{python_expand PYTHONPATH=%{buildroot}%{$python_sitelib}
%{_bindir}/py.test-%{$python_version} -v \
+ -k 'not MediaInfoURLTest and not MediaInfoLibraryTest'
+}
%files %{python_files}
-%defattr(-,root,root,-)
%doc README.rst
+%license LICENSE
%{python_sitelib}/*
%changelog
++++++ pymediainfo-2.2.0.tar.gz -> pymediainfo-4.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/AUTHORS new/pymediainfo-4.1/AUTHORS
--- old/pymediainfo-2.2.0/AUTHORS 1970-01-01 01:00:00.000000000 +0100
+++ new/pymediainfo-4.1/AUTHORS 2019-09-18 14:57:58.000000000 +0200
@@ -0,0 +1,3 @@
+Patrick Altman <[email protected]> (author)
+cjlucas https://github.com/cjlucas
+Louis Sautier <[email protected]> (maintainer since 2016)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/LICENSE new/pymediainfo-4.1/LICENSE
--- old/pymediainfo-2.2.0/LICENSE 1970-01-01 01:00:00.000000000 +0100
+++ new/pymediainfo-4.1/LICENSE 2019-09-18 14:57:58.000000000 +0200
@@ -0,0 +1,24 @@
+The MIT License
+
+Copyright (c) 2010-2014, Patrick Altman <[email protected]>
+Copyright (c) 2016, Louis Sautier <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+http://www.opensource.org/licenses/mit-license.php
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/PKG-INFO
new/pymediainfo-4.1/PKG-INFO
--- old/pymediainfo-2.2.0/PKG-INFO 2017-11-08 00:10:33.000000000 +0100
+++ new/pymediainfo-4.1/PKG-INFO 2019-09-18 14:58:03.000000000 +0200
@@ -1,19 +1,46 @@
Metadata-Version: 1.1
Name: pymediainfo
-Version: 2.2.0
+Version: 4.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
-Description: UNKNOWN
+Description: pymediainfo
+ -----------
+
+ .. image:: https://img.shields.io/pypi/v/pymediainfo.svg
+ :target: https://pypi.org/project/pymediainfo
+
+ .. image:: https://img.shields.io/pypi/pyversions/pymediainfo.svg
+ :target: https://pypi.org/project/pymediainfo
+
+ .. image:: https://repology.org/badge/tiny-repos/python:pymediainfo.svg
+ :target: https://repology.org/metapackage/python:pymediainfo
+
+ .. image:: https://img.shields.io/pypi/implementation/pymediainfo.svg
+ :target: https://pypi.org/project/pymediainfo
+
+ .. image::
https://api.travis-ci.org/sbraz/pymediainfo.svg?branch=master
+ :target: https://travis-ci.org/sbraz/pymediainfo
+
+ .. image::
https://ci.appveyor.com/api/projects/status/g15a2daem1oub57n/branch/master?svg=true
+ :target: https://ci.appveyor.com/project/sbraz/pymediainfo
+
+
+ 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.
+
+ See https://pymediainfo.readthedocs.io/ for more information.
+
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
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-2.2.0/README.rst
new/pymediainfo-4.1/README.rst
--- old/pymediainfo-2.2.0/README.rst 2017-11-08 00:10:07.000000000 +0100
+++ new/pymediainfo-4.1/README.rst 2019-09-18 14:57:58.000000000 +0200
@@ -7,15 +7,21 @@
.. image:: https://img.shields.io/pypi/pyversions/pymediainfo.svg
:target: https://pypi.org/project/pymediainfo
+.. image:: https://repology.org/badge/tiny-repos/python:pymediainfo.svg
+ :target: https://repology.org/metapackage/python:pymediainfo
+
.. image:: https://img.shields.io/pypi/implementation/pymediainfo.svg
:target: https://pypi.org/project/pymediainfo
.. image:: https://api.travis-ci.org/sbraz/pymediainfo.svg?branch=master
:target: https://travis-ci.org/sbraz/pymediainfo
+.. image::
https://ci.appveyor.com/api/projects/status/g15a2daem1oub57n/branch/master?svg=true
+ :target: https://ci.appveyor.com/project/sbraz/pymediainfo
+
+
+This small package is a wrapper around the MediaInfo library.
-This small package is a wrapper around the MediaInfo library. It works on
-Linux, Mac OS X and Windows.
-It is tested on Python 2.6, 2.7, 3.4, 3.5, 3.6, 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, PyPy and PyPy3.
See https://pymediainfo.readthedocs.io/ for more information.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/appveyor.yml
new/pymediainfo-4.1/appveyor.yml
--- old/pymediainfo-2.2.0/appveyor.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/pymediainfo-4.1/appveyor.yml 2019-09-18 14:57:58.000000000 +0200
@@ -0,0 +1,32 @@
+environment:
+ MEDIAINFO_VERSION: 19.09
+ TWINE_PASSWORD:
+ secure: /EO8CxTxhQVNsGNZZvU51jjHwPW524rgddNlwOAyLoA=
+ matrix:
+ - PYTHON: "C:/Python27"
+ - PYTHON: "C:/Python34"
+ - PYTHON: "C:/Python35"
+ - PYTHON: "C:/Python36"
+ - PYTHON: "C:/Python37"
+ - PYTHON: "C:/Python27-x64"
+ - PYTHON: "C:/Python34-x64"
+ - PYTHON: "C:/Python35-x64"
+ - PYTHON: "C:/Python36-x64"
+ - PYTHON: "C:/Python37-x64"
+install:
+ - "SET PATH=%PYTHON%;%PYTHON%/Scripts;%PATH%"
+ - "python --version"
+ - "IF %PYTHON:~-4% == -x64 (SET ARCH=x64) ELSE (SET ARCH=i386)"
+ - ps: "Start-FileDownload
https://mediaarea.net/download/binary/mediainfo/${Env:MEDIAINFO_VERSION}/MediaInfo_CLI_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}.zip"
+ - ps: "unzip -o
MediaInfo_CLI_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}.zip LIBCURL.DLL"
+ - ps: "Start-FileDownload
https://mediaarea.net/download/binary/libmediainfo0/${Env:MEDIAINFO_VERSION}/MediaInfo_DLL_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}_WithoutInstaller.7z"
+ - ps: "7z -y x
MediaInfo_DLL_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}_WithoutInstaller.7z
MediaInfo.dll Developers/License.html"
+ - "move MediaInfo.dll pymediainfo"
+ - "move Developers\\License.html docs"
+ - "pip install --upgrade setuptools pytest pytest-runner twine wheel"
+build_script:
+ - "python setup.py bdist_wheel"
+test_script:
+ - "python setup.py test"
+deploy_script:
+ - ps: If ($env:APPVEYOR_REPO_TAG -eq "true") { Invoke-Expression "twine
upload --skip-existing -u sbraz dist/*" }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/demo.py new/pymediainfo-4.1/demo.py
--- old/pymediainfo-2.2.0/demo.py 1970-01-01 01:00:00.000000000 +0100
+++ new/pymediainfo-4.1/demo.py 2019-09-18 14:57:58.000000000 +0200
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+"""
+a demo that shows how to call pymediainfo
+"""
+
+from __future__ import (absolute_import, division,
+ print_function, unicode_literals)
+
+import sys
+from pprint import pprint
+
+from pymediainfo import MediaInfo
+
+
+def print_frame(text):
+ print("+-{}-+".format("-" * len(text)))
+ print("| {} |".format(text))
+ print("+-{}-+".format("-" * len(text)))
+
+
+def process(fname):
+ media_info = MediaInfo.parse(fname)
+ for track in media_info.tracks:
+ print_frame(track.track_type)
+ pprint(track.to_data())
+ #
+ print()
+ for track in media_info.tracks:
+ if track.track_type == 'General' and track.duration:
+ print("Duration: {} sec.".format(track.duration / 1000.0))
+
+##############################################################################
+
+if __name__ == "__main__":
+ if len(sys.argv) == 1:
+ print("Usage: {} <media_file>".format(sys.argv[0]))
+ sys.exit(0)
+ if sys.version_info.major < 3:
+ process(sys.argv[1].decode(sys.getfilesystemencoding()))
+ else:
+ process(sys.argv[1])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/docs/conf.py
new/pymediainfo-4.1/docs/conf.py
--- old/pymediainfo-2.2.0/docs/conf.py 2017-11-08 00:10:07.000000000 +0100
+++ new/pymediainfo-4.1/docs/conf.py 2019-09-18 14:57:58.000000000 +0200
@@ -113,7 +113,10 @@
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
-#html_theme_options = {}
+html_theme_options = {
+ "page_width": "auto",
+ "fixed_sidebar": True
+}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/docs/index.rst
new/pymediainfo-4.1/docs/index.rst
--- old/pymediainfo-2.2.0/docs/index.rst 2017-11-08 00:10:07.000000000
+0100
+++ new/pymediainfo-4.1/docs/index.rst 2019-09-18 14:57:58.000000000 +0200
@@ -15,6 +15,10 @@
This is a simple wrapper around the MediaInfo library, which you can find
at https://mediaarea.net/en/MediaInfo
+Binary wheels containing the library are provided for Windows and Mac OS X.
+
+Packages are available for `several Linux distributions
<https://repology.org/metapackage/python:pymediainfo>`_.
+
===============
Using MediaInfo
===============
@@ -28,7 +32,7 @@
media_info = MediaInfo.parse('my_video_file.mov')
for track in media_info.tracks:
if track.track_type == 'Video':
- print track.bit_rate, track.bit_rate_mode, track.codec
+ print(track.bit_rate, track.bit_rate_mode, track.codec)
# output: 46033920 CBR DV
@@ -56,12 +60,14 @@
media_info = MediaInfo.parse('my_video_file.mov')
for track in media_info.tracks:
if track.bit_rate is not None:
- print "%s: %s" % (track.track_type, track.bit_rate)
+ print("{}: {}".format(track.track_type, track.bit_rate))
else:
- print """%s tracks do not have bit rate
- associated with them.""" % track.track_type
+ print("""{} tracks do not have bit rate
+ associated with them.""".format(track.track_type))
+
+Output:
-Output::
+.. code-block:: text
General tracks do not have bit rate associated with them.
Video: 46033920
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/pymediainfo/__init__.py
new/pymediainfo-4.1/pymediainfo/__init__.py
--- old/pymediainfo-2.2.0/pymediainfo/__init__.py 2017-11-08
00:10:07.000000000 +0100
+++ new/pymediainfo-4.1/pymediainfo/__init__.py 2019-09-18 14:57:58.000000000
+0200
@@ -1,11 +1,13 @@
+# vim: set fileencoding=utf-8 :
import os
import re
import locale
import json
+import ctypes
import sys
-from pkg_resources import get_distribution
+import warnings
+from pkg_resources import get_distribution, DistributionNotFound
import xml.etree.ElementTree as ET
-from ctypes import *
try:
import pathlib
@@ -17,7 +19,10 @@
else:
import urllib.parse as urlparse
-__version__ = get_distribution("pymediainfo").version
+try:
+ __version__ = get_distribution("pymediainfo").version
+except DistributionNotFound:
+ pass
class Track(object):
"""
@@ -44,16 +49,21 @@
All available attributes can be obtained by calling :func:`to_data`.
"""
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
def __getattribute__(self, name):
try:
return object.__getattribute__(self, name)
except:
pass
return None
+ def __getstate__(self):
+ return self.__dict__
+ def __setstate__(self, state):
+ self.__dict__ = state
def __init__(self, xml_dom_fragment):
- self.xml_dom_fragment = xml_dom_fragment
self.track_type = xml_dom_fragment.attrib['type']
- for el in self.xml_dom_fragment:
+ for el in xml_dom_fragment:
node_name = el.tag.lower().strip().strip('_')
if node_name == 'id':
node_name = 'track_id'
@@ -81,7 +91,7 @@
except:
pass
def __repr__(self):
- return("<Track track_id='{0}',
track_type='{1}'>".format(self.track_id, self.track_type))
+ return("<Track track_id='{}', track_type='{}'>".format(self.track_id,
self.track_type))
def to_data(self):
"""
Returns a dict representation of the track attributes.
@@ -114,39 +124,91 @@
>>> pymediainfo.MediaInfo.parse("/path/to/file.mp4")
Alternatively, objects may be created from MediaInfo's XML output.
- XML output can be obtained using the `XML` output format on versions older
than v17.10
- and the `OLDXML` format on newer versions.
+ Such output can be obtained using the ``XML`` output format on versions
older than v17.10
+ and the ``OLDXML`` format on newer versions.
Using such an XML file, we can create a :class:`MediaInfo` object:
>>> with open("output.xml") as f:
... mi = pymediainfo.MediaInfo(f.read())
- :param str xml: XML output obtained from MediaInfo
- """
- def __init__(self, xml):
- self.xml_dom = MediaInfo._parse_xml_data_into_dom(xml)
+ :param str xml: XML output obtained from MediaInfo.
+ :param str encoding_errors: option to pass to :func:`str.encode`'s `errors`
+ parameter before parsing `xml`.
+ :raises xml.etree.ElementTree.ParseError: if passed invalid XML.
+ :var tracks: A list of :py:class:`Track` objects which the media file
contains.
+ For instance:
- @staticmethod
- def _parse_xml_data_into_dom(xml_data):
- try:
- return ET.fromstring(xml_data.encode("utf-8"))
- except:
- return None
+ >>> mi = pymediainfo.MediaInfo.parse("/path/to/file.mp4")
+ >>> for t in mi.tracks:
+ ... print(t)
+ <Track track_id='None', track_type='General'>
+ <Track track_id='1', track_type='Text'>
+ """
+ def __eq__(self, other):
+ return self.tracks == other.tracks
+ def __init__(self, xml, encoding_errors="strict"):
+ xml_dom = ET.fromstring(xml.encode("utf-8", encoding_errors))
+ self.tracks = []
+ # This is the case for libmediainfo < 18.03
+ # https://github.com/sbraz/pymediainfo/issues/57
+ #
https://github.com/MediaArea/MediaInfoLib/commit/575a9a32e6960ea34adb3bc982c64edfa06e95eb
+ if xml_dom.tag == "File":
+ xpath = "track"
+ else:
+ xpath = "File/track"
+ for xml_track in xml_dom.iterfind(xpath):
+ self.tracks.append(Track(xml_track))
@staticmethod
def _get_library(library_file=None):
- if library_file is not None:
- return CDLL(library_file)
- elif os.name in ("nt", "dos", "os2", "ce"):
- if library_file is None:
- return windll.MediaInfo
- elif sys.platform == "darwin":
+ os_is_nt = os.name in ("nt", "dos", "os2", "ce")
+ if os_is_nt:
+ lib_type = ctypes.WinDLL
+ else:
+ lib_type = ctypes.CDLL
+ if library_file is None:
+ if os_is_nt:
+ library_names = ("MediaInfo.dll",)
+ elif sys.platform == "darwin":
+ library_names = ("libmediainfo.0.dylib", "libmediainfo.dylib")
+ else:
+ library_names = ("libmediainfo.so.0",)
+ script_dir = os.path.dirname(__file__)
+ # Look for the library file in the script folder
+ for library in library_names:
+ lib_path = os.path.join(script_dir, library)
+ if os.path.isfile(lib_path):
+ # If we find it, don't try any other filename
+ library_names = (lib_path,)
+ break
+ else:
+ library_names = (library_file,)
+ for i, library in enumerate(library_names, start=1):
try:
- return CDLL("libmediainfo.0.dylib")
+ lib = lib_type(library)
+ # Define arguments and return types
+ lib.MediaInfo_Inform.restype = ctypes.c_wchar_p
+ lib.MediaInfo_New.argtypes = []
+ lib.MediaInfo_New.restype = ctypes.c_void_p
+ lib.MediaInfo_Option.argtypes = [ctypes.c_void_p,
ctypes.c_wchar_p, ctypes.c_wchar_p]
+ lib.MediaInfo_Option.restype = ctypes.c_wchar_p
+ lib.MediaInfo_Inform.argtypes = [ctypes.c_void_p,
ctypes.c_size_t]
+ lib.MediaInfo_Inform.restype = ctypes.c_wchar_p
+ lib.MediaInfo_Open.argtypes = [ctypes.c_void_p,
ctypes.c_wchar_p]
+ lib.MediaInfo_Open.restype = ctypes.c_size_t
+ lib.MediaInfo_Delete.argtypes = [ctypes.c_void_p]
+ 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",
"")
+ 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)
except OSError:
- return CDLL("libmediainfo.dylib")
- else:
- return CDLL("libmediainfo.so.0")
+ # If we've tried all possible filenames
+ if i == len(library_names):
+ raise
@classmethod
def can_parse(cls, library_file=None):
"""
@@ -160,7 +222,9 @@
except:
return False
@classmethod
- def parse(cls, filename, library_file=None):
+ 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):
"""
Analyze a media file using libmediainfo.
If libmediainfo is located in a non-standard location, the
`library_file` parameter can be used:
@@ -169,44 +233,56 @@
... library_file="/path/to/libmediainfo.dylib")
:param filename: path to the media file which will be analyzed.
+ A URL can also be used if libmediainfo was compiled
+ with CURL support.
:param str library_file: path to the libmediainfo library, this should
only be used if the library cannot be auto-detected.
+ :param bool cover_data: whether to retrieve cover data as base64.
+ :param str encoding_errors: option to pass to :func:`str.encode`'s
`errors`
+ parameter before parsing MediaInfo's XML output.
+ :param float parse_speed: passed to the library as `ParseSpeed`,
+ 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: MediaInfo
+ :rtype: str if `text` is ``True``.
+ :rtype: :class:`MediaInfo` otherwise.
+ :raises FileNotFoundError: if passed a non-existent file
+ (Python ≥ 3.3), does not work on Windows.
+ :raises IOError: if passed a non-existent file (Python < 3.3),
+ does not work on Windows.
+ :raises RuntimeError: if parsing fails, this should not
+ happen unless libmediainfo itself fails.
"""
- lib = cls._get_library(library_file)
+ 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)
- # Test whether the filename is actually a URL
- if url.scheme is None:
- # Test whether the file is readable
- with open(filename, "rb"):
- pass
- # Define arguments and return types
- lib.MediaInfo_Inform.restype = c_wchar_p
- lib.MediaInfo_New.argtypes = []
- lib.MediaInfo_New.restype = c_void_p
- lib.MediaInfo_Option.argtypes = [c_void_p, c_wchar_p, c_wchar_p]
- lib.MediaInfo_Option.restype = c_wchar_p
- lib.MediaInfo_Inform.argtypes = [c_void_p, c_size_t]
- lib.MediaInfo_Inform.restype = c_wchar_p
- lib.MediaInfo_Open.argtypes = [c_void_p, c_wchar_p]
- lib.MediaInfo_Open.restype = c_size_t
- lib.MediaInfo_Delete.argtypes = [c_void_p]
- lib.MediaInfo_Delete.restype = None
- lib.MediaInfo_Close.argtypes = [c_void_p]
- lib.MediaInfo_Close.restype = None
- # Obtain the library version
- lib_version = lib.MediaInfo_Option(None, "Info_Version", "")
- lib_version = [int(_) for _ in re.search("^MediaInfoLib - v(\S+)",
lib_version).group(1).split(".")]
+ # 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):
+ # 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]:
+ if lib_version >= (17, 10):
xml_option = "OLDXML"
else:
xml_option = "XML"
- # Create a MediaInfo handle
- handle = lib.MediaInfo_New()
+ # Cover_Data is not extracted by default since version 18.03
+ # See
https://github.com/MediaArea/MediaInfoLib/commit/d8fd88a1c282d1c09388c55ee0b46029e7330690
+ if lib_version >= (18, 3):
+ lib.MediaInfo_Option(handle, "Cover_Data", "base64" if cover_data
else "")
lib.MediaInfo_Option(handle, "CharSet", "UTF-8")
# Fix for https://github.com/sbraz/pymediainfo/issues/22
# Python 2 does not change LC_CTYPE
@@ -214,38 +290,35 @@
if (sys.version_info < (3,) and os.name == "posix"
and locale.getlocale() == (None, None)):
locale.setlocale(locale.LC_CTYPE, locale.getdefaultlocale())
- lib.MediaInfo_Option(None, "Inform", xml_option)
- lib.MediaInfo_Option(None, "Complete", "1")
- lib.MediaInfo_Open(handle, filename)
- xml = lib.MediaInfo_Inform(handle, 0)
+ lib.MediaInfo_Option(handle, "Inform", "" if text else xml_option)
+ 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 "")
+ if mediainfo_options is not None:
+ if lib_version < (19, 9):
+ warnings.warn("This version of MediaInfo ({}) does not support
resetting all options to their default values, "
+ "passing it custom options is not recommended and may
result in unpredictable behavior, "
+ "see
https://github.com/MediaArea/MediaInfoLib/issues/1128".format(lib_version_str),
+ RuntimeWarning
+ )
+ for option_name, option_value in mediainfo_options.items():
+ lib.MediaInfo_Option(handle, option_name, option_value)
+ if lib.MediaInfo_Open(handle, filename) == 0:
+ raise RuntimeError("An eror occured while opening {}"
+ " with libmediainfo".format(filename))
+ output = 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):
+ lib.MediaInfo_Option(handle, "Reset", "")
# Delete the handle
lib.MediaInfo_Close(handle)
lib.MediaInfo_Delete(handle)
- return cls(xml)
- def _populate_tracks(self):
- if self.xml_dom is None:
- return
- iterator = "getiterator" if sys.version_info < (2, 7) else "iter"
- for xml_track in getattr(self.xml_dom, iterator)("track"):
- self._tracks.append(Track(xml_track))
- @property
- def tracks(self):
- """
- A list of :py:class:`Track` objects which the media file contains.
-
- For instance:
-
- >>> mi = pymediainfo.MediaInfo.parse("/path/to/file.mp4")
- >>> for t in mi.tracks:
- ... print(t)
- <Track track_id='None', track_type='General'>
- <Track track_id='1', track_type='Text'>
- """
- if not hasattr(self, "_tracks"):
- self._tracks = []
- if len(self._tracks) == 0:
- self._populate_tracks()
- return self._tracks
+ if text:
+ return output
+ else:
+ return cls(output, encoding_errors)
def to_data(self):
"""
Returns a dict representation of the object's :py:class:`Tracks
<Track>`.
@@ -258,7 +331,7 @@
return data
def to_json(self):
"""
- Returns a json representation of the object's :py:class:`Tracks
<Track>`.
+ Returns a JSON representation of the object's :py:class:`Tracks
<Track>`.
:rtype: str
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/pymediainfo.egg-info/PKG-INFO
new/pymediainfo-4.1/pymediainfo.egg-info/PKG-INFO
--- old/pymediainfo-2.2.0/pymediainfo.egg-info/PKG-INFO 2017-11-08
00:10:33.000000000 +0100
+++ new/pymediainfo-4.1/pymediainfo.egg-info/PKG-INFO 2019-09-18
14:58:02.000000000 +0200
@@ -1,19 +1,46 @@
Metadata-Version: 1.1
Name: pymediainfo
-Version: 2.2.0
+Version: 4.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
-Description: UNKNOWN
+Description: pymediainfo
+ -----------
+
+ .. image:: https://img.shields.io/pypi/v/pymediainfo.svg
+ :target: https://pypi.org/project/pymediainfo
+
+ .. image:: https://img.shields.io/pypi/pyversions/pymediainfo.svg
+ :target: https://pypi.org/project/pymediainfo
+
+ .. image:: https://repology.org/badge/tiny-repos/python:pymediainfo.svg
+ :target: https://repology.org/metapackage/python:pymediainfo
+
+ .. image:: https://img.shields.io/pypi/implementation/pymediainfo.svg
+ :target: https://pypi.org/project/pymediainfo
+
+ .. image::
https://api.travis-ci.org/sbraz/pymediainfo.svg?branch=master
+ :target: https://travis-ci.org/sbraz/pymediainfo
+
+ .. image::
https://ci.appveyor.com/api/projects/status/g15a2daem1oub57n/branch/master?svg=true
+ :target: https://ci.appveyor.com/project/sbraz/pymediainfo
+
+
+ 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.
+
+ See https://pymediainfo.readthedocs.io/ for more information.
+
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
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-2.2.0/pymediainfo.egg-info/SOURCES.txt
new/pymediainfo-4.1/pymediainfo.egg-info/SOURCES.txt
--- old/pymediainfo-2.2.0/pymediainfo.egg-info/SOURCES.txt 2017-11-08
00:10:33.000000000 +0100
+++ new/pymediainfo-4.1/pymediainfo.egg-info/SOURCES.txt 2019-09-18
14:58:03.000000000 +0200
@@ -1,4 +1,8 @@
+AUTHORS
+LICENSE
README.rst
+appveyor.yml
+demo.py
setup.cfg
setup.py
docs/Makefile
@@ -12,10 +16,15 @@
pymediainfo.egg-info/dependency_links.txt
pymediainfo.egg-info/namespace_packages.txt
pymediainfo.egg-info/not-zip-safe
+pymediainfo.egg-info/requires.txt
pymediainfo.egg-info/top_level.txt
tests/test_pymediainfo.py
+tests/data/aac_he_v2.aac
tests/data/accentué.txt
tests/data/invalid.xml
+tests/data/issue55.flv
tests/data/sample.mkv
tests/data/sample.mp4
-tests/data/sample.xml
\ No newline at end of file
+tests/data/sample.xml
+tests/data/sample_with_cover.mp3
+tests/data/vbr_requires_parsespeed_1.mp4
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/pymediainfo.egg-info/requires.txt
new/pymediainfo-4.1/pymediainfo.egg-info/requires.txt
--- old/pymediainfo-2.2.0/pymediainfo.egg-info/requires.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/pymediainfo-4.1/pymediainfo.egg-info/requires.txt 2019-09-18
14:58:02.000000000 +0200
@@ -0,0 +1 @@
+setuptools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/setup.cfg
new/pymediainfo-4.1/setup.cfg
--- old/pymediainfo-2.2.0/setup.cfg 2017-11-08 00:10:33.000000000 +0100
+++ new/pymediainfo-4.1/setup.cfg 2019-09-18 14:58:03.000000000 +0200
@@ -12,6 +12,12 @@
[aliases]
test = pytest
+[tool:pytest]
+addopts = -vv -r a
+
+[bdist_wheel]
+universal = 1
+
[egg_info]
tag_build =
tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/setup.py
new/pymediainfo-4.1/setup.py
--- old/pymediainfo-2.2.0/setup.py 2017-11-08 00:10:07.000000000 +0100
+++ new/pymediainfo-4.1/setup.py 2019-09-18 14:57:58.000000000 +0200
@@ -1,25 +1,62 @@
+#!/usr/bin/env python
+import os
from setuptools import setup, find_packages
+with open("README.rst") as f:
+ long_description = f.read()
+
+data_files = []
+bin_files = []
+cmdclass = {}
+
+bin_license = 'docs/License.html'
+if os.path.exists(bin_license):
+ data_files.append(('docs', [bin_license]))
+ bin_files.extend(['MediaInfo.dll', 'libmediainfo.*'])
+ try:
+ from wheel.bdist_wheel import bdist_wheel
+
+ class platform_bdist_wheel(bdist_wheel):
+ def finalize_options(self):
+ bdist_wheel.finalize_options(self)
+ # Force the wheel to be marked as platform-specific
+ self.root_is_pure = False
+ def get_tag(self):
+ python, abi, plat = bdist_wheel.get_tag(self)
+ # The python code works for any Python version,
+ # not just the one we are running to build the wheel
+ return 'py2.py3', 'none', plat
+
+ cmdclass['bdist_wheel'] = platform_bdist_wheel
+ except ImportError:
+ pass
+
setup(
name='pymediainfo',
- version='2.2.0',
author='Louis Sautier',
author_email='[email protected]',
url='https://github.com/sbraz/pymediainfo',
description="""A Python wrapper for the mediainfo library.""",
+ long_description=long_description,
packages=find_packages(),
namespace_packages=[],
include_package_data=True,
zip_safe=False,
license='MIT',
+ data_files=data_files,
+ use_scm_version=True,
+ setup_requires=["setuptools_scm"],
+ install_requires=["setuptools"],
tests_require=["pytest", "pytest-runner"],
+ package_data={'pymediainfo': bin_files},
+ cmdclass=cmdclass,
classifiers=[
"Development Status :: 5 - Production/Stable",
- "Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Operating System :: POSIX :: Linux",
Binary files old/pymediainfo-2.2.0/tests/data/aac_he_v2.aac and
new/pymediainfo-4.1/tests/data/aac_he_v2.aac differ
Binary files old/pymediainfo-2.2.0/tests/data/issue55.flv and
new/pymediainfo-4.1/tests/data/issue55.flv differ
Binary files old/pymediainfo-2.2.0/tests/data/sample.mkv and
new/pymediainfo-4.1/tests/data/sample.mkv differ
Binary files old/pymediainfo-2.2.0/tests/data/sample_with_cover.mp3 and
new/pymediainfo-4.1/tests/data/sample_with_cover.mp3 differ
Binary files old/pymediainfo-2.2.0/tests/data/vbr_requires_parsespeed_1.mp4 and
new/pymediainfo-4.1/tests/data/vbr_requires_parsespeed_1.mp4 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pymediainfo-2.2.0/tests/test_pymediainfo.py
new/pymediainfo-4.1/tests/test_pymediainfo.py
--- old/pymediainfo-2.2.0/tests/test_pymediainfo.py 2017-11-08
00:10:07.000000000 +0100
+++ new/pymediainfo-4.1/tests/test_pymediainfo.py 2019-09-18
14:57:58.000000000 +0200
@@ -3,11 +3,20 @@
import os
import sys
import unittest
+import xml
+import pickle
import pytest
from pymediainfo import MediaInfo
+os_is_nt = os.name in ("nt", "dos", "os2", "ce")
+
+if sys.version_info < (3, 3):
+ FileNotFoundError = IOError
+if sys.version_info < (3, 2):
+ unittest.TestCase.assertRegex = unittest.TestCase.assertRegexpMatches
+
data_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
class MediaInfoTest(unittest.TestCase):
@@ -46,12 +55,12 @@
with open(os.path.join(data_dir, 'invalid.xml'), 'r') as f:
self.xml_data = f.read()
def test_parse_invalid_xml(self):
- mi = MediaInfo(MediaInfo._parse_xml_data_into_dom(self.xml_data))
- self.assertEqual(len(mi.tracks), 0)
+ self.assertRaises(xml.etree.ElementTree.ParseError, MediaInfo,
self.xml_data)
class MediaInfoLibraryTest(unittest.TestCase):
def setUp(self):
self.mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"))
+ self.non_full_mi = MediaInfo.parse(os.path.join(data_dir,
"sample.mp4"), full=False)
def test_can_parse_true(self):
self.assertTrue(MediaInfo.can_parse())
def test_track_count(self):
@@ -60,10 +69,13 @@
self.assertEqual(self.mi.tracks[1].track_type, "Video")
self.assertEqual(self.mi.tracks[2].track_type, "Audio")
def test_track_details(self):
- self.assertEqual(self.mi.tracks[1].codec, "AVC")
- self.assertEqual(self.mi.tracks[2].codec, "AAC LC")
+ self.assertEqual(self.mi.tracks[1].format, "AVC")
+ self.assertEqual(self.mi.tracks[2].format, "AAC")
self.assertEqual(self.mi.tracks[1].duration, 958)
self.assertEqual(self.mi.tracks[2].duration, 980)
+ def test_full_option(self):
+ self.assertEqual(self.mi.tracks[0].footersize, "59")
+ self.assertEqual(self.non_full_mi.tracks[0].footersize, None)
class MediaInfoUnicodeXMLTest(unittest.TestCase):
def setUp(self):
@@ -90,8 +102,113 @@
class MediaInfoPathlibTest(unittest.TestCase):
def setUp(self):
- pathlib = pytest.importorskip("pathlib")
- self.path = pathlib.Path(data_dir) / "sample.mp4"
+ self.pathlib = pytest.importorskip("pathlib")
def test_parse_pathlib_path(self):
- mi = MediaInfo.parse(self.path)
+ path = self.pathlib.Path(data_dir) / "sample.mp4"
+ mi = MediaInfo.parse(path)
self.assertEqual(len(mi.tracks), 3)
+ @pytest.mark.skipif(os_is_nt, reason="Windows paths are URLs")
+ def test_parse_non_existent_path_pathlib(self):
+ path = self.pathlib.Path(data_dir) / "this file does not exist"
+ self.assertRaises(FileNotFoundError, MediaInfo.parse, path)
+
+class MediaInfoTestParseNonExistentFile(unittest.TestCase):
+ @pytest.mark.skipif(os_is_nt, reason="Windows paths are URLs")
+ def test_parse_non_existent_path(self):
+ path = os.path.join(data_dir, "this file does not exist")
+ self.assertRaises(FileNotFoundError, MediaInfo.parse, path)
+
+class MediaInfoCoverDataTest(unittest.TestCase):
+ def setUp(self):
+ self.cover_mi = MediaInfo.parse(
+ os.path.join(data_dir, "sample_with_cover.mp3"),
+ cover_data=True
+ )
+ self.no_cover_mi = MediaInfo.parse(
+ os.path.join(data_dir, "sample_with_cover.mp3")
+ )
+ def test_parse_cover_data(self):
+ self.assertEqual(
+ self.cover_mi.tracks[0].cover_data,
+
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACXBIWXMAAAAAAA"
+
"AAAQCEeRdzAAAADUlEQVR4nGP4x8DwHwAE/AH+QSRCQgAAAABJRU5ErkJggg=="
+ )
+ def test_parse_no_cover_data(self):
+ _, lib_version_str, lib_version = MediaInfo._get_library()
+ if lib_version < (18, 3):
+ pytest.skip("Cover_Data option 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)
+
+class MediaInfoTrackParsingTest(unittest.TestCase):
+ def test_track_parsing(self):
+ mi = MediaInfo.parse(os.path.join(data_dir, "issue55.flv"))
+ self.assertEqual(len(mi.tracks), 2)
+
+class MediaInfoRuntimeErrorTest(unittest.TestCase):
+ def test_parse_invalid_url(self):
+ # This is the easiest way to cause a parsing error
+ # since non-existent files return a different exception
+ self.assertRaises(RuntimeError, MediaInfo.parse,
+ "unsupportedscheme://")
+
+class MediaInfoSlowParseTest(unittest.TestCase):
+ def setUp(self):
+ self.mi = MediaInfo.parse(
+ os.path.join(data_dir, "vbr_requires_parsespeed_1.mp4"),
+ parse_speed=1
+ )
+ def test_slow_parse_speed(self):
+ self.assertEqual(self.mi.tracks[2].stream_size, "3353 / 45")
+
+class MediaInfoEqTest(unittest.TestCase):
+ def setUp(self):
+ self.mp3_mi = MediaInfo.parse(os.path.join(data_dir,
"sample_with_cover.mp3"))
+ self.mp3_other_mi = MediaInfo.parse(os.path.join(data_dir,
"sample_with_cover.mp3"))
+ self.mp4_mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"))
+ def test_eq(self):
+ self.assertEqual(self.mp3_mi.tracks[0], self.mp3_other_mi.tracks[0])
+ self.assertEqual(self.mp3_mi, self.mp3_other_mi)
+ self.assertNotEqual(self.mp3_mi.tracks[0], self.mp4_mi.tracks[0])
+ self.assertNotEqual(self.mp3_mi, self.mp4_mi)
+ def test_pickle_unpickle(self):
+ pickled_track = pickle.dumps(self.mp4_mi.tracks[0])
+ self.assertEqual(self.mp4_mi.tracks[0], pickle.loads(pickled_track))
+ pickled_mi = pickle.dumps(self.mp4_mi)
+ self.assertEqual(self.mp4_mi, pickle.loads(pickled_mi))
+
+class MediaInfoTextOutputTest(unittest.TestCase):
+ def setUp(self):
+ self.mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"),
text=True)
+ def test_text_output(self):
+ self.assertRegex(self.mi, r"Stream size\s+: 373836\b")
+
+class MediaInfoLegacyStreamDisplayTest(unittest.TestCase):
+ def setUp(self):
+ self.mi = MediaInfo.parse(os.path.join(data_dir, "aac_he_v2.aac"))
+ self.legacy_mi = MediaInfo.parse(os.path.join(data_dir,
"aac_he_v2.aac"), legacy_stream_display=True)
+ def test_legacy_stream_display(self):
+ self.assertEqual(self.mi.tracks[1].channel_s, 2)
+ self.assertEqual(self.legacy_mi.tracks[1].channel_s, "2 / 1 / 1")
+
+class MediaInfoOptionsTest(unittest.TestCase):
+ def setUp(self):
+ _, lib_version_str, lib_version = MediaInfo._get_library()
+ if lib_version < (19, 9):
+ pytest.skip("Reset option not supported by this library version "
+ "(v{} detected, v19.09 required)".format(lib_version_str)
+ )
+ self.raw_language_mi = MediaInfo.parse(
+ os.path.join(data_dir, "sample.mkv"),
+ mediainfo_options={"Language": "raw"},
+ )
+ # Parsing the file without the custom options afterwards
+ # allows us to check that the "Reset" option worked
+ # https://github.com/MediaArea/MediaInfoLib/issues/1128
+ self.normal_mi = MediaInfo.parse(
+ os.path.join(data_dir, "sample.mkv"),
+ )
+ 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")