o
    ,˜ŽjÌT  ã                   @   sâ   d Z ddlZddlZddlZddlZddlZddlZddlZddlm	  m
Z ddlmZmZmZmZmZmZ zddlmZ W n eyL   ddlZY nw ze d¡ZW n ejy`   dZY nw G dd„ dƒZG d	d
„ d
ƒZdS )z8
This module is a wrapper around the MediaInfo library.
é    N)ÚAnyÚDictÚListÚOptionalÚTupleÚUnion)ÚmetadataÚpymediainfoÚ c                   @   s^   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
ej	fdd„Z
dd„ Zdeeef fdd„ZdS )ÚTracka  
    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
    <Track track_id='None', track_type='General'>
    >>> t.duration
    3000
    >>> t.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`.
    c                 C   ó   | j |j kS ©N©Ú__dict__©ÚselfÚother© r   úQ/var/www/kodo/Anonymous/send/lib/python3.10/site-packages/pymediainfo/__init__.pyÚ__eq__5   ó   zTrack.__eq__c                 C   s$   zt  | |¡W S  ty   Y d S w r   )ÚobjectÚ__getattribute__ÚAttributeError)r   Únamer   r   r   r   8   s   þzTrack.__getattribute__c                 C   ó   | j S r   r   ©r   r   r   r   Ú__getstate__?   s   zTrack.__getstate__c                 C   s
   || _ d S r   r   )r   Ústater   r   r   Ú__setstate__B   s   
zTrack.__setstate__Úxml_dom_fragmentc                 C   s2  |j d | _g }|D ]F}|j ¡  ¡  d¡}|dkrd}|j}t| |ƒd u r-t| ||ƒ q
d|› �}| ||f¡ t| |ƒd u rHt| ||gƒ q
t| |ƒ |¡ q
|D ]C\}}zt| |t	t| |ƒƒƒ W qS t
y–   t| |ƒD ]#}	zt| |ƒ}
t| |t	|	ƒƒ t| |ƒ |
¡ W  n	 t
y“   Y qpw Y qSw d S )NÚtypeÚ_ÚidÚtrack_idÚother_)ÚattribÚ
track_typeÚtagÚlowerÚstripÚtextÚgetattrÚsetattrÚappendÚintÚ
ValueError)r   r    Úrepeated_attributesÚelemÚ	node_nameÚ
node_valueÚother_node_nameÚprimary_keyÚ	other_keyÚother_valueÚcurrentr   r   r   Ú__init__E   s<   

ÿ€õúzTrack.__init__c                 C   s   d  | j| j¡S )Nz&<Track track_id='{}', track_type='{}'>)Úformatr$   r'   r   r   r   r   Ú__repr__k   s   zTrack.__repr__Úreturnc                 C   r   )a  
        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
        r   r   r   r   r   Úto_datan   s   zTrack.to_dataN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   ÚETÚElementr:   r<   r   Ústrr   r>   r   r   r   r   r      s    &r   c                   @   s  e Zd ZdZdd„ Zd<dedefdd„Zd	ed
ee fdd„Z	e
d
ee fdd„ƒZe
d
ee fdd„ƒZe
d
ee fdd„ƒZe
d
ee fdd„ƒZe
d
ee fdd„ƒZe
d
ee fdd„ƒZe
d
ee fdd„ƒZeded
efdd„ƒZeded
efdd „ƒZed!ed
eed"f fd#d$„ƒZe	%d=d&ee d
eeeeeed"f f fd'd(„ƒZed=d&ee d
efd)d*„ƒZe	%	+		,	-	+	%	%	.d>ded&ee d/eded0ed1ed2ed3eeeef  d4ee d5ee d
e ed f fd6d7„ƒZ!d
eeef fd8d9„Z"d
efd:d;„Z#d%S )?Ú	MediaInfoaË  
    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.
    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.
    :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:

        >>> 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'>
    c                 C   r   r   ©Útracksr   r   r   r   r       r   zMediaInfo.__eq__ÚstrictÚxmlÚencoding_errorsc                 C   sP   t  | d|¡¡}g | _|jdkrd}nd}| |¡D ]
}| j t|ƒ¡ qd S )Nzutf-8ÚFileÚtrackz
File/track)rC   Ú
fromstringÚencoderH   r(   Úiterfindr.   r   )r   rJ   rK   Úxml_domÚxpathÚ	xml_trackr   r   r   r:   £   s   
ÿzMediaInfo.__init__r'   r=   c                    s   ‡ fdd„| j D ƒS )Nc                    s   g | ]	}|j ˆ kr|‘qS r   ©r'   )Ú.0rM   rT   r   r   Ú
<listcomp>±   s    z%MediaInfo._tracks.<locals>.<listcomp>rG   )r   r'   r   rT   r   Ú_tracks°   s   zMediaInfo._tracksc                 C   ó
   |   d¡S )zm
        :return: All :class:`Track`\s of type ``General``.
        :rtype: list of :class:`Track`\s
        ÚGeneral©rW   r   r   r   r   Úgeneral_tracks³   ó   
