6

私は外部のビデオ、主にMP4とFLVからサムネイルを作成しようとしています。私はFFmpegPHPを使用しています。サムネイルの生成はすでに正常に機能していますが、最初にビデオをサーバーに完全にロードする必要があります。ビデオのごく一部だけをストリーミングして、そこからサムネイルを抽出することは可能でしょうか?

これが私がこれまでに持っているコードです:

require_once PRIV . 'Vendor/FFmpegPHP/FFmpegAutoloader.php';

// Download the whole video.
$video = file_get_contents($_PUT['video']);
$file = 'path_to_cache';
file_put_contents($file, $video);

$movie = new FFmpegMovie($file);

// Generate the thumbnail.
$thumb = $movie->getFrame($movie->getFrameCount() / 2);
$thumb->resize(320, 240);
imagejpeg($thumb->toGDImage(), 'path_to_thumb');

誰か提案がありますか?

編集

ブラッドが提案したように、更新されたコードは次のとおりです。

$file = CACHE . 'moodboard_video_' . rand();
$fh = fopen($file, 'w');
$size = 0;

curl_setopt($ch, CURLOPT_URL, $_PUT['video']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) use($fh, &$size){
    $length = fwrite($fh, $data);

    if($length === FALSE) {
        return 0;
    } else {
        $size += $length;
    }

    // Downloads 1MB.
    return $size < 1024 * 1024 * XXXXXX ? $length : 0;
});

curl_exec($ch);

fclose($fh);
curl_close($ch);

// Create the thumbnail.
$thumb = $movie->getFrame(XXXXXX);
$thumb->resize(static::DEFAULT_THUMBNAIL_WIDTH, $thumb->getHeight() / $thumb->getWidth() * static::DEFAULT_THUMBNAIL_WIDTH);
$image = $thumb->toGDImage();
imagejpeg($image, PRIV . static::THUMBNAILS_PATH . $item->getLastInsertIdentifier() . '_' . static::DEFAULT_THUMBNAIL_WIDTH);
4

2 に答える 2

3

FFMPEGは、壊れたストリームの処理に非常に適しています。このため、そのリモートメディアの最初の数メガバイトをダウンロードして、不完全なファイルからサムネイルを取得してみてください。

まず、file_get_contents()cURLを削除して使用します。CURLOPT_WRITEFUNCTIONオプションを、ディスク上の一時ファイルにチャンクごとに書き込むカスタム関数に設定できます。十分なデータを受け取ったら0、関数から戻ると、cURLはダウンロードを停止します。最適なサイズを確認するために実験する必要があります。取得するデータが少なすぎる場合は、処理する最も早いフレームのみが存在するか、フレームがまったく存在しません。手遅れで、帯域幅を浪費しています。

一部のコンテナタイプでは、ファイル情報はファイルの最後にあります。それらのために、私はあなたに提案を持っていません。独自のデコーダーを作成し、最後に情報を最初から何かでつなぎ合わせる以外に、ファイル全体をダウンロードせずにそれを行う方法がわかりません。

于 2012-10-01T13:45:51.933 に答える
0

PHP 5、ffmpeg、およびクラスベース構造のCURLでコードを実行すると、次のようになります。

require_once  'PHP_CURFN/ffmpeg-php-master/FFmpegFrame.php';
  require_once  'PHP_CURFN/ffmpeg-php-master/FFmpegAutoloader.php';

class MyVideoTest{

private $fh="";
private $size=0;
private $ch="";

public function __construct(){

                $video = 'http://[hosturl]/video/41a669911fd635167475d7530bffcc9f.mp4';
                $file = 'PHP_CURFN/cache/tmp_video_' . rand();


                $this->ch = curl_init();
                $this->fh = fopen ($file, 'w+');
                $this->ch = curl_init($video);

                $this->size = 0;
                curl_setopt($this->ch, CURLOPT_URL, $video);
                curl_setopt($this->ch, CURLOPT_HEADER, 0);


                curl_setopt($this->ch, CURLOPT_WRITEFUNCTION, array($this, "myfunction"));

                curl_exec($this->ch);

                fclose($this->fh);
                curl_close($this->ch);
                $movie = new FFmpegMovie($file);
                // Create the thumbnail.

                $thumb = $movie->getFrame(2);
                $thumb->resize(320, 240);
                $image = $thumb->toGDImage();
                imagejpeg($image, 'PHP_CURFN/cache' . $item->getLastInsertIdentifier() . '_' . 320);

}
function myfunction($ch, $data)     {
        $length = fwrite($this->fh, $data);
        $size=&$this->size;

        if($length === FALSE) {
            return 0;
        } else {
            $size += $length;
        }

        // Downloads 1MB.

        return $size < 1024 * 1024 *1 ? $length : 0;
} }


$MyVideoTest= new MyVideoTest();
pr($MyVideoTest);
exit;
于 2013-01-22T06:14:43.733 に答える