2012-09-27 10 views
6

Tôi đang cố gắng tạo hình thu nhỏ từ video bên ngoài, chủ yếu là MP4 và FLV. Tôi đang sử dụng FFmpegPHP. Tôi đã có thế hệ hình thu nhỏ làm việc tốt, tuy nhiên, tôi cần phải tải video hoàn toàn trên máy chủ của tôi trước tiên. Có thể chỉ phát một phần nhỏ của video sau đó trích xuất hình thu nhỏ từ đó không?FFmpegPHP lấy hình thu nhỏ từ URL bên ngoài

Dưới đây là đoạn code tôi có cho đến nay:

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

Bất cứ ai cũng có một gợi ý?

EDIT

Như Brad gợi ý, đây là mã Cập nhật:

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

Trả lời

3

FFMPEG là rất tốt về làm việc với những con suối bị hỏng. Bởi vì điều này, tôi nghĩ bạn nên thử tải xuống vài megs đầu tiên của phương tiện từ xa đó và cố gắng lấy một hình thu nhỏ từ tệp không hoàn chỉnh.

Trước tiên, hãy thả file_get_contents() và sử dụng cURL. Bạn có thể đặt tùy chọn CURLOPT_WRITEFUNCTION cho một chức năng tùy chỉnh của bạn ghi vào một tệp tạm thời trên đĩa, chunk theo đoạn. Khi bạn đã nhận đủ dữ liệu, hãy trả về 0 từ chức năng của bạn và cURL sẽ ngừng tải xuống. Bạn sẽ phải thử nghiệm để xem kích thước tối ưu là gì. Nếu bạn nhận được quá ít dữ liệu, bạn sẽ chỉ có các khung hình sớm nhất để hoạt động hoặc không có khung nào cả. Quá muộn, và bạn đang lãng phí băng thông.

Đối với một số loại vùng chứa, thông tin tệp ở cuối tệp. Đối với những người, tôi không có một gợi ý cho bạn. Viết ngắn của bộ giải mã của riêng bạn và nối trên các thông tin ở cuối với một cái gì đó từ đầu, tôi không biết một cách để làm điều đó mà không cần tải toàn bộ tập tin.

+0

Cho đến nay, tôi có thể trích xuất một hình ảnh thu nhỏ mà không cần phải tải về toàn bộ sự việc. Tuy nhiên, tôi đã hy vọng để có được khung giữa (ish) nếu có thể. Tôi chỉ có thể nâng cấp luồng của mình bằng cách nào đó và sau đó viết 0 cho đến khi tôi nhấn vào giữa luồng và chỉ nhận thông tin xung quanh luồng đó. Ngoài ra, có cách nào để tính toán bao lâu tôi cần phải tải về một tập tin để có được thông tin từ nó? – jValdron

+0

@jValdron, Đối với luồng MPEG, bạn thường có thể nhảy ngay ở giữa. Nhiều codec và vùng chứa khác cho phép giống nhau. Bạn có thể sử dụng một yêu cầu phạm vi để chỉ định những byte bạn muốn. Xem thêm: http://stackoverflow.com/a/8507991/362536 Hầu hết các máy chủ đều hỗ trợ nó. Để có được độ dài, bạn có thể thực hiện yêu cầu 'HEAD' (được hỗ trợ) hoặc' GET' và sau đó hủy sau khi bạn nhận được tiêu đề độ dài. – Brad

+0

Cảm ơn bạn đã dành thời gian cho Brad này. Bây giờ, tôi chỉ cần tìm ra cách để có được khung giữa :) – jValdron

0

chạy mã với PHP 5, ffmpeg và CURL với cấu trúc dựa trên lớp như sau:

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;