§
    ‘M§j“™  ã                   óº  — 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	Z	 ddl
mZ dZdZdZdZd	Zd
ZddddehZdZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zedfd„Zd„ Zd„ Zedfd„Zd„ Z d„ Z!d„ Z"d„ Z#d „ Z$d!„ Z%d"„ Z&d#„ Z'd$„ Z(d%„ Z)d&dd'œd(„Z*d@d)„Z+d*„ Z,d+„ Z-d,„ Z.d-„ Z/d.„ Z0d/„ Z1d0„ Z2d@d1„Z3d2„ Z4d@d3„Z5d4„ Z6d5„ Z7d6„ Z8dAd7„Z9dAd8„Z:dAd9„Z;d:„ Z<d;„ Z=d<„ Z>d@d=„Z?d>„ Z@d@d?„ZAdS )Bu	  
Video Metadata Utilities

This module provides functionality to read and write JSON metadata to video files.
- MP4: Uses mutagen to store metadata in Â©cmt tag
- MKV: Uses FFmpeg to store metadata in comment/description tags and source images as attached pictures
é    N)ÚPath©Úresolve_media_binaryi È  Ú_wangp_metadata_reservedõ   Â©cmts   ©cmts
   E£‡COMMENT©ÚcommentÚCOMMENTÚdescriptionÚDESCRIPTIONs   moovs   udtaó   metas   ilst)z.mp4z.mov©ú.jpgz.jpegú.pngc                 ó$   — t          | ¦  «        p| S ©Nr   )Únames    úCC:\Users\johnn\OneDrive\Documents\AI\shared\utils\video_metadata.pyÚ_resolve_media_toolr      s   € Ý Ñ%Ô%Ð-¨Ð-ó    c                 ó^   — 	 t          | pd¦  «        dk    S # t          t          f$ r Y dS w xY w)Nr   é   F)ÚintÚ	TypeErrorÚ
ValueError)Úverbose_levels    r   Ú_is_verbose_metadata_debugr   #   sF   € ðÝ�=Ð% AÑ&Ô&¨!Ò+Ð+øÝ•zÐ"ð ð ð Øˆuˆuðøøøs   ‚ —,«,c                 óL   — t          | ¦  «        rt          d|› �¦  «         d S d S )Nz[Video Metadata] )r   Úprint)r   Úmessages     r   Ú_log_metadata_debugr!   *   s9   € Ý! -Ñ0Ô0ð -ÝÐ+ 'Ð+Ð+Ñ,Ô,Ð,Ð,Ð,ð-ð -r   c                 óÊ   — t          | t          ¦  «        r|                      dd¬¦  «        } t          | pd¦  «                             dd¦  «                             d¦  «        S )Núutf-8Úignore)ÚerrorsÚ u   ï»¿ú )Ú
isinstanceÚbytesÚdecodeÚstrÚreplaceÚrstrip)Útexts    r   Ú_normalize_metadata_textr/   /   sW   € Ý�$�ÑÔð 5Ø�{Š{˜7¨8ˆ{Ñ4Ô4ˆÝˆtˆz�r‰?Œ?×"Ò" 8¨RÑ0Ô0×7Ò7¸Ñ=Ô=Ð=r   c                 óF  — t          | ¦  «        }t          |                     ¦   «         ¦  «        dk    rd S 	 t          j        |¦  «        }n## t
          t          t          j        f$ r Y d S w xY wt          |t          ¦  «        r| 
                    t          ¦  «        rd n|S )Nr   )r/   ÚlenÚstripÚjsonÚloadsr   r   ÚJSONDecodeErrorr(   ÚdictÚgetÚ_RESERVED_METADATA_KEY)r.   ÚpayloadÚmetadatas      r   Ú_parse_metadata_textr;   5   s�   € Ý& tÑ,Ô,€GÝ
ˆ7�=Š=‰?Œ?ÑÔ˜qÒ Ð ØˆtðÝ”:˜gÑ&Ô&ˆˆøÝ•z¥4Ô#7Ð8ð ð ð Øˆtˆtðøøøå˜h­Ñ-Ô-Ðd°(·,²,Õ?UÑ2VÔ2VÐdˆ4ˆ4Ð\dÐds   ¸A ÁA-Á,A-c                 óV   — t          j        | dd¬¦  «                             d¦  «        S )NF©ú,ú:©Úensure_asciiÚ
separatorsr#   )r3   ÚdumpsÚencode)Úmetadata_dicts    r   Ú_encode_metadata_bytesrF   @   s(   € ÝŒ:�m°%ÀJÐOÑOÔO×VÒVÐW^Ñ_Ô_Ð_r   c                 óz   — t          |¦  «        }t          | ¦  «        |k    rd S | d|t          | ¦  «        z
  z  z   S )Nó    )r   r1   )Úpayload_bytesÚreserved_bytess     r   Ú_pad_metadata_bytesrK   D   sD   € Ý˜Ñ(Ô(€NÝ
ˆ=ÑÔ˜NÒ*Ð*ØˆtØ˜D NµS¸Ñ5GÔ5GÑ$GÑHÑIÐIr   c           	      óì   — t          dt          | ¦  «        ¦  «        } t          |€	t          din|¦  «        }t	          |t          | t          |¦  «        ¦  «        ¦  «                             d¦  «        S )Né€   Tr#   )Úmaxr   rF   r8   rK   r1   r*   )rJ   rE   r9   s      r   Ú"build_reserved_video_metadata_textrO   K   sf   € Ý˜�c .Ñ1Ô1Ñ2Ô2€NÝ$À}ÐG\Õ&<¸dÐ%CÐ%CÐboÑpÔp€GÝ˜w­¨N½CÀ¹L¼LÑ(IÔ(IÑJÔJ×QÒQÐRYÑZÔZÐZr   c                 ó  — t          | pd¦  «                             dd¦  «                             dd¦  «                             dd¦  «        }|                     dd¦  «                             d	d
¦  «                             dd¦  «        S )Nr&   ú\z\\úú
z\
ú=z\=ú;z\;ú#z\#)r+   r,   )Úvaluer.   s     r   Ú_escape_ffmetadata_valuerX   Q   sx   € Ýˆuˆ{˜ÑÔ×#Ò# D¨&Ñ1Ô1×9Ò9¸$ÀÑCÔC×KÒKÈDÐRXÑYÔY€DØ�<Š<˜˜UÑ#Ô#×+Ò+¨C°Ñ7Ô7×?Ò?ÀÀUÑKÔKÐKr   c           	      ó  — t          | ddd¬¦  «        5 }|                     d¦  «         |pi                      ¦   «         D ]0\  }}|€Œ|                     |› dt          |¦  «        › d�¦  «         Œ1	 d d d ¦  «         n# 1 swxY w Y   | S )NÚwr#   rS   )ÚencodingÚnewlinez;FFMETADATA1
rT   )ÚopenÚwriteÚitemsrX   )Ú	file_pathÚtagsÚhandleÚkeyrW   s        r   Ú_write_ffmetadata_filerd   V   sø   € Ý	ˆi˜ w¸Ð	=Ñ	=Ô	=ð GÀØ�ŠÐ%Ñ&Ô&Ð&Ø˜: 2×,Ò,Ñ.Ô.ð 	Gð 	G‰JˆC�Øˆ}ØØ�LŠL˜CÐEÐEÕ":¸5Ñ"AÔ"AÐEÐEÐEÑFÔFÐFÐFð	GðGð Gð Gñ Gô Gð Gð Gð Gð Gð Gð Gøøøð Gð Gð Gð Gð Ðs   ”AA>Á>BÂBc                 óB   — t          | dt          ||¦  «        i¦  «        S )Nr	   )rd   rO   )r`   rJ   rE   s      r   Úwrite_reserved_video_ffmetadatarf   `   s$   € Ý! )¨iÕ9[Ð\jÐlyÑ9zÔ9zÐ-{Ñ|Ô|Ð|r   c           
      ó�  — t          d¦  «        }t          j        |dddddd| gddd	d
d¬¦  «        }|j        dk    ri S 	 t	          j        |j        ¦  «        pi                      d¦  «        pi                      d¦  «        pi }n$# t          t          t          j
        f$ r i cY S w xY wd„ |                     ¦   «         D ¦   «         S )NÚffprobeú-vÚerrorz-show_entriesÚformat_tagsz-ofr3   Tr#   r$   F©Úcapture_outputr.   r[   r%   Úcheckr   Úformatra   c                 óR   — i | ]$\  }}|®t          |¦  «        t          |¦  «        “Œ%S r   )r+   ©Ú.0rc   rW   s      r   ú
<dictcomp>z(_read_container_tags.<locals>.<dictcomp>m   s/   € ÐUÐUÐU¡Z S¨%À5ÐCT�C�‰HŒH•c˜%‘j”jÐCTÐCTÐCTr   )r   Ú
subprocessÚrunÚ
returncoder3   r4   Ústdoutr7   r   r   r5   r_   )r`   Úffprobe_pathÚresultra   s       r   Ú_read_container_tagsrz   d   s  € Ý& yÑ1Ô1€LÝŒ^˜\¨4°¸/È=ÐZ_ÐagÐirÐsð  EIð  PTð  _fð  owð  Dð  Eñ  Eô  E€FØÔ˜AÒÐØˆ	ðÝ”˜FœMÑ*Ô*Ð0¨b×5Ò5°hÑ?Ô?ÐEÀ2×JÒJÈ6ÑRÔRÐXÐVXˆˆøÝ•z¥4Ô#7Ð8ð ð ð Øˆ	ˆ	ˆ	ðøøøàUÐU°4·:²:±<´<ÐUÑUÔUÐUs   Á AB ÂB'Â&B'c                 ó†   — t          | ¦  «        }t          |                     |j        › d|› |j        › �¦  «        ¦  «        S )NÚ_)r   r+   Ú	with_nameÚstemÚsuffix)r`   r   Úpaths      r   Ú_make_temp_output_pathr�   p   s>   € Ý�	‰?Œ?€DÝˆt�~Š~ ¤ÐBÐB¨VÐB°T´[ÐBÐBÑCÔCÑDÔDÐDr   c                 ó’  — |dz   |k    rd S t                                | ||dz   …         d¦  «        }t          | |dz   |dz   …         ¦  «        }d}|dk    r7|dz   |k    rd S t                                | |dz   |dz   …         d¦  «        }d}n|dk    r||z
  }||z   }||k     s||k    rd S ||z   |dk    rdndz   }||k    rd n|||fS )Né   é   Úbigé   é   r   r   )r   Ú
from_bytesr)   )ÚmmÚoffsetÚendÚbox_sizeÚbox_typeÚheader_sizeÚbox_endÚcontent_offsets           r   Ú_read_mp4_boxr‘   u   s  € Ø��z�CÒÐØˆtÝ�~Š~˜b ¨°©
Ð!2Ô3°UÑ;Ô;€HÝ�R˜ ™
 6¨A¡:Ð-Ô.Ñ/Ô/€HØ€KØ�1‚}€}Ø�B‰;˜ÒÐØ�4Ý—>’> " V¨a¡Z°¸±Ð%;Ô"<¸eÑDÔDˆØˆˆØ	�QŠˆØ˜‘<ˆØ�xÑ€GØ�+ÒÐ ¨3¢ ØˆtØ˜kÑ)°(¸gÒ2EÐ2E¨Q¨QÈ1ÑM€NØ! GÒ+Ð+ˆ4ˆ4°(¸NÈGÐ1TÐTr   c                 óP  — |}|dz   |k    ršt          | ||¦  «        }|€n†|\  }}}|t          k    rL|}|dz   |k    r@t          | ||¦  «        }	|	€n,|	\  }
}}|
dk    r|dz   |k    r|dz   }|||z
  fS |}|dz   |k    °@n|t          v rt          | ||¦  «        }|�|S |}|dz   |k    °šd S )Nrƒ   s   data)r‘   Ú_MP4_COMMENT_BOXÚ_MP4_METADATA_CONTAINERSÚ_find_mp4_comment_slot_in_range)r‰   Ústartr‹   ÚcursorÚboxr�   r�   r�   Úchild_cursorÚ	child_boxÚ
child_typeÚchild_content_offsetÚ	child_endÚpayload_offsetÚslots                  r   r•   r•   ‰   s  € Ø€FØ
�1‰*˜Ò
Ð
Ý˜B ¨Ñ,Ô,ˆØˆ;ØØ,/Ñ)ˆ�. 'ØÕ'Ò'Ð'Ø)ˆLØ Ñ" gÒ-Ð-Ý)¨"¨l¸GÑDÔD�	ØÐ$ØØ>GÑ;�
Ð0°)Ø Ò(Ð(Ð-AÀAÑ-EÈÒ-RÐ-RØ%9¸AÑ%=�NØ)¨9°~Ñ+EÐEÐEØ(�ð  Ñ" gÒ-Ð-øð Õ1Ð1Ð1Ý2°2°~ÀwÑOÔOˆDØÐØ�Øˆð) �1‰*˜Ò
Ð
ð* ˆ4r   c           	      óD  — t          | d¦  «        5 }t          j        |                     ¦   «         dt          j        ¬¦  «        5 }t	          |dt          |¦  «        ¦  «        cd d d ¦  «         cd d d ¦  «         S # 1 swxY w Y   	 d d d ¦  «         d S # 1 swxY w Y   d S )NÚrbr   ©Úaccess)r]   ÚmmapÚfilenoÚACCESS_READr•   r1   )r`   rb   r‰   s      r   Ú_find_mp4_comment_slotr§   £   sU  € Ý	ˆi˜Ñ	Ô	ð C &ÝŒY�v—}’}‘”¨µ$Ô2BÐCÑCÔCð 	CÀrÝ2°2°q½#¸b¹'¼'ÑBÔBð	Cð 	Cð 	Cð 	Cñ 	Cô 	Cð 	CðCð Cð Cð Cñ Cô Cð Cð Cð	Cð 	Cð 	Cð 	Cøøøð 	Cð 	Cð 	Cð 	Cð 	CðCð Cð Cñ Cô Cð Cð Cð Cð Cð Cð Cð Cøøøð Cð Cð Cð Cð Cð Cs5   ‘4BÁA<Á#BÁ<B 	Â BÂB 	ÂBÂBÂBc           
      óÌ  — t          t          di¦  «        }t          | d¦  «        5 }t          j        |                     ¦   «         dt          j        ¬¦  «        5 }d}d }d }	 |                     ||¦  «        }|dk     rn¤|t          |¦  «        z   }|t          |¦  «        k     r0||         dk    r$|dz  }|t          |¦  «        k     r||         dk    °$|||z
  f}	|	}|                     t          t          d|dz
  ¦  «        |¦  «        dk    r|	}|t          |¦  «        z   }ŒÁ|p|cd d d ¦  «         cd d d ¦  «         S # 1 swxY w Y   	 d d d ¦  «         d S # 1 swxY w Y   d S )NTr¡   r   r¢   é    r†   é@   )rF   r8   r]   r¤   r¥   r¦   Úfindr1   Úrfindr“   rN   )
r`   Úplaceholderrb   r‰   r—   Úfallback_slotÚcomment_slotrž   Úpayload_endrŸ   s
             r   Ú!_find_reserved_metadata_text_slotr±   ©   s  € Ý(Õ*@À$Ð)GÑHÔH€KÝ	ˆi˜Ñ	Ô	ð 1 &ÝŒY�v—}’}‘”¨µ$Ô2BÐCÑCÔCð 	1ÀrØˆFØ ˆMØˆLð;Ø!#§¢¨°fÑ!=Ô!=�Ø! AÒ%Ð%ØØ,­s°;Ñ/?Ô/?Ñ?�Ø!¥C¨¡G¤GÒ+Ð+°°;´À4Ò0GÐ0GØ 1Ñ$�Kð "¥C¨¡G¤GÒ+Ð+°°;´À4Ò0GÐ0Gà% {°^Ñ'CÐC�Ø $�Ø—8’8Õ,­c°!°^ÀbÑ5HÑ.IÔ.IÈ>ÑZÔZÐ^_Ò_Ð_Ø#'�LØ'­#¨kÑ*:Ô*:Ñ:�ð;ð  Ð0 =ð!	1ð 	1ð 	1ð 	1ñ 	1ô 	1ð 	1ð1ð 1ð 1ð 1ñ 1ô 1ð 1ð 1ð	1ð 	1ð 	1ð 	1øøøð 	1ð 	1ð 	1ð 	1ð 	1ð1ð 1ð 1ñ 1ô 1ð 1ð 1ð 1ð 1ð 1ð 1ð 1øøøð 1ð 1ð 1ð 1ð 1ð 1s6   §4EÁCE Ä'EÅ E	ÅEÅE	ÅEÅEÅ Ec                 ó>   — t          | ¦  «        pt          | ¦  «        S r   )r±   r§   ©r`   s    r   Ú_find_mp4_metadata_slotr´   ¿   s   € Ý,¨YÑ7Ô7Ð\Õ;QÐR[Ñ;\Ô;\Ð\r   c                 ó   — |t          | ¦  «        k    rd S | |         }d}d}|dk    r||z  s|dz  }|dz  }|dk    r||z  ¯|dk    s||z   t          | ¦  «        k    rd S ||dz
  z  }t          d|¦  «        D ]}|dz  | ||z            z  }Œ||fS )NrM   r†   rƒ   )r1   Úrange)r‰   rŠ   ÚfirstÚmaskÚlengthrW   Úindexs          r   Ú_read_ebml_sizer»   Ã   sÏ   € Ø•�R‘”ÒÐØˆtØˆvŒJ€EØ€DØ€FØ
