U
    PeX                     @   sn  d Z dZddlmZ ddlmZ ddlmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ G dd deZ G dd deZ!G dd deZ"G dd deZ#G dd deZ$G dd deZ%G dd deZ&e'dkrjddl(Z(dd l)m*Z* e&e(j+d! d"Z,e*e, e,rjd#e,_-dS )$a	  
Video player
============

.. versionadded:: 1.2.0

The video player widget can be used to play video and let the user control the
play/pausing, volume and position. The widget cannot be customized much because
of the complex assembly of numerous base widgets.

.. image:: images/videoplayer.jpg
    :align: center

Annotations
-----------

If you want to display text at a specific time and for a certain duration,
consider annotations. An annotation file has a ".jsa" extension. The player
will automatically load the associated annotation file if it exists.

An annotation file is JSON-based, providing a list of label dictionary items.
The key and value must match one of the :class:`VideoPlayerAnnotation` items.
For example, here is a short version of a jsa file that you can find in
`examples/widgets/cityCC0.jsa`::


    [
        {"start": 0, "duration": 2,
        "text": "This is an example of annotation"},
        {"start": 2, "duration": 2,
        "bgcolor": [0.5, 0.2, 0.4, 0.5],
        "text": "You can change the background color"}
    ]

For our cityCC0.mpg example, the result will be:

.. image:: images/videoplayer-annotation.jpg
    :align: center

If you want to experiment with annotation files, test with::

    python -m kivy.uix.videoplayer examples/widgets/cityCC0.mpg

Fullscreen
----------

The video player can play the video in fullscreen, if
:attr:`VideoPlayer.allow_fullscreen` is activated by a double-tap on
the video. By default, if the video is smaller than the Window, it will be not
stretched.

You can allow stretching by passing custom options to a
:class:`VideoPlayer` instance::

    player = VideoPlayer(source='myvideo.avi', state='play',
        options={'fit_mode': 'contain'})

End-of-stream behavior
----------------------

You can specify what happens when the video has finished playing by passing an
`eos` (end of stream) directive to the underlying
:class:`~kivy.core.video.VideoBase` class. `eos` can be one of 'stop', 'pause'
or 'loop' and defaults to 'stop'. For example, in order to loop the video::

    player = VideoPlayer(source='myvideo.avi', state='play',
        options={'eos': 'loop'})

.. note::

    The `eos` property of the VideoBase class is a string specifying the
    end-of-stream behavior. This property differs from the `eos`
    properties of the :class:`VideoPlayer` and
    :class:`~kivy.uix.video.Video` classes, whose `eos`
    property is simply a boolean indicating that the end of the file has
    been reached.

)VideoPlayerVideoPlayerAnnotation    )load)exists)ObjectPropertyStringPropertyBooleanPropertyNumericPropertyDictPropertyOptionProperty)	Animation)
GridLayout)FloatLayout)ProgressBar)Label)Video)Image)Factory)Logger)Clockc                   @   s,   e Zd ZedZdd Zdd Zdd ZdS )VideoPlayerVolumeNc                 C   s2   | j |j sdS ||  | jjdg|j| j< dS )NFr   T)collide_pointposgrabvideovolumeuduidselftouch r!   8/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/videoplayer.pyon_touch_downe   s
    
zVideoPlayerVolume.on_touch_downc                 C   sT   |j | k	rd S t|j|j }|dkrPt|d d}||j| j d< |d | j_dS )N
   d      g      Y@T)	grab_currentabsyoyminr   r   r   r   r   r    Zdyr!   r!   r"   on_touch_movem   s    
zVideoPlayerVolume.on_touch_movec                 C   sR   |j | k	rd S ||  t|j|j }|dk rN| jjdkrFd| j_nd| j_d S )Nr$   r         ?)r'   ungrabr(   r)   r*   r   r   r,   r!   r!   r"   on_touch_upx   s    


zVideoPlayerVolume.on_touch_up)__name__
__module____qualname__r   r   r#   r-   r0   r!   r!   r!   r"   r   b   s   r   c                   @   s   e Zd ZedZdd ZdS )VideoPlayerPlayPauseNc                 C   s2   | j |j r.| jjdkr"d| j_nd| j_dS dS )z.. versionchanged:: 1.4.0playpauseTN)r   r   r   stater   r!   r!   r"   r#      s
    
z"VideoPlayerPlayPause.on_touch_downr1   r2   r3   r   r   r#   r!   r!   r!   r"   r4      s   r4   c                   @   s   e Zd ZedZdd ZdS )VideoPlayerStopNc                 C   s$   | j |j r d| j_d| j_dS d S )Nstopr   T)r   r   r   r7   positionr   r!   r!   r"   r#      s    zVideoPlayerStop.on_touch_downr8   r!   r!   r!   r"   r9      s   r9   c                       s   e Zd ZedZedddZedZ fddZdd Z	d	d
 Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Z  ZS )VideoPlayerProgressBarNT)Z	allownoner.   c                    sv   t t| jf | tjdd| _tjdd| _| j| j | | j | j	}| j
}|d| |d| |d| d S )N)2   ,   )sizez0:00)textr   r?   seek)superr<   __init__r   ZBubblebubbler   bubble_label
add_widget_update_bubblefbind)r   kwargsupdaterH   	__class__r!   r"   rC      s    

zVideoPlayerProgressBar.__init__c                 C   s   | j j| j| jd d S )N)r;   r7   )r   bindrG   _showhide_bubbler   instancevaluer!   r!   r"   on_video   s    
zVideoPlayerProgressBar.on_videoc                 C   s2   | j |j sd S |   ||  | |j dS NT)r   r   _show_bubbler   _update_seekxr   r!   r!   r"   r#      s    
z$VideoPlayerProgressBar.on_touch_downc                 C   s   |j | k	rd S | |j dS rS   )r'   rU   rV   r   r!   r!   r"   r-      s    
z$VideoPlayerProgressBar.on_touch_movec                 C   s>   |j | k	rd S ||  | jr,| j| j d | _|   dS rS   )r'   r/   rA   r   _hide_bubbler   r!   r!   r"   r0      s    

z"VideoPlayerProgressBar.on_touch_upc                 C   s<   | j dkrd S t| jt| j|| j }|t| j  | _d S )Nr   )widthmaxrV   r+   rightfloatrA   )r   rV   r!   r!   r"   rU      s    
z#VideoPlayerProgressBar._update_seekc                 C   s   d| _ t| d d S )Nr&   alpha)r\   r   Zstop_allr   r!   r!   r"   rT      s    z#VideoPlayerProgressBar._show_bubblec                 C   s   d| _ tdddd|  d S )Nr.   r      Zin_out_expo)r\   dt)r\   r   startr]   r!   r!   r"   rW      s    z#VideoPlayerProgressBar._hide_bubblec                 C   s$   ddd|f| j _ddd|f| j_d S )Nr&   )rD   Zbackground_colorrE   colorrO   r!   r!   r"   on_alpha   s    zVideoPlayerProgressBar.on_alphac                 G   s   | j }| j d kr2| jjdkr"d}n| jj| jj }| jj| }t|d }t||d  }d||f | j_| j|| j  | j	_
| j| j	_d S )Nr   <   z%d:%02d)rA   r   durationr;   intrE   r@   rV   rX   rD   Zcenter_xtopr)   )r   lrA   r_   minutessecondsr!   r!   r"   rG      s    
z%VideoPlayerProgressBar._update_bubblec                 C   s   |dkr|    n|   d S )Nr5   )rW   rT   rO   r!   r!   r"   rN      s    
z'VideoPlayerProgressBar._showhide_bubble)r1   r2   r3   r   r   r	   rA   r\   rC   rR   r#   r-   r0   rU   rT   rW   rc   rG   rN   __classcell__r!   r!   rK   r"   r<      s   
r<   c                   @   s,   e Zd ZedZedZedZdd ZdS )VideoPlayerPreviewNFc                 C   s$   | j |j r | js d| _d| j_dS )NTr5   )r   r   
click_doner   r7   r   r!   r!   r"   r#      s    z VideoPlayerPreview.on_touch_down)	r1   r2   r3   r   sourcer   r   rm   r#   r!   r!   r!   r"   rl      s   rl   c                   @   s0   e Zd ZdZedZedZei Zdd Z	dS )r   a0  Annotation class used for creating annotation labels.

    Additional keys are available:

    * bgcolor: [r, g, b, a] - background color of the text box
    * bgsource: 'filename' - background image used for the background text box
    * border: (n, e, s, w) - border used for the background image

    r   r&   c                 C   s"   |  D ]\}}t| || qd S N)itemssetattr)r   rP   annkeyrQ   r!   r!   r"   on_annotation  s    z#VideoPlayerAnnotation.on_annotationN)
