一、編碼方案
????????在視頻錄制時,每一幀保存為一個yuv文件,便于糾錯和修改。在編碼為MP4文件時,我的方案是將所有yuv文件先轉碼為單個MP4文件,然后使用ffmpeg的concat功能拼接為完整的視頻。
二、shell腳本
#!/bin/bash# 檢查參數數量是否正確
if [ "$#" -ne 5 ]; thenecho "Usage: $0 <directory> <width> <height> <FPS> <quality>"echo "quality : ultrafast superfast veryfast faster fast medium slow slower veryslow placebo"exit 1
fi# 將傳入的參數賦值給變量
# 使用雙引號將變量括起來,防止變量被shell解釋
DIRECTORY="$1"
WIDTH="$2"
HEIGHT="$3"
FRAMERATE="$4"
QUALITY="$5"# 輸入輸出格式
PIX_FMT="yuv420p"# 輸入文件名前綴
PREFIX="video_frame_"# 輸出文件名
OUTPUT_VIDEO="output.mp4"# 進入目錄
cd $DIRECTORY || exit 1# 清理文件列表
rm -f filelist.txt# 刪除臨時文件
rm -f temp_*.mp4# 使用for循環遍歷目錄中的YUV文件
for file in ./${PREFIX}*.yuv; do # 提取文件名(不帶擴展名) base=$(basename "$file" .yuv)# 設置輸出文件名output_temp="temp_${base}.mp4"# 不顯示輸出ffmpeg -s ${WIDTH}x${HEIGHT} -f rawvideo -pix_fmt $PIX_FMT -r $FRAMERATE -i "$file" -c:v libx264 -pix_fmt $PIX_FMT -frames:v 1 "$output_temp" > /dev/null 2>&1# 顯示輸出#ffmpeg -s ${WIDTH}x${HEIGHT} -f rawvideo -pix_fmt $PIX_FMT -r $FRAMERATE -i "$file" -c:v libx264 -pix_fmt $PIX_FMT -frames:v 1 "$output_temp"echo "file '$output_temp'" >> filelist.txt
done# 使用FFmpeg合并所有MP4文件
ffmpeg -f concat -safe 0 -i filelist.txt -c copy "$OUTPUT_VIDEO"# 檢查ffmpeg命令是否執行成功
if [ $? -eq 0 ]; thenecho "Success! Conversion completed: $OUTPUT_VIDEO"
elseecho "Error! Conversion failed."
fi# 刪除臨時文件
rm -f temp_*.mp4# 清理文件列表
rm -f filelist.txt
使用filelist.txt保存中間文件名,注意寫入格式,前面有一個file,這是concat功能的讀取格式。
每一項參數都可以查到,注意要加上 -frames:v 1,不加會報錯
三、總結
????????該方法為自身實驗并成功播放,用于提供思路,并不是最優解,還有很多可以優化的地方。
由于我是在開發板上運行的,所以編碼較慢。
放一張效果圖: