Page 1 sur 1

Extraire une image de n’importe qu'elle vidéo ?

Publié : mer. 17/sept./2008 22:10
par meganet
Salut, je suis entrain de monter un projet de site, où les gens pourront posters leurs vidéos.
Et je doit pour cela pouvoir extraire la première image (de bonne qualité si possible) de la vidéo pour l'afficher en miniature, pour que quand le visiteurs clique dessus, la vidéo ce lance.
Ma question est la suivante : est-ce que quelqu'un sais comment extraire une image d'une vidéo de n’importe quel format soit en ligne de commande, soit avec une lib!
Je compte faire une extension PHP (si c’est une lib) pour pouvoir l'utiliser sur mon site (donc il me faudrait un code qui tourne sous linux).
Merci d’avance!!!

Publié : mer. 17/sept./2008 22:21
par Ar-S
Le problème de ce système est que la première image d'une vidéo est souvent noire.. Ou alors on voit TRISTAR PICTURE ou autre 20tf CENTURY et j'en passe... donc faut plutôt un logiciel pour capturer l'image choisit par l'utilisateur.
Pour linux je ne peux pas t'aider, sous windows, un simple lecteur comme media player classic te permet de capturer n'importe quelle image donc je me dis que sous linux, un player doit pouvoir aussi le faire.
Quand à PB pour faire cela.. surtout pour linux, je ne sais quoi te dire.

Publié : jeu. 18/sept./2008 6:38
par Stefou
Salut Meganet,

J'ai ce code, qui n'a pas fait toute ses preuves, mais bon cela pourrait peut être faire avancer le chmilblik...

Code : Tout sélectionner

#streamtypeVIDEO = $73646976 
#AVIGETFRAMEF_BESTDISPLAYFMT = 1 
#AVI_ERR_OK = 0 
#Lib = 0 