�AŠ+ˆ+˜u t™|ˆ+Ø�‰
ˆØ�!‰ˆð �AŠ+ˆ+˜u t™|ˆ+ð �‚z€z�V˜f‘_¥s¨2¡w¤wÒ.Ð.ØˆtØ�T˜A‘XÑ€EÝ�q˜&Ñ!Ô!ð 2ð 2ˆØ˜!‘˜r &¨5¡.Ô1Ñ1ˆˆØ�&ˆ=Ðr   c                 óÒ  — t          | d¦  «        5 }t          j        |                     ¦   «         dt          j        ¬¦  «        5 }d}	 |                     t
          |¦  «        }|dk     r	 d d d ¦  «         d d d ¦  «         d S |t          t
          ¦  «        z   }t          t          |¦  «        |dz   ¦  «        }|                     d||¦  «        }|dk    rTt          ||dz   ¦  «        }|�?|\  }	}
|dz   |
z   }||	z   t          |¦  «        k    r||	fcd d d ¦  «         cd d d ¦  «         S |t          t
          ¦  «        z   }Œú# 1 swxY w Y   	 d d d ¦  «         d S # 1 swxY w Y   d S )Nr¡   r   r¢   Ti    s   D‡r   )	r]   r¤   r¥   r¦   r«   Ú_MKV_COMMENT_NAMEr1   Úminr»   )r`   rb   r‰   r—   Úname_offsetÚsearch_startÚ
search_endÚvalue_offsetÚparsed_sizeÚ	data_sizeÚsize_lenÚdata_offsets               r   Ú_find_mkv_comment_slotrÇ   Ô   s>  € Ý	ˆi˜Ñ	Ô	ð > &ÝŒY�v—}’}‘”¨µ$Ô2BÐCÑCÔCð 	>ÀrØˆFð>Ø ŸgšgÕ&7¸Ñ@Ô@�Ø ’?�?Øð	>ð 	>ð 	>ñ 	>ô 	>ð 	>ð>ð >ð >ñ >ô >ð >ð >ð >ð  +­SÕ1BÑ-CÔ-CÑC�Ý ¥ R¡¤¨,¸Ñ*=Ñ>Ô>�
Ø!Ÿwšw {°LÀ*ÑMÔM�Ø 1Ò$Ð$Ý"1°"°lÀQÑ6FÑ"GÔ"G�KØ"Ð.Ø.9Ñ+˜	 8Ø&2°QÑ&6¸Ñ&A˜Ø&¨Ñ2µc¸"±g´gÒ=Ð=Ø#.°	Ð#9ð	>ð 	>ð 	>ð 	>ñ 	>ô 	>ð 	>ð>ð >ð >ð >ñ >ô >ð >ð >ð" %¥sÕ+<Ñ'=Ô'=Ñ=�ð>ð	>ð 	>ð 	>ð 	>øøøð 	>ð 	>ð 	>ð 	>ð 	>ð>ð >ð >ñ >ô >ð >ð >ð >ð >ð >ð >ð >øøøð >ð >ð >ð >ð >ð >sH   ‘4EÁ&EÁ+EÂBEÄEÄ+EÅE	ÅEÅ
E	ÅEÅE Å#E c                 óä   — |€dS |\  }}t          ||¦  «        }|€dS t          | d¦  «        5 }|                     |¦  «         |                     |¦  «         d d d ¦  «         n# 1 swxY w Y   dS )NFzr+bT)rK   r]   Úseekr^   )r`   rŸ   rI   rž   rJ   Úpaddedrb   s          r   Ú_write_metadata_slotrË   é   s¼   € Ø€|ØˆuØ%)Ñ"€N�NÝ  °Ñ?Ô?€FØ€~ØˆuÝ	ˆi˜Ñ	Ô	ð  6Ø�Š�NÑ#Ô#Ð#Ø�Š�VÑÔÐðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ˆ4s   ®+A%Á%A)Á,A)F©Úallow_inplace_updater   c                ó  — |sdS t          j        ¦   «         } || ¦  «        }t          j        ¦   «         |z
  dz  }|€t          ||› d|d›d�¦  «         dS |\  }	}
t          |¦  «        t	          |
¦  «        k    r9t          ||› dt          |¦  «        › dt	          |
¦  «        › d|d›d�¦  «         dS t          | ||¦  «        }|r't          ||› d	|d›d
t	          |	¦  «        › �¦  «         nt          ||› d|d›d�¦  «         |S )NFg     @�@z%: no reserved metadata slot found in z.1fz msz$: reserved metadata slot too small (z > z) after z: updated metadata in place in z ms at offset z.: in-place update failed after slot lookup in )ÚtimeÚperf_counterr!   r1   r   rË   )r`   rI   Úcontainer_nameÚfind_slot_fnrÍ   r   Ú
started_atrŸ   Ú
elapsed_msrž   rJ   Úoks               r   Ú_maybe_update_metadata_in_placerÖ   ö   sÎ  € Øð ØˆuÝÔ"Ñ$Ô$€JØˆ<˜	Ñ"Ô"€DÝÔ#Ñ%Ô%¨
Ñ2°fÑ<€JØ€|Ý˜M¨nÐ+vÐ+vÐcmÐ+vÐ+vÐ+vÐ+vÑwÔwÐwØˆuØ%)Ñ"€N�NÝ
ˆ=ÑÔ�C Ñ/Ô/Ò/Ð/Ý˜M¨nð  ,jð  ,jÕbeÐfsÑbtÔbtð  ,jð  ,jÕy|ð  ~Lñ  zMô  zMð  ,jð  ,jð  Wað  ,jð  ,jð  ,jð  ,jñ  	kô  	kð  	kØˆuÝ	˜i¨¨}Ñ	=Ô	=€BØ	ð AÝ˜M¨nð  ,Qð  ,QÐ]gð  ,Qð  ,Qð  ,QÕ{~ð  @Nñ  |Oô  |Oð  ,Qð  ,Qñ  	Rô  	Rð  	Rð  	Rå˜M¨nÐ+Ð+ÐlvÐ+Ð+Ð+Ð+ñ  	Aô  	Að  	AØ€Ir   c                 óÌ  — t          d¦  «        }t          | d¦  «        }t          j        d¬¦  «        }t          j                             |d¦  «        }d„ t          | ¦  «                             ¦   «         D ¦   «         }||d<   	 t          ||¦  «         |dd	d
d| ddd|ddddddg}t          t          ||¦  «        ¦  «        D ] \  }	\  }
}}|d|
d|	› �d|› �d|	› �d|› �gz  }Œ!||gz  }t          j        |ddddd¬¦  «        }|j        dk    st          j                             |¦  «        smt          j                             |¦  «        rt	          j        |¦  «         d|j        p|j        pd                     ¦   «         ft+          j        |d¬¦  «         S t	          j        || ¦  «         	 t+          j        |d¬¦  «         d S # t+          j        |d¬¦  «         w xY w)!NÚffmpegr:   Úwangp_metadata_)Úprefixzcomment.ffmetac                 ó`   — i | ]+\  }}t          |¦  «                             ¦   «         d v¯(||“Œ,S )>   r	   r   )r+   Úlowerrq   s      r   rs   z,_copy_video_with_comment.<locals>.<dictcomp>  s`   € ð  Hð  Hð  H™:˜3 ÕTWÐX[ÑT\ÔT\×TbÒTbÑTdÔTdð  mGð  UGð  UGˆC�ð  UGð  UGð  UGr   r	   ú-yri   rj   ú-iz-fÚ
ffmetadataú-mapÚ0z-map_metadataÚ1ú-cÚcopyz-attachz-metadata:s:t:z	mimetype=z	filename=Tr#   r$   Frl   r   r&   )Úignore_errors)Tr&   )r   r�   ÚtempfileÚmkdtempÚosr€   Újoinrz   r_   rd   Ú	enumerateÚ_materialize_mkv_attachmentsrt   ru   rv   ÚisfileÚexistsÚremoveÚstderrrw   r2   ÚshutilÚrmtreer,   )r`   Úmetadata_textÚsource_imagesÚffmpeg_pathÚtemp_output_pathÚmeta_dirÚmetadata_pathra   ÚcommandÚattachment_noÚattachment_pathÚattachment_filenameÚmimetypery   s                 r   Ú_copy_video_with_commentrý     s‘  € Ý% hÑ/Ô/€KÝ-¨i¸ÑDÔDÐÝÔÐ'8Ð9Ñ9Ô9€HÝ”G—L’L Ð+;Ñ<Ô<€Mð Hð  HÕ)=¸iÑ)HÔ)H×)NÒ)NÑ)PÔ)Pð  Hñ  Hô  H€DØ#€Dˆ�Oð4Ý˜}¨dÑ3Ô3Ð3Ø  d¨G°T¸9ÀdÈLÐZ^Ð`mÐouÐwzð  }Lð  NQð  SWð  Y_ð  `ˆÝOXÕYuð  wDð  FNñ  ZOô  ZOñ  PPô  PPð 	sð 	sÑKˆMÑK˜OÐ-@À(Ø˜	 ?Ð4TÀ]Ð4TÐ4TÐVlÐbjÐVlÐVlð  oOð  @Mð  oOð  oOð  Qrð  ]pð  Qrð  Qrð  sñ  sˆGˆGØÐ$Ð%Ñ%ˆÝ” ¸À4ÐRYÐbjÐrwÐxÑxÔxˆØÔ Ò!Ð!­¬¯ªÐ8HÑ)IÔ)IÐ!ÝŒw�~Š~Ð.Ñ/Ô/ð ,Ý”	Ð*Ñ+Ô+Ð+Ø˜6œ=Ð?¨F¬MÐ?¸R×FÒFÑHÔHÐHõ 	Œ�h¨dÐ3Ñ3Ô3Ð3Ð3õ 	Œ
Ð# YÑ/Ô/Ð/ØåŒ�h¨dÐ3Ñ3Ô3Ð3Ð3Ð3ø�Œ�h¨dÐ3Ñ3Ô3Ð3Ð3øøøs   ÂD G ÆG ÇG#c                 óº  — ddl m} ddlm} ddl}ddl}	 t          | t          ¦  «        r'|                      d¦  «        r	| |j	        fS | |j
        fS t          | t          ¦  «        �rX|j                             | ¦  «        st          d| › �¦  «         dS |j                             | ¦  «        d                              ¦   «         }|                     | ¦  «        }|j        d	vrn|j        d
k    rN|                     d|j        d¦  «        }|                     ||                     ¦   «         d         ¬¦  «         |}n|                     d¦  «        }|                     ¦   «         }|dv r|                     |d¬¦  «         |j	        }	n|                     |dd¬¦  «         |j
        }	|                     ¦   «         |	fS t          | |j        ¦  «        r½| j        d	vrn| j        d
k    rN|                     d| j        d¦  «        }|                     | |                      ¦   «         d         ¬¦  «         |} n|                      d¦  «        } |                     ¦   «         }|                      |d¬¦  «         |                     ¦   «         |j	        fS t          dt7          | ¦  «        › �¦  «         dS # t8          $ r}
t          d|
› �¦  «         Y d}
~
dS d}
~
ww xY w)ak  
    Convert various image formats to bytes suitable for MP4 cover art.
    
    Args:
        img: Can be:
            - PIL Image object
            - File path (str)
            - bytes
    
    Returns:
        tuple: (image_bytes, image_format)
            - image_bytes: Binary image data
            - image_format: AtomDataType constant (JPEG or PNG)
    r   )ÚAtomDataType)ÚImageNó   ‰PNGzWarning: Image file not found: )NNr†   )ÚRGBÚLÚRGBAr  )éÿ   r  r  é   )r¸   )r   z.bmpz.tiffz.tifÚPNG)ro   ÚJPEGé_   )ro   Úqualityz!Warning: Unsupported image type: z!Error converting image to bytes: )Úmutagen.mp4rÿ   ÚPILr   Úiorè   r(   r)   Ú
startswithr  r  r+   r€   rí   r   ÚsplitextrÜ   r]   ÚmodeÚnewÚsizeÚpasteÚsplitÚconvertÚBytesIOÚsaveÚgetvalueÚtypeÚ	Exception)Úimgrÿ   r   r  rè   ÚextÚpil_imgÚ
backgroundÚ	img_bytesÚ
img_formatÚes              r   Ú_convert_image_to_bytesr"  "  s  € ð )Ð(Ð(Ð(Ð(Ð(ØÐÐÐÐÐØ€I€I€IØ€I€I€IðAå�c�5Ñ!Ô!ð 	.à�~Š~˜jÑ)Ô)ð .Ø˜LÔ,Ð,Ð,à˜LÔ-Ð-Ð-õ �c�3ÑÔñ  	4Ø”7—>’> #Ñ&Ô&ð "ÝÐ=¸Ð=Ð=Ñ>Ô>Ð>Ø!�zð ”'×"Ò" 3Ñ'Ô'¨Ô*×0Ò0Ñ2Ô2ˆCð —j’j ‘o”oˆGð Œ| <Ð/Ð/Ø”< 6Ò)Ð)à!&§¢¨5°'´,ÀÑ!PÔ!P�JØ×$Ò$ W°7·=²=±?´?À1Ô3EÐ$ÑFÔFÐFØ(�G�Gà%Ÿošo¨eÑ4Ô4�Gð Ÿ
š
™œˆIð Ð7Ð7Ð7Ø—’˜Y¨u�Ñ5Ô5Ð5Ø)Ô-�
�
à—’˜Y¨v¸r�ÑBÔBÐBØ)Ô.�
à×%Ò%Ñ'Ô'¨Ð3Ð3õ �c˜5œ;Ñ'Ô'ð 	:àŒx˜|Ð+Ð+Ø”8˜vÒ%Ð%Ø!&§¢¨5°#´(¸OÑ!LÔ!L�JØ×$Ò$ S¨s¯yªy©{¬{¸1¬~Ð$Ñ>Ô>Ð>Ø$�C�CàŸ+š+ eÑ,Ô,�Cð Ÿ
š
™œˆIØ�HŠH�Y uˆHÑ-Ô-Ð-Ø×%Ò%Ñ'Ô'¨Ô)9Ð9Ð9åÐ=µ$°s±)´)Ð=Ð=Ñ>Ô>Ð>Øˆzøåð ð ð ÝÐ5°!Ð5Ð5Ñ6Ô6Ð6Øˆzˆzˆzˆzˆzøøøøðøøøs8   –2J3 Á	J3 ÁAJ3 ÂD)J3 Ç CJ3 ÊJ3 Ê3
KÊ=KËKc                 ó´   — d                      d„ t          | pd¦  «                             ¦   «         D ¦   «         ¦  «        }|                     d¦  «        }|p|S )Nr&   c              3   óN   K  — | ] }|                      ¦   «         s|d v r|ndV — Œ!dS )z._-r|   N)Úisalnum)rr   Úchars     r   ú	<genexpr>z/_safe_metadata_filename_part.<locals>.<genexpr>{  s;   è è € ÐhÐhÈ˜4Ÿ<š<™>œ>ÐC¨T°U¨]¨]�4�4ÀÐhÐhÐhÐhÐhÐhr   z._)ré   r+   r2   )r.   ÚdefaultÚsafes      r   Ú_safe_metadata_filename_partr*  z  sY   € Ø�7Š7ÐhÐhÕPSÐTXÐT^Ð\^ÑP_ÔP_×PeÒPeÑPgÔPgÐhÑhÔhÑhÔh€DØ�:Š:�dÑÔ€DØˆ?�7Ðr   c                 óF  — t           j                             t          | pd¦  «        ¦  «        } t           j                             | ¦  «        \  }}d|v r<|                     dd¦  «        \  }}t          |d¦  «        t          |d¦  «        |z   fS dt          | d¦  «        fS )Nr&   Ú__r†   ÚunknownÚsourcez
source.png)rè   r€   Úbasenamer+   r  r  r*  )Úfilenamer~   r  ÚtagÚoriginal_stems        r   Ú_split_mkv_attachment_filenamer3  €  s›   € ÝŒw×Ò¥ H N°Ñ 3Ô 3Ñ4Ô4€HÝ”× Ò  Ñ*Ô*�I€Dˆ#Øˆt€|€|Ø!ŸZšZ¨¨aÑ0Ô0Ñˆˆ]Ý+¨C°Ñ;Ô;Õ=YÐZgÐiqÑ=rÔ=rÐuxÑ=xÐxÐxØÕ2°8¸\ÑJÔJÐJÐJr   c                 óª  — | sd S i }t          | t          ¦  «        r|                      ¦   «         }n8d„ t          t          | t          t          f¦  «        r| n| g¦  «        D ¦   «         }|D ]e\  }}t          |t          ¦  «        r|n|g}d„ |D ¦   «         }|r8|                     t          |pd¦  «        g ¦  «                             |¦  «         Œf|pd S )Nc              3   óD   K  — | ]}t          |¦  «        d          |fV — ŒdS )r   N)r3  ©rr   r  s     r   r'  z+_normalize_source_images.<locals>.<genexpr>�  sM   è è € ð  cð  cÀcÕ3°CÑ8Ô8¸Ô;¸SÐAð  cð  cð  cð  cð  cð  cr   c                 ó   — g | ]}|®|‘ŒS r   © r6  s     r   ú
<listcomp>z,_normalize_source_images.<locals>.<listcomp>“  s   € ÐCÐCÐC °3°?˜°?°?°?r   r-  )r(   r6   r_   ÚlistÚtupleÚ
setdefaultr+   Úextend)ró   Ú
normalizedÚiterableÚimg_tagÚimg_dataÚimg_listÚvalid_imagess          r   Ú_normalize_source_imagesrD  ‰  s7  € Øð ØˆtØ€JÝ�-¥Ñ&Ô&ð cØ ×&Ò&Ñ(Ô(ˆˆð cð  cÍTÕcmÐn{õ  Cõ  EJð  ~Kñ  dLô  dLð  SaÐR_ÐR_ð  S`ð  Rañ  Nbô  Nbð  cñ  cô  cˆØ%ð Vð VÑˆ�Ý)¨(µDÑ9Ô9ÐI�8�8À¸zˆØCÐC xÐCÑCÔCˆØð 	VØ×!Ò!¥# gÐ&:°Ñ";Ô";¸RÑ@Ô@×GÒGÈÑUÔUÐUøØÐ˜Ðr   c                 ó4   — |                       d¦  «        rdS dS )Nr  )r   z	image/png)r   z
image/jpeg)r  )Úimage_bytess    r   Ú_image_extension_and_mimetyperG  ™  s$   € Ø×Ò˜jÑ)Ô)ð #Ø"Ð"ØÐr   c                 óh  — t          | ¦  «        } | €g S g }t          ¦   «         }|                      ¦   «         D �]ø\  }}t          |d¦  «        }t	          |¦  «        D �]Ñ\  }}t          |¦  «        \  }	}
|	sŒt          |	¦  «        \  }}t          |t          ¦  «        rtt          j
                             |¦  «        rUt          t          j
                             |¦  «        ¦  «        \  }}t          j
                             |¦  «        d         }nd|› �}t          |d|› �¦  «        }|› d|› |› �}t          j
                             |¦  «        \  }}d}|                     ¦   «         |v r$|› d|› |› �}|dz  }|                     ¦   «         |v °$|                     |                     ¦   «         ¦  «         t          j
                             ||¦  «        }t%          |d¦  «        5 }|                     |	¦  «         d d d ¦  «         n# 1 swxY w Y   |                     |||f¦  «         �ŒÓ�Œú|S )Nr-  r   Úsource_r,  r†   r|   Úwb)rD  Úsetr_   r*  rê   r"  rG  r(   r+   rè   r€   rí   r3  r/  r  rÜ   Úaddré   r]   r^   Úappend)ró   Úwork_dirÚattachmentsÚused_filenamesr@  rB  Úsafe_tagÚimage_nor  rF  Ú_image_formatÚ	extensionrü   Ú_attachment_tagÚoriginal_filenameÚoriginal_nameÚ	safe_namerû   Ú	base_namer  Úcounterrú   rb   s                          r   rë   rë   Ÿ  s˜  € Ý,¨]Ñ;Ô;€MØÐØˆ	Ø€KÝ‘U”U€NØ*×0Ò0Ñ2Ô2ð Qñ QÑˆ�Ý/°¸ÑCÔCˆÝ& xÑ0Ô0ð 	Qñ 	Q‰MˆH�cÝ)@ÀÑ)EÔ)EÑ&ˆK˜Øð ØÝ"?ÀÑ"LÔ"LÑˆI�xÝ˜#�sÑ#Ô#ð 5­¬¯ª°sÑ(;Ô(;ð 5Ý5SÕTVÔT[×TdÒTdÐehÑTiÔTiÑ5jÔ5jÑ2�Ð!2Ý "¤× 0Ò 0Ð1BÑ CÔ CÀAÔ F��à 4¨(Ð 4Ð 4�Ý4°]ÐDXÈhÐDXÐDXÑYÔYˆIØ%-Ð"GÐ"G°Ð"G¸IÐ"GÐ"GÐÝœW×-Ò-Ð.AÑBÔB‰NˆI�sØˆGØ%×+Ò+Ñ-Ô-°Ð?Ð?Ø)2Ð&CÐ&C°WÐ&C¸cÐ&CÐ&CÐ#Ø˜1‘�ð &×+Ò+Ñ-Ô-°Ð?Ð?ð ×ÒÐ2×8Ò8Ñ:Ô:Ñ;Ô;Ð;Ý œgŸlšl¨8Ð5HÑIÔIˆOÝ�o tÑ,Ô,ð *°Ø—’˜[Ñ)Ô)Ð)ð*ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *à×Ò Ð1DÀhÐOÑPÔPÐPÑPñ+	Qð, Ðs   Ç)HÈHÈHc                 ó²  — ddl m}m}m} dd l}dd l}t          |¦  «        }|s| S 	 | j        €|                      ¦   «          g }i }| 	                    ¦   «         D �]\  }	}
|
€Œ	g }t          |
t          ¦  «        r|
n|
g}|D ]Ü}|�Øt          |¦  «        \  }}|rÄt          |t          ¦  «        rU|j                             |¦  «        r;|j                             |¦  «        }|j                             |¦  «        d         }n||j        k    rdnd}|	› |› �}|                     t)          |¦  «        ||dœ¦  «         |                      |||¦  «        ¦  «         ŒÝ|r|||	<   �Œ|r5|| j        d<    |j        |¦  «                             d¦  «        | j        d	<   n8# t.          $ r+}t1          d
|› �¦  «         t1          d¦  «         Y d }~nd }~ww xY w| S )Nr   )ÚMP4ÚMP4Coverrÿ   r†   r   r   )rº   r0  rT  ú%----:com.apple.iTunes:EMBEDDED_IMAGESr#   ú$----:com.apple.iTunes:IMAGE_METADATAz(Failed to embed cover art with mutagen: z>This might be due to image format or MP4 file structure issues)r  r\  r]  rÿ   r3   rè   rD  ra   Úadd_tagsr_   r(   r:  r"  r+   r€   rí   r/  r  r  rM  r1   rC   rD   r  r   )Úfileró   r\  r]  rÿ   r3   rè   Ú
cover_dataÚimage_metadatar@  rA  Ú
tag_imagesrB  r  Úcover_bytesÚimage_formatr0  rT  r!  s                      r   Ú embed_source_images_metadata_mp4rg  À  sx  € Ø7Ð7Ð7Ð7Ð7Ð7Ð7Ð7Ð7Ð7Ø€K€K€KØ€I€I€Iå,¨]Ñ;Ô;€MØð Øˆð2QØŒ9ÐØ�MŠM‰OŒOˆOð ˆ
Øˆð "/×!4Ò!4Ñ!6Ô!6ð 	5ñ 	5ÑˆG�XØÐØàˆJõ $.¨h½Ñ#=Ô#=ÐM�x�xÀHÀ:ˆHàð Oð O�Ø�?Ý0GÈÑ0LÔ0LÑ-�K Ø"ð Oå% c­3Ñ/Ô/ð ?°B´G·N²NÀ3Ñ4GÔ4Gð ?Ø')¤w×'7Ò'7¸Ñ'<Ô'<˜HØ(*¬×(8Ò(8¸Ñ(BÔ(BÀ1Ô(E˜I˜Ið 3?À,ÔBRÒ2RÐ2R¨¨ÐX^˜IØ*1Ð'>°9Ð'>Ð'>˜Hà"×)Ò)Ý%(¨¡_¤_Ø(0Ø)2ð+ð +ñ ô ð ð
 #×)Ò)¨(¨(°;ÀÑ*MÔ*MÑNÔNÐNøàð 5Ø*4�˜wÑ'ùàð 	kØAKˆDŒIÐ=Ñ>à@JÀÄ
È>Ñ@ZÔ@Z×@aÒ@aÐbiÑ@jÔ@jˆDŒIÐ<Ñ=øøõ ð Qð Qð QÝÐ<¸Ð<Ð<Ñ=Ô=Ð=ÝÐOÑPÔPÐPÐPÐPÐPÐPÐPøøøøðQøøøð €Ks   §E7F Æ
GÆ)!GÇGc                 ó
  — 	 ddl m}  || ¦  «        }t          j        |¦  «        g|j        d<   |�t          ||¦  «         |                     ¦   «          dS # t          $ r }t          d| › d|› �¦  «         Y d}~dS d}~ww xY w)	zï
    Legacy MP4 metadata writer kept for reference.
    
    Args:
        file_path (str): Path to MP4 file
        metadata_dict (dict): Metadata dictionary to save
    
    Returns:
        bool: True if successful, False otherwise
    r   ©r\  r   NTúError saving metadata to MP4 ú: F)	r  r\  r3   rC   ra   rg  r  r  r   )r`   rE   ró   r\  ra  r!  s         r   Ú_legacy_save_metadata_to_mp4rl     s²   € ð
Ø#Ð#Ð#Ð#Ð#Ð#Øˆs�9‰~Œ~ˆÝ"œj¨Ñ7Ô7Ð8ˆŒ	�'ÑØÐ$Ý,¨T°=ÑAÔAÐAØ�	Š	‰ŒˆØˆtøÝð ð ð ÝÐ>¨iÐ>Ð>¸1Ð>Ð>Ñ?Ô?Ð?Øˆuˆuˆuˆuˆuøøøøðøøøs   ‚AA Á
BÁ"A=Á=Bc                 óØ  — 	 |                       dd¦  «        }ddd| ddt          j        |¦  «        › �dd	d
d|g}t          j        |dd¬¦  «        }|j        dk    rt          j        || ¦  «         dS t          d|j	        › �¦  «         t          j                             |¦  «        rt          j        |¦  «         dS # t          $ r }t          d| › d|› �¦  «         Y d}~dS d}~ww xY w)zï
    Legacy MKV metadata writer kept for reference.
    
    Args:
        file_path (str): Path to MKV file
        metadata_dict (dict): Metadata dictionary to save
    
    Returns:
        bool: True if successful, False otherwise
    ú.mkvz_temp_with_metadata.mkvrØ   rÝ   rÞ   z	-metadatazcomment=rà   rá   rã   rä   T©rm   r.   r   ú-Warning: Failed to add metadata to MKV file: FúError saving metadata to MKV rk  N)r,   r3   rC   rt   ru   rv   rð   Úmover   rï   rè   r€   rí   rî   r  )r`   rE   Ú	temp_pathÚ
ffmpeg_cmdry   r!  s         r   Ú_legacy_save_metadata_to_mkvru    s   € ðà×%Ò% fÐ.GÑHÔHˆ	ð �d˜D )ØÐ?¥D¤J¨}Ñ$=Ô$=Ð?Ð?Ø�CØ�&Øð
ˆ
õ ” 
¸4ÀdÐKÑKÔKˆàÔ Ò!Ð!åŒK˜	 9Ñ-Ô-Ð-Ø�4åÐQÀ&Ä-ÐQÐQÑRÔRÐRåŒw�~Š~˜iÑ(Ô(ð %Ý”	˜)Ñ$Ô$Ð$Ø�5øåð ð ð ÝÐ>¨iÐ>Ð>¸1Ð>Ð>Ñ?Ô?Ð?Øˆuˆuˆuˆuˆuøøøøðøøøs   ‚A/B? Á3A
B? Â?
C)Ã	C$Ã$C)c                 ó"  — t          | ¦  «                             ¦   «                              t          ¦  «        rt	          | ||¦  «        S t          | ¦  «                             ¦   «                              d¦  «        rt          | |¦  «        S dS )zó
    Legacy video metadata writer kept for reference.
    
    Args:
        file_path (str): Path to video file
        metadata_dict (dict): Metadata dictionary to save
    
    Returns:
        bool: True if successful, False otherwise
    rn  F)r+   rÜ   ÚendswithÚ_MP4_METADATA_EXTENSIONSÚsave_metadata_to_mp4Úsave_metadata_to_mkv)r`   rE   ró   s      r   Ú_legacy_save_video_metadatar{  C  s|   € õ ˆ9�~„~×ÒÑÔ×&Ò&Õ'?Ñ@Ô@ð Ý# I¨}¸mÑLÔLÐLÝ	ˆY‰Œ×	Ò	Ñ	Ô	×	(Ò	(¨Ñ	0Ô	0ð Ý# I¨}Ñ=Ô=Ð=àˆur   c                 ó–   — 	 ddl m}  || ¦  «        }|j        d         d         }t          j        |¦  «        S # t
          $ r Y dS w xY w)zÆ
    Legacy MP4 metadata reader kept for reference.
    
    Args:
        file_path (str): Path to MP4 file
    
    Returns:
        dict or None: Metadata dictionary if found, None otherwise
    r   ri  r   N)r  r\  ra   r3   r4   r  )r`   r\  ra  ra   s       r   Ú_legacy_read_metadata_from_mp4r}  W  si   € ðØ#Ð#Ð#Ð#Ð#Ð#Øˆs�9‰~Œ~ˆØŒy˜Ô! !Ô$ˆÝŒz˜$ÑÔÐøÝð ð ð Øˆtˆtðøøøs   ‚7: º
AÁAc           	      ó\  — 	 t          j        dddddd| gdd¬¦  «        }|j        d	k    rpt          j        |j        ¦  «        }|                     d
i ¦  «                             di ¦  «        }dD ]*}||v r$	 t          j        ||         ¦  «        c S #  Y Œ'xY wŒ+dS # t          $ r Y dS w xY w)zÆ
    Legacy MKV metadata reader kept for reference.
    
    Args:
        file_path (str): Path to MKV file
    
    Returns:
        dict or None: Metadata dictionary if found, None otherwise
    rh   ri   Úquietú-print_formatr3   ú-show_formatTro  r   ro   ra   r   N)rt   ru   rv   r3   r4   rw   r7   r  )r`   ry   Ú