zMediaInfo.general_tracksc                 C   rX   )zk
        :return: All :class:`Track`\s of type ``Video``.
        :rtype: list of :class:`Track`\s
        ÚVideorZ   r   r   r   r   Úvideo_tracks»   r\   zMediaInfo.video_tracksc                 C   rX   )zk
        :return: All :class:`Track`\s of type ``Audio``.
        :rtype: list of :class:`Track`\s
        ÚAudiorZ   r   r   r   r   Úaudio_tracksÃ   r\   zMediaInfo.audio_tracksc                 C   rX   )zj
        :return: All :class:`Track`\s of type ``Text``.
        :rtype: list of :class:`Track`\s
        ÚTextrZ   r   r   r   r   Útext_tracksË   r\   zMediaInfo.text_tracksc                 C   rX   )zk
        :return: All :class:`Track`\s of type ``Other``.
        :rtype: list of :class:`Track`\s
        ÚOtherrZ   r   r   r   r   Úother_tracksÓ   r\   zMediaInfo.other_tracksc                 C   rX   )zk
        :return: All :class:`Track`\s of type ``Image``.
        :rtype: list of :class:`Track`\s
        ÚImagerZ   r   r   r   r   Úimage_tracksÛ   r\   zMediaInfo.image_tracksc                 C   rX   )zj
        :return: All :class:`Track`\s of type ``Menu``.
        :rtype: list of :class:`Track`\s
        ÚMenurZ   r   r   r   r   Úmenu_tracksã   r\   zMediaInfo.menu_tracksÚfilenamec                 C   s@   t tdƒrt| tjƒrt | ¡S td urt| tjƒrt| ƒS | S )NÚPathLike)ÚhasattrÚosÚ
isinstancerj   ÚfspathÚpathlibÚPurePathrE   )ri   r   r   r   Ú_normalize_filenameë   s
   
zMediaInfo._normalize_filenameÚlibc                 C   s  t j|j_g |j_t j|j_t jt jt jg|j_t j|j_t jt jg|j_t j|j_t jt jg|j	_t j|j	_t jt j
t j
g|j_t j|j_t jt jt jg|j_t j|j_t jg|j_t j
|j_t jg|j_t j|j_t jg|j_d |j_t jg|j_d |j_d S r   )ÚctypesÚ	c_wchar_pÚMediaInfo_InformÚrestypeÚMediaInfo_NewÚargtypesÚc_void_pÚMediaInfo_OptionÚc_size_tÚMediaInfo_OpenÚc_uint64ÚMediaInfo_Open_Buffer_InitÚc_char_pÚMediaInfo_Open_Buffer_ContinueÚ'MediaInfo_Open_Buffer_Continue_GoTo_GetÚMediaInfo_Open_Buffer_FinalizeÚMediaInfo_DeleteÚMediaInfo_Close)Úclsrr   r   r   r   Ú_define_library_prototypesó   s<   

ý


ý
ý


z$MediaInfo._define_library_prototypesÚos_is_nt.c                 C   s^   | rd}n
t jdkrd}nd}tj t¡}|D ]}tj ||¡}tj |¡r,|f} |S q|S )N)zMediaInfo.dllÚdarwin)zlibmediainfo.0.dylibzlibmediainfo.dylib)zlibmediainfo.so.0)ÚsysÚplatformrl   ÚpathÚdirnameÚ__file__ÚjoinÚisfile)r‡   Úlibrary_pathsÚ
script_dirÚlibraryÚabsolute_library_pathr   r   r   Ú_get_library_paths  s   
üzMediaInfo._get_library_pathsNÚlibrary_filec                 C   s  t jdv }|rtj}ntj}|d u r|  |¡}n|f}g }|D ]V}z;||ƒ}|  |¡ | ¡ }| |dd¡}	t	 
d|	¡}
|
rP|
 d¡}tdd„ | d¡D ƒƒ}ntd	ƒ‚||||fW   S  tyu } z| t|ƒ¡ W Y d }~qd }~ww td
 d |¡d |¡¡ƒ‚)N)ÚntÚdosÚos2ÚceÚInfo_Versionr
   z^MediaInfoLib - v(\S+)é   c                 s   s   � | ]}t |ƒV  qd S r   )r/   ©rU   r"   r   r   r   Ú	<genexpr>D  s   € z)MediaInfo._get_library.<locals>.<genexpr>Ú.z#Could not determine library versionz#Failed to load library from {} - {}z, )rl   r   rs   ÚWinDLLÚCDLLr”   r†   rw   rz   ÚreÚsearchÚgroupÚtupleÚsplitÚRuntimeErrorÚOSErrorr.   rE   r;   rŽ   )r…   r•   r‡   Úlib_typer�   Ú
exceptionsÚlibrary_pathrr   ÚhandleÚversionÚmatchÚlib_version_strÚlib_versionÚexcr   r   r   Ú_get_library*  s:   


