:::
11-4 上傳影片並產生縮圖
一、安裝所需環境
- 上傳影片必須要注意 php.ini 中的一些設定(一樣編輯php.ini,修改後重啟即可):
file_uploads=On:支持 HTTP 上傳upload_max_filesize=600M:允許上傳檔案容量的上限max_file_uploads=20:允許一次上傳的最大檔案數量post_max_size=620M:表單發送資料容量的上限(需>=upload_max_filesize)max_execution_time=300:設定程式被解析器終止之前允許的最大執行時間,防止程式寫得不好而耗盡伺服器資源,單位: 秒(-1 為不限制)。memory_limit=128M:一個 Web 請求,給予該執行緒記憶體使用量的上限。
- 要從影片擷取出圖檔,必須借助 FFMpeg 及 PHP-FFMpeg
- 請先安裝 FFMpeg,這裡以
https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z為例 - 下載後,解壓縮至專案目錄下的
ffmpeg目錄,像這樣:

- PHP-FFMpeg可透過Composer安裝之,按 Ctrl+` 開啟終端機,並貼上 :
composer require php-ffmpeg/php-ffmpeg
二、產生影片縮圖
- 先上傳影片後產生截圖,最後在產生縮圖即可。
- 產生縮圖的基本用法(這裡直接使用完整命名空間,所以無須事先
use),其中路徑的地方記得用絕對路徑:// 建立物件 $ffmpeg = FFMpeg\FFMpeg::create(array( 'ffmpeg.binaries' => _PATH . '/ffmpeg/bin/ffmpeg.exe', 'ffprobe.binaries' => _PATH . '/ffmpeg/bin/ffprobe.exe', 'timeout' => 3600, // 底層進程的時間上限 'ffmpeg.threads' => 12, // FFMpeg 應該使用的線程數 )); // 開啟影片 $video = $ffmpeg->open(影片檔來源); // 擷取第N秒的話格,並存檔 $video ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(秒數)) ->save(圖片位置及檔名); - 影片一律只接受
mp4,因為相容性最高 - 修改上傳部份如下:
// 依序讀出檔案 foreach ($_FILES['files']['name'] as $i => $filename) { ...略... // 檢查檔案是否上傳成功 if ($_FILES['files']['error'][$i] === UPLOAD_ERR_OK) { ...略... // 原圖欲放置到哪裡 $dest = _PATH . "/uploads/{$id}/{$prefix}-{$i}.{$ext}"; if ($ext == 'mp4') { // 縮圖欲放置到哪裡 $thumb_dest = _PATH . "/uploads/{$id}/thumbs/{$prefix}-{$i}.jpg"; // 將檔案移至指定位置 if (move_uploaded_file($file, $dest)) { // 物件設定 $ffmpeg = FFMpeg\FFMpeg::create(array( 'ffmpeg.binaries' => _PATH . '/ffmpeg/bin/ffmpeg.exe', 'ffprobe.binaries' => _PATH . '/ffmpeg/bin/ffprobe.exe', 'timeout' => 3600, // The timeout for the underlying process 'ffmpeg.threads' => 12, // The number of threads that FFMpeg should use )); // 開啟影片 $video = $ffmpeg->open($dest); // 擷取畫面 $video ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10)) ->save($thumb_dest); // 製作縮圖 $image = Image::make($thumb_dest)->resize(480, 480, function ($constraint) { $constraint->aspectRatio(); $constraint->upsize(); })->save($thumb_dest); } else { die("無法將檔案{$file}上傳至指定位置{$dest}"); } } else { ...略... } } else { die("上傳錯誤:{$_FILES['files']['error'][$i]}"); } }- 由於影片沒有所謂的原圖,只有原檔,所以,仍用
move_uploaded_file()的方式將影片移到上傳目錄下。

- 影片的縮圖一律為 jpg,因此,縮圖檔名部份的設定,我們依據副檔名不同,分開處理
- 可利用
TimeCode::fromSeconds(10)來設定要抓取第幾秒的畫面 - 抓到畫面後,用剛剛的縮圖工具來做縮圖

- 由於影片沒有所謂的原圖,只有原檔,所以,仍用
11-3 產生圖片縮圖