r1   r2   r3   __doc__r	   ra   re   r
   
annotationrt   r!   r!   r!   r"   r      s
   	r   c                       sz  e Zd ZdZedZedZedZedZ	edZ
edddZed	d
dZedZedZedZedZedZedZedZedZedZedZed	Zed
Zei ZedZdZ fddZ dd Z!dd Z"dd Z#dd Z$d d! Z%d"d# Z&d$d% Z'd&d' Z(d(d) Z)d*d+ Z*d,d- Z+d.d/ Z,d0d1 Z-d2d3 Z.d4d5 Z/d6d7 Z0d@d8d9Z1d:d; Z2 fd<d=Z3d>d? Z4  Z5S )Ar   zFVideoPlayer class. See module documentation for more information.
     r   r.   r:   )r5   r6   r:   )optionsFT)
deprecatedz4atlas://data/images/defaulttheme/player-play-overlayzdata/images/image-loading.zipz5atlas://data/images/defaulttheme/media-playback-startz4atlas://data/images/defaulttheme/media-playback-stopz5atlas://data/images/defaulttheme/media-playback-pausez2atlas://data/images/defaulttheme/audio-volume-highz4atlas://data/images/defaulttheme/audio-volume-mediumz1atlas://data/images/defaulttheme/audio-volume-lowz3atlas://data/images/defaulttheme/audio-volume-mutedNc                    sb   d | _ d | _d| _g | _tt| jf | | j}| j}| j	}|d| |d| | j
r^|   d S )Nrw   	thumbnailannotations)_video_image_annotations_annotations_labelsrB   r   rC   _update_thumbnail_update_annotationsrH   rn   _trigger_video_load)r   rI   Zupdate_thumbnailZupdate_annotationsrH   rK   r!   r"   rC     s    

zVideoPlayer.__init__c                 G   s,   | j }|d kr"t| jd }| _ |  d S Nrx   )_video_load_evr   schedule_once_do_video_load)r   largsZevr!   r!   r"   r     s    
zVideoPlayer._trigger_video_loadc                 G   s6   | j s2| jdd}|d d }t|r2| | d S )N.r&   r   z.png)r{   rn   rsplitr   _load_thumbnail)r   r   filenamer{   r!   r!   r"   _try_load_default_thumbnail  s
    z'VideoPlayer._try_load_default_thumbnailc                 G   s6   | j s2| jdd}|d d }t|r2| | d S )Nr   r&   r   z.jsa)r|   rn   r   r   _load_annotations)r   r   r   r|   r!   r!   r"   _try_load_default_annotations  s
    z)VideoPlayer._try_load_default_annotationsc                 C   sF   t | jd t | jd | jd k	r6| j  d | _|rB|   d S r   )r   r   r   r   r}   Zunloadr   rO   r!   r!   r"   	on_source	  s    

zVideoPlayer.on_sourcec                 G   s   |  | j d S ro   )r   r{   r   r   r!   r!   r"   r     s    zVideoPlayer._update_thumbnailc                 G   s   |  | j d S ro   )r   r|   r   r!   r!   r"   r     s    zVideoPlayer._update_annotationsc                 C   s   || j _d S ro   )r~   image_overlay_playrO   r!   r!   r"   on_image_overlay_play  s    z!VideoPlayer.on_image_overlay_playc                 C   s   || j _d S ro   )r~   image_loadingrO   r!   r!   r"   on_image_loading  s    zVideoPlayer.on_image_loadingc                 C   s8   | j s
d S | j   |r4t|| d| _| j | j d S )N)rn   r   )	containerclear_widgetsrl   r~   rF   )r   r{   r!   r!   r"   r      s    
zVideoPlayer._load_thumbnailc              	   C   s\   | j s
d S g | _|rXt|d}t|| _W 5 Q R X | jrX| jD ]}| jt|d q@d S )Nr)rv   )r   r   openr   r   appendr   )r   r|   fdrr   r!   r!   r"   r   (  s    
zVideoPlayer._load_annotationsc                 C   s   | j d k	r|| j _d S ro   )r}   r7   rO   r!   r!   r"   on_state4  s    
zVideoPlayer.on_statec                 C   s
   || _ d S ro   )r7   rO   r!   r!   r"   
