2012-09-27 14 views
6

Genellikle MP4 ve FLV gibi harici videolardan küçük resimler oluşturmaya çalışıyorum. FFmpegPHP kullanıyorum. Küçük resim nesli zaten çalışıyor, ancak önce videoyu tamamen sunucuma yüklemem gerekiyor. Videonun sadece küçük bir kısmını oynatmak mümkün mü yoksa küçük resmi oradan mı çıkarmak mümkün olabilir?FFmpegPHP, dış URL'den küçük resmi al

İşte kod var bugüne kadar var:

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'); 

Herkes bir önerisi var?

$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); 

cevap

3

FFMPEG kırık akışları ile çalışma hakkında çok iyidir:

DÜZENLEME

Brad öne sürdüğü gibi, burada güncellenen koddur. Bu yüzden, bu uzak medyanın ilk birkaç megasını indirmeyi denemelisiniz ve eksik dosyadan bir küçük resim elde etmeye çalışmalısınız.

İlk önce file_get_contents()'u bırakın ve cURL kullanın. CURLOPT_WRITEFUNCTION seçeneğini, diskte geçici bir dosyaya yazıp sizin için özel bir işlev olarak ayarlayabilirsiniz. Yeterli veri aldığınızda, işlevinizden 0'u döndürün ve cURL indirmeyi durdurur. Optimum boyutun ne olduğunu görmek için denemelisiniz. Çok az veri alırsanız, yalnızca en eski çerçevelerin çalışacağı veya hiç karesi olmayacak. Çok geç ve bant genişliğini harcıyorsun.

Bazı kapsayıcı türleri için, dosya bilgileri dosyanın sonundadır. Onlar için bir öneri yok. Kendi dekoderinizi yazmaktan ve en başından bir şeyle bilgi üzerine ekleme yapmaktan çok, tüm dosyayı indirmeden bunu yapmanın bir yolunu bilmiyorum. PHP 5, sınıf bazlı yapısı ile ffmpeg ve CURL ile kod çalıştıran

+0

Şimdiye kadar, hepsini indirmek zorunda kalmadan bir küçük resim elde edebilirsiniz. Ancak, mümkünse orta (ish) çerçeveyi almayı umuyordum. Akımımı bir şekilde ileri aktarabilirim ve akıntının ortasına gelene kadar 0 yazabilirim ve bunun hakkında bilgi alabilirim. Ayrıca, bir dosyadan bilgi almak için ne kadar süre indirmem gerektiğini hesaplamanın bir yolu var mı? – jValdron

+0

@jValdron, MPEG akışları için, genellikle sadece ortada atlayabilirsiniz. Diğer birçok codec ve konteyner aynı izin verir. İstediğiniz baytları belirtmek için aralık isteği kullanabilirsiniz. Ayrıca bkz: http://stackoverflow.com/a/8507991/362536 Çoğu sunucu bunu desteklemektedir. Uzunluğunu elde etmek için, "HEAD" isteği (desteklenen yerlerde) veya "GET" komutunu yapabilir ve uzunluk başlığını aldıktan sonra iptal edebilirsiniz. – Brad

+0

Bu Brad ile geçirdiğiniz zaman için teşekkürler. Şimdi, sadece orta kareyi nasıl alacağımı anlamaya ihtiyacım var :) – jValdron

0

aşağıdaki gibidir:

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;