€ÿÿÿzMediaInfo._get_libraryc                 C   sF   z|   |¡dd… \}}| |¡ | |¡ W dS  ty"   Y dS w )zö
        Checks whether media files can be analyzed using libmediainfo.

        :param str library_file: path to the libmediainfo library, this should only be used if
            the library cannot be auto-detected.
        :rtype: bool
        Né   TF)r±   r„   rƒ   Ú	Exception)r…   r•   rr   r«   r   r   r   Ú	can_parseP  s   	

ÿzMediaInfo.can_parseFç      à?Té   Ú
cover_dataÚparse_speedÚfullÚlegacy_stream_displayÚmediainfo_optionsÚoutputÚbuffer_sizec                 C   sz  |   |¡\}}}}|dkrd}nd}|dkr!| |d|rdnd¡ | |dd	¡ | |d
|	du r2|n|	¡ | |d|r=dnd¡ | |dt|ƒ¡ | |d|rQdnd¡ |duru|dk ret d |¡t¡ | ¡ D ]\}}| |||¡ qiz| dd¡ | 	¡ }| d¡ W n t
y‘   d}Y nw |durádt|ddƒvr¢tdƒ‚| ||d¡ 	 | |
¡}|rÙ| ||t|ƒ¡d@ r½n| |¡}|t d¡jkrØ| |¡ | ||| 	¡ ¡ nnqª| |¡ n/|  |¡}| ||¡dk�r| |¡ | |¡ d|v�r	tj |¡�s	t|ƒ‚td |¡ƒ‚| |d¡}|du�r'|dk�r'| |dd¡ | |¡ | |¡ |	du �r;| ||ƒS |S )u¸  
        Analyze a media file using libmediainfo.

        .. 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 or file-like object 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 full: display additional tags, including computer-readable values
            for sizes and durations, corresponds to the CLI's ``--Full``/``-f`` parameter.
        :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"}``.
            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``)
        :param int buffer_size: size of the buffer used to read the file, in bytes. This is only
            used when `filename` is a file-like object.
        :type filename: str or pathlib.Path or os.PathLike or file-like object.
        :rtype: str if `output` is set.
        :rtype: :class:`MediaInfo` otherwise.
        :raises FileNotFoundError: if passed a non-existent file.
        :raises ValueError: if passed a file-like object opened in text mode.
        :raises OSError: if the library file could not be loaded.
        :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',  â€¦ }


        )é   é
   ÚOLDXMLÚXML)é   é   Ú
Cover_DataÚbase64r
   ÚCharSetzUTF-8ÚInformNÚCompleteÚ1Ú
ParseSpeedÚLegacyStreamDisplay)é   é	   zðThis version of MediaInfo (v{}) 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/1128r   r²   ÚbÚmodez$File should be opened in binary modeTé   éÿÿÿÿz://z3An error occured while opening {} with libmediainfoÚReset) r±   rz   rE   ÚwarningsÚwarnr;   ÚRuntimeWarningÚitemsÚseekÚtellr   r,   r0   r~   Úreadr€   Úlenr�   rs   r}   Úvaluer‚   rq   r|   r„   rƒ   rl   r‹   ÚexistsÚFileNotFoundErrorr¦   ru   )r…   ri   r•   r·   rK   r¸   r¹   rº   r»   r¼   r½   rr   r«   r®   r¯   Ú
xml_optionÚoption_nameÚoption_valueÚ	file_sizeÚbufferr×   Úinfor   r   r   Úparsea  sz   Rûÿ


€ñ


ÿ



zMediaInfo.parsec                 C   s   ddd„ | j D ƒiS )zq
        Returns a dict representation of the object's :py:class:`Tracks <Track>`.

        :rtype: dict
        rH   c                 S   s   g | ]}|  ¡ ‘qS r   )r>   rœ   r   r   r   rV     s    z%MediaInfo.to_data.<locals>.<listcomp>rG   r   r   r   r   r>     s   zMediaInfo.to_datac                 C   s   t  |  ¡ ¡S )zp
        Returns a JSON representation of the object's :py:class:`Tracks <Track>`.

        :rtype: str
        )ÚjsonÚdumpsr>   r   r   r   r   Úto_json  s   zMediaInfo.to_json)rI   r   )	NFrI   rµ   TFNNr¶   )$r?   r@   rA   rB   r   rE   r:   r   r   rW   Úpropertyr[   r^   r`   rb   rd   rf   rh   Ústaticmethodr   rq   Úclassmethodr†   Úboolr   r”   r   r/   r±   r´   Úfloatr   r   rä   r>   rç   r   r   r   r   rF      sŒ     #þþý%óüûúùø	÷
öõôó
ò %rF   )rB   rs   rå   rl   ro   r¡   r‰   rÓ   Úxml.etree.ElementTreeÚetreeÚElementTreerC   Útypingr   r   r   r   r   r   Ú	importlibr   ÚImportErrorÚimportlib_metadatar¬   Ú__version__ÚPackageNotFoundErrorr   rF   r   r   r   r   Ú<module>   s,    ÿÿe