4
\$\begingroup\$

I made the following wrapper for the mediainfo command line. I did this mainly because mediainfo gives me more information than os.stat, specifically it gives me the Encoded date for .wma files, while the dates in os.stat don't represent the time the files were made, but rather the date the files were compressed (they were delivered to me in a compressed folder).

But is it actually a good idea to use a class for this? I needed to do this in bulk, for 20.000 files. Also it feels inefficient to let mediainfo format the information first and then read it again, but I'm not sure how to do that otherwise.

from pathlib import Path
from subprocess import Popen, PIPE

class MediaInfo:
    """Wrapper class for the mediainfo command line tool."""

    # Define the path to the `mediainfo` command line tool.
    mediainfo = "/usr/bin/mediainfo"

    def __init__(self, filename):
        self.file = Path(filename).resolve()
        self.info = self.readinfo()

        if not self.file.is_file():
            raise OSError(f"File not found: {file}")


    def __str__(self):
        """String representation (the same as what mediainfo shows)"""
        if hasattr(self, "info") and self.info is not None:
            return self.info.strip()

        return self.readinfo().strip()


    def infofield(self, field, postread=None):
        """Find a given field and return its value.

        If the `field` is not in the mediainfo metadata, return None.
        `postread` can be a callable to, for example, cast the returned type.
        """
        val = None
        for line in self.info.split("\n"):
            if not line.strip() or not ":" in line:
                continue
            key, val = line.strip().split(" : ")
            key = key.strip()
            val = val.strip()
            if key == field:
                break

        if postread is None:
            return val
        return postread(val)


    def readinfo(self):
        # Start the command line process
        proc = Popen([self.mediainfo, str(self.file)], stdout=PIPE, stderr=PIPE)
        # Catch the output
        stdout, stderr = proc.communicate()

        if stderr:
            self.info = stderr.decode()
            raise MediaInfoException("Error in MediaInfo process", self.info)

        self.info = stdout.decode()
        return self.info


class MediaInfoException(Exception):
    """Custom exception for MediaInfo."""
    pass
\$\endgroup\$
1
\$\begingroup\$

Using a class might be too much. It all depends of how you want to use your script.

But I think you should take a look at mediainfo help. Issuing:

mediainfo --Inform="Audio;%Encoded_Date%" Filename

outputs only the encoded date value of your audio file, or an empty line if not applicable. Maybe you won't need your script anymore.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.