Procedure AVI2BMP ( avifile.s, bmpfile.s ) 
  *ptr.BITMAPINFOHEADER 
  bfh.BITMAPFILEHEADER 
  
  bmpdir.s = GetPathPart( bmpfile ) 
  bmpfile  = GetFilePart( bmpfile ) 
  
  res = CallFunction( #Lib, "AVIFileOpen", @pAVIFile, @avifile.s, #OF_SHARE_DENY_WRITE, 0 ) 
  
  If res = #AVI_ERR_OK 
    
    res = CallFunction( #Lib, "AVIFileGetStream", pAVIFile, @pAVIStream, #streamtypeVIDEO, 0 ) 
    If res = #AVI_ERR_OK 
      
      firstFrame = CallFunction( #Lib, "AVIStreamStart", pAVIStream ) 
      numFrames  = CallFunction( #Lib, "AVIStreamLength", pAVIStream ) 
      
      pGetFrameObj = CallFunction( #Lib, "AVIStreamGetFrameOpen", pAVIStream, #AVIGETFRAMEF_BESTDISPLAYFMT ) 
      
      For a = firstFrame To ( numFrames - 1 ) - firstFrame 
        *ptr = CallFunction( #Lib, "AVIStreamGetFrame", pGetFrameObj, a ) 
        If *ptr And OpenFile ( 0, bmpdir + Right("000" + Str(a), 4 ) + "_" + bmpfile ) 
          
          bfh\bfType = $4D42 
          bfh\bfSize = SizeOf(BITMAPFILEHEADER) + *ptr\biSize + *ptr\biSizeImage 
          bfh\bfReserved1 = 0 
          bfh\bfReserved2 = 0 
          bfh\bfOffBits = SizeOf(BITMAPFILEHEADER) + *ptr\biSize 
          
          WriteData( 0, @bfh, SizeOf(BITMAPFILEHEADER) ) 
          WriteData( 0, *ptr, SizeOf(BITMAPINFOHEADER) ) 
          WriteData( 0, *ptr+SizeOf(BITMAPINFOHEADER), *ptr\biSizeImage) 
          
          CloseFile (0) 
        EndIf 
      Next 
      CallFunction( #Lib, "AVIStreamGetFrameClose", pGetFrameObj ) 
    EndIf 
    CallFunction( #Lib, "AVIFileRelease", pAVIFile ) 
  EndIf 
  MessageRequester( "AVI2BMP", Str(numFrames) + " Frames extracted",  0 ) 
EndProcedure 
  
Procedure AVI2BMP_num_frame( avifile.s, bmpfile.s ,num_frame) 
  Debug "AVI2BMP_num_frame( avifile.s, bmpfile.s ,num_frame) "
  Debug avifile
  Debug bmpfile
  Debug num_frame
  *ptr.BITMAPINFOHEADER 
  bfh.BITMAPFILEHEADER 
  
  
  
  res = CallFunction( #Lib, "AVIFileOpen", @pAVIFile, @avifile.s, #OF_SHARE_DENY_WRITE, 0 ) 
  
  If res = #AVI_ERR_OK 
    
    res = CallFunction( #Lib, "AVIFileGetStream", pAVIFile, @pAVIStream, #streamtypeVIDEO, 0 ) 
    If res = #AVI_ERR_OK 
      
      firstFrame = CallFunction( #Lib, "AVIStreamStart", pAVIStream ) 
      numFrames  = CallFunction( #Lib, "AVIStreamLength", pAVIStream ) 
      If num_frame=-1
        num_frame=numFrames/2
      EndIf
      
      pGetFrameObj = CallFunction( #Lib, "AVIStreamGetFrameOpen", pAVIStream, #AVIGETFRAMEF_BESTDISPLAYFMT ) 
      
      
      
      *ptr = CallFunction( #Lib, "AVIStreamGetFrame", pGetFrameObj, num_frame ) 
      Debug *ptr 
      If *ptr And OpenFile ( 0, bmpfile ) 
        Debug "create fichier"
        bfh\bfType = $4D42 
        bfh\bfSize = SizeOf(BITMAPFILEHEADER) + *ptr\biSize + *ptr\biSizeImage 
        bfh\bfReserved1 = 0 
        bfh\bfReserved2 = 0 
        bfh\bfOffBits = SizeOf(BITMAPFILEHEADER) + *ptr\biSize 
        
        WriteData( 0, @bfh, SizeOf(BITMAPFILEHEADER) ) 
        WriteData( 0, *ptr, SizeOf(BITMAPINFOHEADER) ) 
        WriteData( 0, *ptr+SizeOf(BITMAPINFOHEADER), *ptr\biSizeImage) 
        
        CloseFile (0) 
      EndIf 
      
      CallFunction( #Lib, "AVIStreamGetFrameClose", pGetFrameObj ) 
    EndIf 
    CallFunction( #Lib, "AVIFileRelease", pAVIFile ) 
  EndIf 
  Debug "AVI2BMP : "+ Str(numFrames) + " Frames extracted"
  Debug avifile
  Debug bmpfile
EndProcedure 

Merci!

Publié : jeu. 18/sept./2008 10:38
par meganet
Salut, Ar-s: je sais bien ça, mais j'ai vue que mplayer pouvait extraire des images de bonnes qualité uniquement en laissant les autres de cotées.
Je vois arriver la question: pourquoi n'utilises-tu pas mplayer alors?
Parce-que il faut dire à mplayer jusqu'à quel endroit de la vidéo il doit extraire les images. Et si mon visiteur poste une vidéo en avi ou en mpeg ou en mp4 voir en flash, il faudrait que je sache récupérer le temps pour tous ces formats, pour pouvoir calculer après le temps d'un nombre d'images raisonnable pour que mplayer tombe sur une image de bonne qualité et encore c'est Aser aléatoire.
Stefou: merci pour ton code je vais regarder ça ce-soir, mais apparemment il faudrait une lib (je me trompe peut-être j'y est jeté un rapide coup d'œil rapidement j'aurais plus le temps ce-soir).
Merci à tous!