probe_datark   Útag_keys        r   Ú_legacy_read_metadata_from_mkvr„  j  sö   € ðå”Ø�t˜W o°vØ˜Ið!
ð  Tð+ñ +ô +ˆð
 Ô Ò!Ð!Ýœ F¤MÑ2Ô2ˆJØ$Ÿ.š.¨°2Ñ6Ô6×:Ò:¸6À2ÑFÔFˆKð Pð !ð !�Ø˜kÐ)Ð)ð!Ý#œz¨+°gÔ*>Ñ?Ô?Ð?Ð?Ð?øð!Ø ˜øøøð	 *ð
 ˆtøÝð ð ð Øˆtˆtðøøøs*   ‚A4B Á7BÂB ÂBÂB Â
B+Â*B+c                 ó  — t          | ¦  «                             ¦   «                              t          ¦  «        rt	          | ¦  «        S t          | ¦  «                             ¦   «                              d¦  «        rt          | ¦  «        S dS )zÊ
    Legacy video metadata reader kept for reference.
    
    Args:
        file_path (str): Path to video file
    
    Returns:
        dict or None: Metadata dictionary if found, None otherwise
    rn  N©r+   rÜ   rw  rx  Úread_metadata_from_mp4Úread_metadata_from_mkvr³   s    r   Ú _legacy_read_metadata_from_videor‰  ‹  sv   € õ ˆ9�~„~×ÒÑÔ×&Ò&Õ'?Ñ@Ô@ð Ý% iÑ0Ô0Ð0Ý	ˆY‰Œ×	Ò	Ñ	Ô	×	(Ò	(¨Ñ	0Ô	0ð Ý% iÑ0Ô0Ð0àˆtr   c                 ó  — t          j        |dd¬¦  «        }|                     d¦  «        }t          |¦  «        }|€t	          | |dt
          ||¬¦  «        rdS |�t          |d¦  «         	 d	d
lm}  || ¦  «        }|j	        €| 
                    ¦   «          |g|j	        t          <   |�t          ||¦  «         |                     ¦   «          t          |d¦  «         dS # t          $ r }	t          d| › d|	› �¦  «         Y d }	~	dS d }	~	ww xY w)NFr=   r@   r#   r\  ©rÑ   rÒ   rÍ   r   TzKMP4: skipping in-place update because embedded images are being written toor   ri  z4MP4: used standard metadata save path (non in-place)rj  rk  )r3   rC   rD   rD  rÖ   r´   r!   r  r\  ra   r`  Ú_MP4_COMMENT_TAGrg  r  r  r   )
r`   rE   ró   rÍ   r   rò   rI   r\  ra  r!  s
             r   ry  ry  �  sZ  € Ý”J˜}¸5ÈZÐXÑXÔX€MØ!×(Ò(¨Ñ1Ô1€MÝ,¨]Ñ;Ô;€MØÐÕ!@ÀÈMÐjoõ  Vð  mAð  Q^ð  "_ñ  "_ô  "_ÐØˆtØÐ Ý˜MÐ+xÑyÔyÐyðØ#Ð#Ð#Ð#Ð#Ð#Øˆs�9‰~Œ~ˆØŒ9ÐØ�MŠM‰OŒOˆOØ'4 oˆŒ	Õ"Ñ#ØÐ$Ý,¨T°=ÑAÔAÐAØ�	Š	‰ŒˆÝ˜MÐ+aÑbÔbÐbØˆtøÝð ð ð ÝÐ>¨iÐ>Ð>¸1Ð>Ð>Ñ?Ô?Ð?Øˆuˆuˆuˆuˆuøøøøðøøøs   Á-A2C! Ã!
DÃ+DÄDc                 ó¬  — t          j        |dd¬¦  «        }|                     d¦  «        }t          |¦  «        }|€t	          | |dt
          ||¬¦  «        rdS |�t          |d¦  «         	 t          | ||¦  «        \  }}|rt          |d	¦  «         dS t          d
|› �¦  «         dS # t          $ r }	t          d| › d|	› �¦  «         Y d }	~	dS d }	~	ww xY w)NFr=   r@   r#   ÚMKVr‹  TzKMKV: skipping in-place update because embedded images are being written tooz9MKV: created a rewritten container copy to store metadatarp  rq  rk  )
r3   rC   rD   rD  rÖ   rÇ   r!   rý   r   r  )
r`   rE   ró   rÍ   r   rò   rI   rÕ   rj   r!  s
             r   rz  rz  µ  s-  € Ý”J˜}¸5ÈZÐXÑXÔX€MØ!×(Ò(¨Ñ1Ô1€MÝ,¨]Ñ;Ô;€MØÐÕ!@ÀÈMÐjoõ  Uð  l@ð  P]ð  "^ñ  "^ô  "^ÐØˆtØÐ Ý˜MÐ+xÑyÔyÐyð	Ý,¨Y¸À}ÑUÔU‰	ˆˆEØð 	Ý Ð/jÑkÔkÐkØ�4ÝÐE¸eÐEÐEÑFÔFÐFØˆuøÝð ð ð ÝÐ>¨iÐ>Ð>¸1Ð>Ð>Ñ?Ô?Ð?Øˆuˆuˆuˆuˆuøøøøðøøøs   Á-&B) ÂB) Â)
CÂ3CÃCc                 óN  — t          |¦  «        }t          | ¦  «                             ¦   «                              t          ¦  «        rt          | ||||¬¦  «        S t          | ¦  «                             ¦   «                              d¦  «        rt          | ||||¬¦  «        S dS )NrÌ   rn  F)rD  r+   rÜ   rw  rx  ry  rz  )r`   rE   ró   rÍ   r   s        r   Úsave_video_metadatar�  É  s½   € Ý,¨]Ñ;Ô;€MÝ
ˆ9�~„~×ÒÑÔ×&Ò&Õ'?Ñ@Ô@ð UÝ# I¨}¸mÐbvð  GTð  Uñ  Uô  Uð  	UÝ
ˆ9�~„~×ÒÑÔ×&Ò& vÑ.Ô.ð UÝ# I¨}¸mÐbvð  GTð  Uñ  Uô  Uð  	UØˆ5r   c                 óX  — 	 ddl m}  || ¦  «        }|j        �|j                             t          ¦  «        nd }|sd nt          |d         ¦  «        }|�|S n# t          $ r Y nw xY wt          | ¦  «        }t          D ]*}t          |                     |¦  «        ¦  «        }|�|c S Œ+d S )Nr   ri  )	r  r\  ra   r7   rŒ  r;   r  rz   Ú_CONTAINER_COMMENT_TAGS)r`   r\  ra  Ú
tag_valuesr:   ra   rƒ  s          r   r‡  r‡  Ò  sà   € ðØ#Ð#Ð#Ð#Ð#Ð#Øˆs�9‰~Œ~ˆØ8<¼	Ð8M�T”Y—]’]Õ#3Ñ4Ô4Ð4ÐSWˆ
Ø)ÐR�4�4Õ/CÀJÈqÄMÑ/RÔ/RˆØÐØˆOð  øåð ð ð Øˆðøøøå 	Ñ*Ô*€DÝ*ð ð ˆÝ'¨¯ª°Ñ(9Ô(9Ñ:Ô:ˆØÐØˆOˆOˆOð  àˆ4s   ‚AA Á
A&Á%A&c           	      óŠ  — 	 t          d¦  «        }t          j        |ddddd| gdddd	d
¬¦  «        }|j        dk    rut	          j        |j        ¦  «        }|                     di ¦  «                             di ¦  «        }t          D ]*}t          |                     |¦  «        ¦  «        }|�|c S Œ+d S # t          $ r Y d S w xY w)Nrh   ri   r  r€  r3   r�  Tr#   r$   Frl   r   ro   ra   )r   rt   ru   rv   r3   r4   rw   r7   r’  r;   r  )r`   rx   ry   r‚  rk   rƒ  r:   s          r   rˆ  rˆ  ä  s  € ðÝ*¨9Ñ5Ô5ˆÝ” ¨t°W¸oÈvÐWeÐgpÐ qð  CGð  NRð  ]dð  muð  }Bð  Cñ  Cô  CˆØÔ Ò!Ð!Ýœ F¤MÑ2Ô2ˆJØ$Ÿ.š.¨°2Ñ6Ô6×:Ò:¸6À2ÑFÔFˆKÝ2ð $ð $�Ý/°·²ÀÑ0HÔ0HÑIÔI�ØÐ'Ø#�O�O�Oð (àˆtøÝð ð ð Øˆtˆtðøøøs   ‚B.B4 Â1B4 Â4
CÃCc                 ó  — t          | ¦  «                             ¦   «                              t          ¦  «        rt	          | ¦  «        S t          | ¦  «                             ¦   «                              d¦  «        rt          | ¦  «        S d S )Nrn  r†  r³   s    r   Úread_metadata_from_videor–  ô  st   € Ý
ˆ9�~„~×ÒÑÔ×&Ò&Õ'?Ñ@Ô@ð 1Ý% iÑ0Ô0Ð0Ý
ˆ9�~„~×ÒÑÔ×&Ò& vÑ.Ô.ð 1Ý% iÑ0Ô0Ð0Øˆ4r   c                 ó¸  — 	 ddl m} ddl} || ¦  «        }|j        �	d|j        vri S |j        d         }|j                             d¦  «        }|�rí |j        |d                              d¦  «        ¦  «        }i }|                     ¦   «         D �]ª\  }	}
g ||	<   |
D �]›}|d         }|t          |¦  «        k    rŒ|€t          ¦   «         }t          j        |d¬	¦  «         ||         }|d
         }t          j                             ||¦  «        }t          j                             |¦  «        r�t          j                             |¦  «        \  }}d}t          j                             |¦  «        rM|› d|› |› �}t          j                             ||¦  «        }|dz  }t          j                             |¦  «        °Mt!          |d¦  «        5 }|                     |¦  «         ddd¦  «         n# 1 swxY w Y   t          j                             |¦  «        r||	                              |¦  «         �Œ��Œ¬|S t'          d| › d�¦  «         dg i}t)          |¦  «        D ]È\  }}|€t          ¦   «         }t          j        |d¬	¦  «         d|› d�}t          j                             ||¦  «        }t!          |d¦  «        5 }|                     |¦  «         ddd¦  «         n# 1 swxY w Y   t          j                             |¦  «        r|d                              |¦  «         ŒÉ|S # t*          $ r}t'          d|› �¦  «         i cY d}~S d}~ww xY w)aj  
    Extract cover art from MP4 files using mutagen with proper tag association.
    
    Args:
        video_path (str): Path to the MP4 file
        output_dir (str): Directory to save extracted images
    
    Returns:
        dict: Dictionary mapping tags to lists of extracted image file paths
              Format: {tag_name: [path1, path2, ...], ...}
    r   ri  Nr^  r_  r#   rº   T©Úexist_okr0  r†   r|   rJ  z$Warning: No IMAGE_METADATA found in z, using generic extractionr-  Ú
cover_art_r   z%Error extracting cover art from MP4: )r  r\  r3   ra   r7   r4   r*   r_   r1   Ú_create_temp_dirrè   Úmakedirsr€   ré   rí   r  r]   r^   rM  r   rê   r  )Ú
video_pathÚ
output_dirr\  r3   ra  Ú	cover_artÚmetadata_datarc  Úextracted_filesr1  rd  Úimg_infoÚ	cover_idxÚcoverr0  Úoutput_fileÚbaser  rZ  ÚfÚir!  s                         r   Ú_extract_mp4_cover_artr©  û  s  € ðMØ#Ð#Ð#Ð#Ð#Ð#Øˆˆˆàˆs�:‰ŒˆàŒ9ÐÐ GÈtÌyÐ XÐ XØˆIà”YÐFÔGˆ	ð œ	ŸšÐ&LÑMÔMˆàñ ;	#à'˜TœZ¨°aÔ(8×(?Ò(?ÀÑ(HÔ(HÑIÔIˆNØ ˆOà#1×#7Ò#7Ñ#9Ô#9ð  Añ  A‘��ZØ')� Ñ$à *ð Añ A�HØ (¨Ô 1�Ià ¥C¨	¡N¤NÒ2Ð2Ø Ø!Ð)Õ8HÑ8JÔ8J¨:Ý”K 
°TÐ:Ñ:Ô:Ð:à% iÔ0�Eð  (¨
Ô3�HÝ"$¤'§,¢,¨z¸8Ñ"DÔ"D�Kõ ”w—~’~ kÑ2Ô2ð )Ý$&¤G×$4Ò$4°XÑ$>Ô$>™	˜˜cØ"#˜Ý œgŸnšn¨[Ñ9Ô9ð )Ø*.Ð'?Ð'?°Ð'?¸#Ð'?Ð'?˜HÝ*,¬'¯,ª,°zÀ8Ñ*LÔ*L˜KØ# q™L˜Gõ !œgŸnšn¨[Ñ9Ô9ð )õ ˜k¨4Ñ0Ô0ð '°AØŸš ™œ˜ð'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'õ ”w—~’~ kÑ2Ô2ð AØ'¨Ô,×3Ò3°KÑ@Ô@Ð@ùñ;Að> #Ð"õ Ð_¸Ð_Ð_Ð_Ñ`Ô`Ð`Ø(¨"˜oˆOå% iÑ0Ô0ð Cð C‘��5ØÐ%Õ4DÑ4FÔ4F zÝ”˜J°Ð6Ñ6Ô6Ð6à/¨Ð/Ð/Ð/�Ý œgŸlšl¨:°xÑ@Ô@�å˜+ tÑ,Ô,ð #°Ø—G’G˜E‘N”N�Nð#ð #ð #ñ #ô #ð #ð #ð #ð #ð #ð #øøøð #ð #ð #ð #õ ”7—>’> +Ñ.Ô.ð CØ# IÔ.×5Ò5°kÑBÔBÐBøà"Ð"øåð ð ð ÝÐ9°aÐ9Ð9Ñ:Ô:Ð:Øˆ	ˆ	ˆ	ˆ	ˆ	ˆ	øøøøðøøøss   ‚&L1 ©F*L1 ÇG5Ç)L1 Ç5G9Ç9L1 Ç<G9Ç=AL1 É BL1 ËK)ËL1 Ë)K-	Ë-L1 Ë0K-	Ë1?L1 Ì1
MÌ;MÍMÍMc                  óX   — t          j        ¦   «         } t          j        | d¬¦  «         | S )NTr˜  )ræ   rç   rè   rœ  )Útemp_dirs    r   r›  r›  V  s*   € ÝÔÑ!Ô!€HÝ„K� 4Ð(Ñ(Ô(Ð(Ø€Or   c                 ó	  — |                       ¦   «                              t          ¦  «        rt          | |¦  «        S |€t	          ¦   «         }t          j        |d¬¦  «         	 t          d¦  «        }t          d¦  «        }|ddddd	| g}t          j	        |ddd¬
¦  «        }dd l
}|                     |j        ¦  «        }g }t          |                     dg ¦  «        ¦  «        D �]7\  }	}
|
                     di ¦  «                             dd¦  «        dk    }|
                     di ¦  «        }d|v r-|d                               ¦   «                              d¦  «        pnd|v o,|d                               ¦   «                              d¦  «        p=d|v o|d                              d¦  «        pd|v o|d                              d¦  «        }|
                     d¦  «        dk    }|
                     d¦  «        dk    r|s|r|r|                     |	¦  «         �Œ9|si S i }t#          ¦   «         }|D �]ô}|d         |         }|                     di ¦  «        }|                     d¦  «        p|                     d¦  «        pd|› d�}t%          |¦  «        \  }}t
          j                             |¦  «        }|                      ¦   «                              t*          ¦  «        s|dz  }t
          j                             |¦  «        \  }}d}|}||v r|dz  }|› d|› |› �}||v °|                     |¦  «         t
          j                             ||¦  «        }|dddd | d!d"|› �d#d$d%d$|g}	 t          j	        |ddd¬
