# ffmpeg-php + PHP5



## Skat0r (31. Oktober 2008)

Hallo,

ich habe ein kleines Problem mit der FFMPEG-PHP erweiterung. Soweit funktioniert das ganze eigentlich lediglich das beim erstellen eines Screenshots eines Frames bricht er ab und bringt folgenden Fehler.



> Fatal error: failed to convert frame to gd image in ... On line 8



Der passende PHP Code dazu:


```
<?php
$frame = 73;
$mov = new ffmpeg_movie(dirname(__FILE__) . '/test_media/robot.avi');
$img = sprintf("%s/test-%04d.png", dirname(__FILE__), $frame);

$ff_frame = $mov->getFrame($frame);
if ($ff_frame) {
    $gd_image = $ff_frame->toGDImage();
    if ($gd_image) {
        imagepng($gd_image, $img);
        imagedestroy($gd_image);
        // generate md5 of file (NOTE: different versions of ffmpeg may produce different
        // md5 hashes since resampling has been changed slightly due to a fix. Need to
        // use EXPECTREX to test for both md5 possibilities.
        printf("ffmpeg getFrame(): md5 = %s\n", md5(file_get_contents($img)));
        unlink($img);
    }
}
?>
```

Zeile 8 wäre dann $gd_image = $ff_frame->toGDImage(); . Bis auf das funktionieren eigentlich alle Funktionen von ffmpeg-php. Ich habe es auch schon mit verschiedenen anderen Versionen probiert aber bisher leider ohne Erfolg.

Noch ein Auszug aus der phpinfo:



> *ffmpeg*
> ffmpeg-php version 	0.6.0-svn
> ffmpeg-php built on 	Oct 30 2008 15:45:14
> ffmpeg-php gd support 	enabled
> ...



Ich hab auch schon gegoogelt und in der entsprechenden goolge Code Group geschaut aber bisher keine wirkliche Lösung gefunden. Ich hoffe ihr könnt mir da vllt. weiter helfen :/


----------



## Back2toxic (31. Oktober 2008)

Vielleicht solltest du mal die Funktion toGDImage posten.
Aber dran denken: Quelle und Copyright dazu


----------



## Skat0r (31. Oktober 2008)

Die Funktion steckt in der ffmpeg_movie Klasse (Von ffmpeg-php) welches als php Extension geladen wurde. Sprich schon kompiliert ist


----------



## Back2toxic (31. Oktober 2008)

Ach, erst denken, dann posten.. *wallbash*
Sorry 

Der Aufruf und der vorhergehende Code ist laut API korrekt.

PHP-Version >= 4.3.0?
Eher unwahrscheinlich, dass das Problem hier liegt, aber ausgeschlossen wurde es noch nicht.


----------



## Skat0r (31. Oktober 2008)

Wie im Titel steht arbeite ich mit PHP 5 um genau zusein mit "PHP Version 5.2.0-8+etch11"

Und ja, der Code sollte eigentlich stimmen. Ist 1zu1 aus deren Beispiel übernommen (Zum testen eben). Aber leider kommt dort dann halt jener Fehler der mich ein wenig verzweifeln lässt da alle anderen Funktionen gehen.


----------



## kalle123456 (31. Oktober 2008)

Ich denke die Funktion kommt mit den Framenummer nicht klar. Probiere es mal so, Pfade mußt du natürlich anpassen, ich habe es nur aus meiner Klasse rausgerissen . Wenn es klappt sollstest du ein Bild aus der Mitte des Videos bekommen.


```
if ($ff_frame) {
  $mov_img = new ffmpeg_movie(PFAD_ABSOLUT_ZUM_VIDEO);
   $framenumber = ($mov_img->getFrameCount() / 200) + 2;
   $ff_frame = $mov_img->getFrame($framenumber);
   $ff_frame->resize($mov_img->getFrameWidth(), $mov_img->getFrameHeight(), 10, 10, 10, 10);
    $gd_image = $ff_frame->toGDImage();
    if ($gd_image) {
       $img = 'Pfad zum Bild';
        imagepng($gd_image, $img);
        imagedestroy($gd_image);
        // generate md5 of file (NOTE: different versions of ffmpeg may produce different
        // md5 hashes since resampling has been changed slightly due to a fix. Need to
        // use EXPECTREX to test for both md5 possibilities.
        printf("ffmpeg getFrame(): md5 = %s\n", md5(file_get_contents($img)));
        unlink($img);
    }
}
```


----------



## Skat0r (31. Oktober 2008)

Kommt leider der gleiche Fehler :/ Auf die Idee bin ich ja auch schon gekommen und habe von frame 1 bis ~200 alles durch probiert. Aber leider immer ohne Erfolg.

Das ist echt ärgerlich den diese Screenshot funktion ist eigentlich das einzige was ich aus der Erweiterung wirklich brauche


----------



## kalle123456 (31. Oktober 2008)

Hmm bei mir geht es, hier mal der Link zum Bugtracker von PHP-FFmpeg, der führt genau zu deinen Problem.


----------



## kalle123456 (31. Oktober 2008)

Hast du die Zeilen in deinen Programm? Sonst wird es natürlich nichts , wichtig sind die letzen beiden.


```
extension_loaded('ffmpeg') or die("skip ffmpeg extension not loaded"); 
extension_loaded('gd') or die("skip gd extension not avaliable.");
function_exists("imagecreatetruecolor") or die("skip function imagecreatetruecolor unavailable");
```


----------



## Skat0r (31. Oktober 2008)

Jap habe ich  Und siehe PHP Info, geladen sind eigentlich alle Module korrekt.


----------



## kalle123456 (31. Oktober 2008)

Hier wurde dein Problem auch schon mal behandelt, vielleicht hilft es ja weiter.


----------



## Skat0r (31. Oktober 2008)

Leider nicht, den die entsprechende Zeile ist entweder schon auskommentiert (0.5.1 oder 0.5.0) oder existiert garnicht mehr (0.6.0)


----------



## kalle123456 (31. Oktober 2008)

Na dann wirst du wohl dein Problem im Bugtracker posten müssen. Mit der neuesten Version über SVN schon probiert oder woher holst die die Packages? Wenn du Debian hast, dann stelle deine Sourcelist auf stable und ziehe es über apt oder aptitude. So hat es bei mir zumindest immer funktioniert.


----------



## Ch (6. Februar 2009)

Hallo,

ich weiß ja nicht ob das Thema noch aktuell ist, aber ich hatte jetzt das selbe Problem. FFMPEG über svn ist nicht kompatibel zu PHP5-FFMPEG. 

Hier meine Lösung:

für FFMPEG habe ich die version genommen.
svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk/ ffmpeg -r14473

für FFMPEG-PHP die Version 0.5.3.1, aber auch die funktionierte erstmal nicht. Aber es gibt einen Patch. Hier gibt es die gepatchte Version zum download.


----------



## Skat0r (10. Februar 2009)

Das Thema ist noch mehr oder minder Aktuell. Ich hatte es irgendwann einfach aufgegeben  Aber ich schau mir das ganze nachher nochmal an, schon mal danke für  Deinen Post!


----------



## Ch (10. Februar 2009)

Hallo,

scheint ja doch einige noch zu interressieren. Nach langen experimentieren, habe ich mich jetzt entschlossen von Php5-ffmpeg weg zu kommen. Der Grund ist ziemlich einfach, ständige Abstürze der GD Klasse. Momentan bin ich auf der Suche, die Metadaten eines Videos mit Php auszulesen. Vielleicht hat jemand eine Idee, von der Sache her reichen Höhe, Breite und Abspiellänge.

Meine Videos und Vorschaubilder erstelle ich über die system($convertStr, $ret) von  php. Leider gibt FFmpeg nur im Fehlerfall was zurück. Ein "> log.txt" am Ende vom Convertstr. hat zwar die datei erstellt aber die Konsolenausgabe nicht reingeschrieben. Naja vielleicht habe ich da ja auch einen Denkfehler, weil das Skript rufe ich über cron über cli auf. Hier mal meine Convertstrings.

Video

```
//$format = $breite.'x'.$höhe -> in pixel, sollte vorher berechnet werden
// man könnte ein $format = $breite.'x' oder  $format = 'x'.$höhe ausprobieren, habe ich aber nicht gemacht. Bei imagick klappt es...
$convert_befehl = FFMPEG_BINARY.' -i '.$saves_pfad.$org_file_name.' -s '. $format . ' -ab 128k -ac 2 -ar 44100 -sameq -r 20 '. $saves_pfad.$neuer_file_name
```
Vorschaubild

```
//$zeit = Format 00:00:50 ->50sec
$convert_jpg_str = FFMPEG_BINARY.' -i '.$saves_pf.$neuer_file_name.' -an -ss '.$zeit.' -r 1 -vframes 1 -s '.$mov->getFrameWidth().'x'.$mov->getFrameHeight().' %d.jpg && mv 1.jpg '.$saves_pf.$img_name';
```

Wie gesagt noch brauche ich die Klasse, wegen den Metadaten. Hoffe nur bald nicht mehr. Wenn du animierte Gifs brauchst, erstelle temporär verschiedene Vorschaubilder, also von unterschiedlichen Frames und lasse sie durch Imagick zu einen Gif verarbeiten. Ungefähr so

```
$convert_gif_str = '/usr/bin/convert -delay 100 -loop 0 ';
foreach ($img_tmp_arr as $value){  // dass ist die Liste der Vorschaubilder
   $convert_gif_str .= ' '.$value.' ';
}
$convert_gif_str .= PFAD_ABSOLUT.$gif_name;
system($convert_gif_str, $ret);
```

Gruss


----------



## micronix (8. März 2009)

*Gelöst*

Da ich gerade selbst dass Problem hatte am 8 März 2009 um 05:24
habe ich dass Problem mit meinen guten C kenntnissen so gelöst
bitte diesen code mit der zeile /* {{{ _php_avframe_to_gd_image()
ersetzten


```
/* {{{ _php_avframe_to_gd_image()
 */
static int _php_avframe_to_gd_image(AVFrame *frame, gdImage *dest, int width, 
        int height)
{
    int x, y;
     int *src = (int*)frame->data[0];

    if (width > dest->sx || height > dest->sy)
    {
        return -1;
    }

     for (y = 0; y < height; y++) 
	 {
         for (x = 0; x < width; x++) 
		 {
           /* copy pixel to gdimage buffer zeroing the alpha channel */
           dest->tpixels[y][x] = src[x] & 0x00ffffff;
         }
         src += width;
     }
    return 0;
}
/* }}} */
```

Liebe Grüße 
Sascha


----------

