#!/usr/bin/python
# -*- coding: utf-8 -*-

import cv
import sys, threading

class film:
    """
    Une classe pour accéder aux images d'un film
    """
    def __init__(self,filename):
        """
        le constructeur
        @param filename le nom d'un fichier video
        """
        self.filename=filename

        self.capture=cv.CreateFileCapture(self.filename)
        t=threading.Thread(target=self.autoTest)
        t.start()
        t.join(5.0) # attente de 5 secondes au plus
        

    def autoTest(self):
        self.ok=False
        try:
            self.frame=cv.QueryFrame(self.capture)
            self.num=0
            self.fps=cv.GetCaptureProperty(self.capture,cv.CV_CAP_PROP_FPS)
            self.framecount=cv.GetCaptureProperty(self.capture,cv.CV_CAP_PROP_FRAME_COUNT)
            assert 1.0*self.filesize/self.framecount > 2000, "fichier aberrant en taille"
            # plus de 200 octets par trame
            self.ok=True
        except:
            pass

    def __int__(self):
        return int(self.ok)
    def __nonzero__(self):
        return self.ok
        
    def image(self,num,recode=None):
        """
        accès à une image du film, avec rembobinage du film si nécessaire
        @param num l'image recherchée
        @param recode recodage si nécessaire, peut valoir 'PIL'. None par défaut
        @return un objet de type IplImage ou None si la fin du film est dépassée
        """
        if num>self.num:
            for i in range(self.num,num):
                self.frame=cv.QueryFrame(self.capture)
        elif 0<=num<self.num: 
            #cv.ReleaseCapture(self.capture)
            self.capture = cv.CreateFileCapture(self.filename)
            for i in range (0, num+1):
                self.frame=cv.QueryFrame(self.capture)
        self.num=num
        if recode == 'PIL':
            return Ipl2PIL(self.frame)
        else:
            return self.frame

    def nbTrames(self):
        """
        @return Le nombre de trames du film
        """
        return int(self.framecount)

    def tramesParSeconde(self):
        """
        @return le nombre de trames par seconde
        """
        return int(self.fps)

    def totalTrames(self):
        """
        @return le nombre total de trames dans le film
        """
        return int(self.framecount)
        


##################### ci-dessous, des fonctions de démonstration seulement #####
    
import os.path, re

def showSlowAVI(fname):
    f=film(fname)
    if f:
        print "vidéo : %s %d trames %d trames par seconde" %(fname, f.nbTrames(), f.tramesParSeconde())
        loop = True
        forward = None
        num=0
        frame=f.image(num)
        while(loop):
            if forward == True:
                num+=1
                frame = f.image(num)
            elif forward == False and num>0:
                num-=1
                frame = f.image(num)
            forward=None
            if (frame == None):
                break;
            cv.ShowImage("Example2", frame)
            char = cv.WaitKey(33)
            if (char != -1):
                if char==1048603: #ESC
                    loop = False
                elif char==1048678: #f
                    forward=True
                elif char==1048674: #b
                    forward=False
    else:
        print "la vidéo %s n'est pas bien acceptée par OpenCV" %fname
    cv.DestroyWindow("Example2")
        
def showMovies(arg, dirname,names):
    aviPattern=re.compile(".*\.avi$|.*\.mov$", re.I)
    for f in names:
        if aviPattern.match(f):
            showSlowAVI(os.path.join(dirname,f))
    
if __name__ == '__main__':
    if len(sys.argv)>1:
        basedir=sys.argv[1]
    else:
        basedir='/usr/share/python-mecavideo/video'
    print "forward='f' backward='b' next='Esc'"
    cv.NamedWindow("Example2", cv.CV_WINDOW_AUTOSIZE)
    os.path.walk(basedir, showMovies, None)
    cv.DestroyWindow("Example2")