¦  «         t
          j                             |¦  «        r)|                     |g ¦  «                             |¦  «         �ŒŸ# t          j        $ rE}t9          d&|› d't
          j                             | ¦  «        › d(|j        › �¦  «         Y d }~�Œîd }~ww xY w|S # t          j        $ rC}t9          d)t
          j                             | ¦  «        › d(|j        › �¦  «         i cY d }~S d }~ww xY w)*NTr˜  rh   rØ   ri   r  r€  r3   z-show_streams)rm   r.   rn   r   ÚstreamsÚdispositionÚattached_picr†   ra   ÚFILENAMEr   r0  ÚMIMETYPEzimage/rü   Ú
codec_nameÚmjpegÚ
codec_typeÚvideoÚattachment_r   r|   rÝ   rj   rÞ   rà   z0:z	-frames:vrâ   z-updatezFailed to extract attachment z from rk  z$Error extracting source images from )rÜ   rw  rx  r©  r›  rè   rœ  r   rt   ru   r3   r4   rw   rê   r7   r  rM  rK  r3  r€   r/  Ú_IMAGE_EXTENSIONSr  rL  ré   rí   r<  ÚCalledProcessErrorr   rï   )r�  rž  rx   rô   Ú	probe_cmdry   Újson_moduler‚  Úattachment_streamsr¨  ÚstreamÚis_attached_picra   Úhas_image_metadataÚis_mjpegr¡  rP  Ú
stream_idxÚstream_inforV  r@  Úsafe_filenamerY  r  rZ  Úfinal_filenamer¥  Úextract_cmdr!  s                                r   Úextract_source_imagesrÅ  [  s+  € ð ×ÒÑÔ×"Ò"Õ#;Ñ<Ô<ð >Ý% j°*Ñ=Ô=Ð=ØÐÝ%Ñ'Ô'ˆ
Ý„K�
 TÐ*Ñ*Ô*Ð*ð[Ý*¨9Ñ5Ô5ˆÝ)¨(Ñ3Ô3ˆð ˜$ ¨¸&Ø˜Zð
ˆ	õ
 ” 	¸$ÀTÐQUÐVÑVÔVˆØ"Ð"Ð"Ð"Ø ×&Ò& v¤}Ñ5Ô5ˆ
ð  ÐÝ" :§>¢>°)¸RÑ#@Ô#@ÑAÔAð 	-ñ 	-‰IˆAˆvð
 %Ÿjšj¨¸Ñ;Ô;×?Ò?ÀÐPQÑRÔRÐVWÒWˆOð —:’:˜f bÑ)Ô)ˆDà˜dÐ"Ðc t¨JÔ'7×'=Ò'=Ñ'?Ô'?×'HÒ'HÐIbÑ'cÔ'cð MØ˜dÐ"Ðc t¨JÔ'7×'=Ò'=Ñ'?Ô'?×'HÒ'HÐIbÑ'cÔ'cðMà˜dÐ"ÐL t¨JÔ'7×'BÒ'BÀ8Ñ'LÔ'LðMð ˜dÐ"ÐL t¨JÔ'7×'BÒ'BÀ8Ñ'LÔ'Lð	 ð —z’z ,Ñ/Ô/°7Ò:ˆHà—
’
˜<Ñ(Ô(¨GÒ3Ð3Ø ð 4Ø%7ð 4Ø<Dð 4à"×)Ò)¨!Ñ,Ô,Ð,ùà!ð 	ØˆIð ˆÝ™œˆà,ð (	tñ (	tˆJà$ YÔ/°
Ô;ˆKØ—?’? 6¨2Ñ.Ô.ˆDà—’˜Ñ$Ô$ð /Ø—’˜Ñ$Ô$ð/à.˜jÐ.Ð.Ð.ð õ *HÐHYÑ)ZÔ)ZÑ&ˆGÐ&õ œG×,Ò,Ð->Ñ?Ô?ˆMØ ×&Ò&Ñ(Ô(×1Ò1Õ2CÑDÔDð (Ø Ñ'�õ  œW×-Ò-¨mÑ<Ô<‰NˆI�sØˆGØ*ˆNØ  NÐ2Ð2Ø˜1‘�Ø$-Ð!>Ð!>°Ð!>¸Ð!>Ð!>�ð ! NÐ2Ð2ð ×Ò˜~Ñ.Ô.Ð.åœ'Ÿ,š, z°>ÑBÔBˆKð ˜T 4¨°$¸
ØÐ)˜ZÐ)Ð)¨;¸¸YÈØðˆKðtÝ”˜{¸4ÀdÐRVÐWÑWÔWÐWÝ”7—>’> +Ñ.Ô.ð PØ#×.Ò.¨w¸Ñ;Ô;×BÒBÀ;ÑOÔOÐOùøÝÔ0ð tð tð tÝÐr°jÐrÐrÍÌ×HXÒHXÐYcÑHdÔHdÐrÐrÐhiÔhpÐrÐrÑsÔsÐsÐsÐsÐsÐsÑsøøøøðtøøøð ÐøåÔ(ð ð ð ÝÐ_µR´W×5EÒ5EÀjÑ5QÔ5QÐ_Ð_ÐUVÔU]Ð_Ð_Ñ`Ô`Ð`Øˆ	ˆ	ˆ	ˆ	ˆ	ˆ	øøøøðøøøsQ   Á$F>P- È#EP- Í2A OÏP- ÏP(Ï#:P#ÐP- Ð#P(Ð(P- Ð-Q?Ð<8Q:Ñ4Q?Ñ:Q?r   )NFr   )BÚ__doc__r3   r¤   rè   rð   rt   ræ   rÏ   Úpathlibr   Úshared.utils.video_decoder   Ú%DEFAULT_RESERVED_VIDEO_METADATA_BYTESr8   rŒ  r“   r½   r’  r”   rx  r·  r   r   r!   r/   r;   rF   rK   rO   rX   rd   rf   rz   r�   r‘   r•   r§   r±   r´   r»   rÇ   rË   rÖ   rý   r"  r*  r3  rD  rG  rë   rg  rl  ru  r{  r}  r„  r‰  ry  rz  r�  r‡  rˆ  r–  r©  r›  rÅ  r8  r   r   ú<module>rÊ     sû  ððð ð €€€Ø €€€Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð à :Ð :Ð :Ð :Ð :Ð :à(1Ð %Ø3Ð ØÐ ØÐ Ø*Ð ØNÐ Ø# W¨g°wÐ@PÐQÐ Ø+Ð Ø-Ð ð.ð .ð .ðð ð ð-ð -ð -ð
>ð >ð >ðeð eð eð`ð `ð `ðJð Jð Jð 7\Ðkoð [ð [ð [ð [ðLð Lð Lð
ð ð ð ?dÐswð }ð }ð }ð }ð	Vð 	Vð 	VðEð Eð Eð
Uð Uð Uð(ð ð ð4Cð Cð Cð1ð 1ð 1ð,]ð ]ð ]ðð ð ð">ð >ð >ð*
ð 
ð 
ð uzð  JKð ð ð ð ð ð*4ð 4ð 4ð 4ð.Uð Uð Uðpð ð ðKð Kð Kðð ð ð  ð  ð  ðð ð ðB=ð =ð =ð@ð ð ð ð0'ð 'ð 'ðVð ð ð ð(ð ð ð&ð ð ðBð ð ð$ð ð ð ð0ð ð ð ð(ð ð ð ðð ð ð$ð ð ð ð ð ðYð Yð Yð Yðvð ð ð
eð eð eð eð eð er   