_set_state8  s    zVideoPlayer._set_statec                 G   sX   t f | j| j| jdddd| j| _| jj| j| d| d| d| j	d d S )Nr   )rV   r)   )rn   r7   r   pos_hintre   r;   r   )Ztexturere   r;   r   r7   )
r   rn   r7   r   ry   r}   rM   _play_startedsetterr   r   r!   r!   r"   r   ;  s     
zVideoPlayer._do_video_loadc                 C   s   |rdnd}|  ||S )Nr5   r:   )r   rO   r!   r!   r"   on_playE  s    zVideoPlayer.on_playc                 C   s   | j s
d S || j _d S ro   )r}   r   rO   r!   r!   r"   	on_volumeI  s    zVideoPlayer.on_volumec                 C   sf   | j }|sd S |D ]N}|j}|j}||ks6|| |k rJ|jr`|j| q|jd kr| j| qd S ro   )r   ra   re   parentremove_widgetr   rF   )r   rP   rQ   labelslabelra   re   r!   r!   r"   on_positionN  s    
zVideoPlayer.on_positionc                 C   s   | j s
dS | j j||d dS )aj  Change the position to a percentage (strictly, a proportion)
           of duration.

        :Parameters:
            `percent`: float or int
                Position to seek as a proportion of total duration, must
                be between 0-1.
            `precise`: bool, defaults to True
                Precise seeking is slower, but seeks to exact requested
                percent.

        .. warning::
            Calling seek() before the video is loaded has no effect.

        .. versionadded:: 1.2.0

        .. versionchanged:: 1.10.1
            The `precise` keyword argument has been added.
        N)precise)r}   rA   )r   percentr   r!   r!   r"   rA   [  s    zVideoPlayer.seekc                 C   s   | j   | j | j d S ro   )r   r   rF   r}   rO   r!   r!   r"   r   s  s    
zVideoPlayer._play_startedc                    s:   | j |j sdS |jr*| jr*| j | _dS tt| |S )NFT)r   r   Zis_double_tapallow_fullscreen
fullscreenrB   r   r#   r   rK   r!   r"   r#   w  s    
zVideoPlayer.on_touch_downc                 C   s>  |   }|s$td |r d| _d S | jsBtd |r>d| _d S |r| j| j| j| j| j|j	d d  d | _
}|j	d d  D ]}|| q|d |k	r|d |  ||  d| _d| _i | _d| _nl| j
}||  |d	 D ]}|| q|d
 | _|d | _|d | _|d | _|d |k	r:|d |  d S )Nz;VideoPlayer: Cannot switch to fullscreen, window not found.Fz4VideoPlayer: Cannot switch to fullscreen, no parent.)r   r   r?   r   	size_hintwindow_childrenr   )r   r   )r%   r%   )r&   r&   r   r   r   r   r?   )Zget_parent_windowr   warningr   r   r   r?   r   r   childrenZ_fullscreen_stater   rF   )r   rP   rQ   Zwindowr7   childr!   r!   r"   on_fullscreen  sL    

	





zVideoPlayer.on_fullscreen)T)6r1   r2   r3   ru   r   rn   r{   r	   re   r;   r   r   r7   r   r5   r   r   Z
image_playZ
image_stopZimage_pauseZimage_volumehighZimage_volumemediumZimage_volumelowZimage_volumemutedr|   r   r   r
   ry   r   r   r   rC   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rA   r   r#   r   rk   r!   r!   rK   r"   r     sx   	
	

r   __main__N)runTouchAppr&   )rn   r:   ).ru   __all__jsonr   os.pathr   Zkivy.propertiesr   r   r   r	   r
   r   Zkivy.animationr   Zkivy.uix.gridlayoutr   Zkivy.uix.floatlayoutr   Zkivy.uix.progressbarr   Zkivy.uix.labelr   Zkivy.uix.videor   r   Zkivy.factoryr   Zkivy.loggerr   Z
kivy.clockr   r   r4   r9   r<   rl   r   r   r1   sysZ	kivy.baser   argvZplayerr7   r!   r!   r!   r"   <module>   s>   O "
W   
