diff --git a/docs/index.rst b/docs/index.rst index dc67f70..3b23acf 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -73,7 +73,7 @@ Reporting Issues / Bugs ======================= Please use the issue tracker in GitHub at https://github.com/sbraz/pymediainfo/issues -to report all feature requests or bug reports. Thanks! +to report all feature requests or bug reports. Thanks! Indices and tables diff --git a/docs/pymediainfo.rst b/docs/pymediainfo.rst index 6ec4bbc..4974410 100644 --- a/docs/pymediainfo.rst +++ b/docs/pymediainfo.rst @@ -7,4 +7,3 @@ Module contents .. automodule:: pymediainfo :members: :undoc-members: - :show-inheritance: diff --git a/pymediainfo/__init__.py b/pymediainfo/__init__.py index 6cb862d..3037d83 100644 --- a/pymediainfo/__init__.py +++ b/pymediainfo/__init__.py @@ -20,6 +20,30 @@ __version__ = get_distribution("pymediainfo").version class Track(object): + """ + An object associated with a media file track. + + Each :class:`Track` attribute corresponds to attributes parsed from MediaInfo's output. + All attributes are lower case. Attributes that are present several times such as Duration + yield a second attribute starting with `other_` which is a list of all alternative attribute values. + + When a non-existing attribute is accessed, `None` is returned. + + Example: + + >>> t = mi.tracks[0] + >>> t + + >>> t.duration + 3000 + >>> t.to_data()["other_duration"] + ['3 s 0 ms', '3 s 0 ms', '3 s 0 ms', + '00:00:03.000', '00:00:03.000'] + >>> type(t.non_existing) + NoneType + + All available attributes can be obtained by calling :func:`to_data`. + """ def __getattribute__(self, name): try: return object.__getattribute__(self, name) @@ -59,6 +83,19 @@ def __init__(self, xml_dom_fragment): def __repr__(self): return("".format(self.track_id, self.track_type)) def to_data(self): + """ + Returns a dict representation of the track attributes. + + Example: + + >>> sorted(track.to_data().keys())[:3] + ['codec', 'codec_extensions_usually_used', 'codec_url'] + >>> t.to_data()["file_size"] + 5988 + + + :rtype: dict + """ data = {} for k, v in self.__dict__.items(): if k != 'xml_dom_fragment': @@ -67,6 +104,26 @@ def to_data(self): class MediaInfo(object): + """ + An object containing information about a media file. + + + :class:`MediaInfo` objects can be created by directly calling code from + libmediainfo (in this case, the library must be present on the system): + + >>> 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. + + 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) @@ -92,6 +149,11 @@ def _get_library(library_file=None): return CDLL("libmediainfo.so.0") @classmethod def can_parse(cls, library_file=None): + """ + Checks whether media files can be analyzed using libmediainfo. + + :rtype: bool + """ try: cls._get_library(library_file) return True @@ -101,10 +163,15 @@ def can_parse(cls, library_file=None): def parse(cls, filename, library_file=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") - :param filename: path to the media file. - :param str library_file: path to the libmediainfo library, this should only be used if the library cannot auto-detected. + :param filename: path to the media file which will be analyzed. + :param str library_file: path to the libmediainfo library, this should only be used if the library cannot be auto-detected. :type filename: str or pathlib.Path + :rtype: MediaInfo """ lib = cls._get_library(library_file) if pathlib is not None and isinstance(filename, pathlib.PurePath): @@ -163,15 +230,36 @@ def _populate_tracks(self): 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) + + + """ if not hasattr(self, "_tracks"): self._tracks = [] if len(self._tracks) == 0: self._populate_tracks() return self._tracks def to_data(self): + """ + Returns a dict representation of the object's :py:class:`Tracks `. + + :rtype: dict + """ data = {'tracks': []} for track in self.tracks: data['tracks'].append(track.to_data()) return data def to_json(self): + """ + Returns a json representation of the object's :py:class:`Tracks `. + + :rtype: str + """ return json.dumps(self.to_data())