sbraz/pymediainfo

Get mediainfo library version

Opened this issue · 9 comments

I couldn't find anything related in the docs. I would like to print out information whether a wheel is used or a system binary with subprocess (on Linux) and the version of the mediainfo wheel/binary.

sbraz commented

Hi,
You could rely on _get_library which returns a CDLL/WinDLL object, a pointer to an internal handle, the version as a string and as a tuple of integers.

def _get_library(

In [3]: pymediainfo.MediaInfo._get_library()
Out[3]: 
(<CDLL 'libmediainfo.so.0', handle 561a3c818d20 at 0x7ff59b456b50>,
 94670684320096,
 '23.04',
 (23, 4))

Maybe I could make this method public or create a get_library_version function that would returned the unparsed version (MediaInfoLib - v23.04), what do you think?

sbraz commented

system binary with subprocess

By the way, this library hasn't subprocess since 2016 (a16e5c2).

Maybe I could make this method public or create a get_library_version function that would returned the unparsed version (MediaInfoLib - v23.04), what do you think?
That would be pretty cool. Maybe it could be get_library_info() which would return something like:

{
  "DLL": "libmediainfo.so.0",
  "version": [23, 10],
  "version_string": "23.10",
  "type": "wheel" # "wheel" / "system"
}

"type" would be useful to reliably report if mediainfo is from the system or from wheel. (The dll name could be used now, but once Linux wheel is added it would break.)

sbraz commented

I don't think I can return info about whether a wheel or system library was used, only the path would tell you that and even then I'm not 100% sure. I don't have a system where I can test the wheels right now, what does _get_library return on one of these?

In [24]: MediaInfo._get_library()
Out[24]:
(<CDLL 'libmediainfo.so.0', handle 7fffc8ad8f40 at 0x7fef593a51e0>,
 140736560434112,
 '23.10',
 (23, 10))

It returns this on WSL

sbraz commented

There isn't a Linux wheel yet so that would probably be the system library. Can you try on a normal Windows system?

MediaInfo._get_library()
(<WinDLL 'C:\Users\roland\AppData\Local\Programs\Python\Python311\Lib\site-packages\pymediainfo\MediaInfo.dll', handle 7ff8cc570000 at 0x27810266410>, 2714694968896, '23.10', (23, 10))

Would it be possible to test if the dll is next to the main file itself?

By the way, this library hasn't subprocess since 2016

And what happens if a distro has mediainfo in the system PATH variable, but it's not installed through a package manager, but a static build? Would it still work?

sbraz commented

Would it be possible to test if the dll is next to the main file itself?

The DLL can be passed manually via the library_file but the autodetection only checks the script folder. Maybe ctypes also loads it if it exists in the current working directory, I'm not sure.

Here's the autodetection code that runs when not library file is forced:

def _get_library_paths(os_is_nt: bool) -> Tuple[str]:
if os_is_nt:
library_paths = ("MediaInfo.dll",)
elif sys.platform == "darwin":
library_paths = ("libmediainfo.0.dylib", "libmediainfo.dylib")
else:
library_paths = ("libmediainfo.so.0",)
script_dir = os.path.dirname(__file__)
# Look for the library file in the script folder
for library in library_paths:
absolute_library_path = os.path.join(script_dir, library)
if os.path.isfile(absolute_library_path):
# If we find it, don't try any other filename
library_paths = (absolute_library_path,)
break
return library_paths

And what happens if a distro has mediainfo in the system PATH variable, but it's not installed through a package manager, but a static build? Would it still work?

This package is a wrapper around the library, not the binary. If you only have a static binary, you can generate the XML output manually (mediainfo --Full --Output=OLDXML or --output=XML for v17.10 or older) and pass it to the MediaInfo class, the doc contains an example:

Alternatively, objects may be created from MediaInfo's XML output.
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())

I guess making the method public is enough then, if detecting of wheel usage is not possible.