首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 從 FLV 檔案擷取預覽圖:FFmpeg 進階整合與參數解析

     編輯:PHP 相關知識

前言

FLV (Flash Video) 為舊式串流格式,仍有存量資產需處理。本文分析一個完整的 FLV 縮圖擷取腳本,支援時間點、百分比定位、直接輸出或儲存檔案,並修正原碼潛在問題。

完整功能腳本(修正版)

<?php
/**
 * FLV 影片縮圖擷取器
 * 參數:
 *   file   - FLV 檔案路徑 (必要)
 *   time   - 時間點 HH:MM:SS (預設 00:00:01)
 *   percent - 百分比 0-100 (優先於 time)
 *   browser - true 輸出圖片串流, false 儲存檔案
 */
$videofile = $_GET['file'] ?? 'video.flv';
$time      = $_GET['time'] ?? '00:00:01';
$percent   = isset($_GET['percent']) ? (float)$_GET['percent'] : null;
$browser   = ($_GET['browser'] ?? 'true') === 'true';

// 安全:限制存取目錄
$allowedDir = '/var/www/videos/';
$realVideo = realpath($videofile);
$realAllowed = realpath($allowedDir);
if (!$realVideo || strpos($realVideo, $realAllowed) !== 0) {
    http_response_code(403);
    exit('Forbidden');
}

// 百分比轉時間
if ($percent !== null) {
    $cmd = sprintf('ffprobe -v error -show_entries format=duration -of csv=p=0 %s', escapeshellarg($realVideo));
    $duration = (float) trim(shell_exec($cmd));
    if ($duration > 0) {
        $seekSec = $duration * $percent / 100;
        $time = gmdate('H:i:s', $seekSec);
    }
}

// 驗證時間格式
if (!preg_match('/^\d{2}:\d{2}:\d{2}$/', $time)) {
    $time = '00:00:01';
}

// 執行擷取
$codec = 'png'; // 或 mjpeg
$format = $browser ? 'image2pipe' : 'image2';
$output = $browser ? '-' : escapeshellarg(dirname($realVideo) . '/thumb_%d.' . $codec);

$cmd = sprintf(
    'ffmpeg -v 0 -y -i %s -ss %s -vframes 1 -vcodec %s -f %s %s',
    escapeshellarg($realVideo),
    escapeshellarg($time),
    $codec,
    $format,
    $output
);

if ($browser) {
    header('Content-Type: image/' . $codec);
    passthru($cmd);
} else {
    shell_exec($cmd);
    echo "縮圖已儲存";
}
?>

關鍵修正點

  • 路徑遍歷防護:使用 realpath() 驗證檔案在允許目錄內。
  • ffprobe 替代 ffmpeg 取得長度:ffprobe 專門讀取中繼資料,速度快、輸出穩定。
  • 移除 split():原碼使用已移除的 split(),改用 explode() 或 sscanf()。
  • 統一 escapeshellarg:所有外部參數必須跳脫。
  • 輸出格式修正:image2pipe 輸出 stdout,image2 輸出檔案序列。

效能優化建議

  • -ss 放在 -i 前面(輸入前 seek):ffmpeg -ss 00:00:10 -i input.flv ... 速度極快(關鍵幀定位),但可能不精確。
  • -ss 放在 -i 後面(輸出 seek):精確但需解碼前段畫面,較慢。
  • 生產環境建議:關鍵幀快速定位 + 微調,或預先生成縮圖陣列(每 N 秒一張)。

總結

FLV 縮圖擷取核心同一般影片,重點在於參數安全、路徑驗證、ffprobe 取得長度、非同步架構。修正舊碼相容性問題後可穩定運行。希望本文對您的 PHP 程式設計有所幫助。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved