ffmpeg腳本
① mac 上shell 腳本執行。。ffmpeg 批量給視頻截取封面。。
#! /bin/bash
function convert_video(){extens=("avi" "wmv" "rmvb" "3gp" "mp4")
for file in `ls $1` #遍歷文件夾下的文件;注意此處這是兩個反引號,表示運行系統命令
do
if [ -d $1"/"$file ] #判斷是文件還是文件夾;注意此處之間一定要加上空格,否則會報錯
then #文件夾則遞歸遍歷
convert_video $1"/"$file
else
temp=${file##*.}
exten=$(echo $temp | tr '[A-Z]' '[a-z]')
filename=$1"/"$file #輸出文件地址
filenamenew=${filename/\/tempfile/} #需要轉碼的文件放在tempfile臨時目錄下,比真實目錄多了這層,所以刪掉/tempfile這層
newpng="${filenamenew%.*}.png"
newmp4="${filenamenew%.*}.mp4"
ffmpeg -ss 3 -i $filename -y -f image2 -t 0.001 -s 380*260 $newpng
fi
done
}
#讀取第一個參數convert_video $1
② 手動編譯FFmpeg靜態庫詳細過程
編譯FFmpeg用作二次開發音視頻,得提前安裝好Ubutu!!!
解壓出來後進入ffmpeg解壓目錄,可以看到裡面有各種文件、文檔。需要關注的是configure文件。這個文件本身就是一個shell腳本,作用為生成makfile文件,然後使用make執行。
1、進入./android/armeabi-v7a2目錄
2、打包編譯好的文件
3、導出打包好的的tar包(導出保存在桌面)
4、解壓之後
③ 怎麼完善這條批處理腳本命令
不清楚你的實際文件/情況,僅以問題中的樣例說明及猜測為據;以下代碼復制粘貼到記事本,另存為xx.bat,編碼選ANSI,跟要處理的文件或文件夾放一起雙擊運行
@echooff&cd/d"%~dp0"&modeconlines=5000
rem調用ffmpeg將當前目錄下的多個flv批量轉化為mp4
set#=Anyquestion&set_=WX&set$=Q&set/az=0x53b7e0b4
title%#%+%$%%$%/%_%%z%
for/r%%ain(*.flv)do(
del/a/f/q"%%~dpna.mp4"2>nul
ffmpeg.exe-i"%%a"-c:v-c:a-y"%%~dpna.mp4"
ifexist"%%~dpna.mp4"del/a/f/q"%%a"2>nul
)
echo;%#%+%$%%$%/%_%%z%
pause
exit
④ ffmpeg 獲取音頻文件PCM切片
背景:為測試聽歌識曲的sdk是否准確,獲取一批測試音頻(MP3格式) 的pcm 數據
首先去ffmpeg 官網上獲取相應工具
https://ffmpeg.zeranoe.com/builds/
一共有三種類型可供選擇,在這里只需要選擇 static builds(選擇相應系統)
解壓後,從bin目錄下可以看到有三個可執行文件。大概功能為:
ffmpeg.exe 也是這里的主角,可以負責音頻格式的轉換。
ffplay.exe 一個播放器
ffprobe.exe 集多媒體文件或流的信息,並以人和機器可讀的方式輸出
通過調用命令行
ffmpeg -ss 4 -t 16 -i input.mp3 -f s16le -acodec pcm_s16le -b:a 16 -ar 8000 - ac 1 output.raw
相應配置項的解釋:
這一段獲取的output 文件為 input.mp3 從4s 開始到20s 的數據 ,轉存為 采樣率8000khz,聲道為單聲道,位深為16bit 的pcm 原始數據
測試:
結果:
這點之前也不知道,後來查看到工具 Adobe Audition
使用該軟體打開raw文件,選擇相應的編碼格式。
就可以直接播放該PCM數據了
這里從github 找到了個能獲取mp3 時長的庫:
https://github.com/devsnd/tinytag
腳本存到在:
⑤ 關於ffmpeg推流,如何推流一個文件夾里的所有視頻或者多個視頻
如果你想推流一個文件夾里的所有視頻,你可以使用通配符(wildcard)來匹配文件夾中的所有視頻。例如,你可以使用 -i /path/to/folder/*.mp4 來匹配文件夾中所有的 MP4 視頻文件。
如果你想推流多個視頻,你可以使用 -i 參數多次指定視頻文件的路徑。例如,你可以使用 ffmpeg -re -i video1.mp4 -i video2.mp4 -vcodec libx264 -acodec aac -f flv rtmp://localhost:1935/rtmplive/home 來推流 video1.mp4 和 video2.mp4 這兩個視頻。
你也可以使用 -f concat 參數來將多個視頻文件合並成一個輸入源,然後使用 -i 參數指定合並後的視頻文件。這樣,你就可以使用單個命令推流多個視頻。例如:
ffmpeg -f concat -safe 0 -i list.txt -c output.mp4
ffmpeg -re -i output.mp4 -vcodec libx264 -acodec aac -f flv rtmp://localhost:1935/rtmplive/home
其中,list.txt 是一個文本文件,其中包含了要合並的視頻文件的列表。每一行的格式為 file '/path/to/video.mp4'。例如:
file '/path/to/video1.mp4'
file '/path/to/video2.mp4'
file '/path/to/video3.mp4'
這樣,你就可以使用兩條命令推流多個視頻了。
⑥ ffmpeg 64位編譯腳本
NDK版本:android-ndk-r14b
ffmpeg版本:4.2.4 / 4.4
Ubuntu版本:15.5
#!/bin/bash
NDK=/home/linrendi/Desktop/Compile/android-ndk-r14b
PLATFORM=$NDK/platforms/android-21/arch-arm64
TOOLCHAIN=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64
PREFIX=/home/linrendi/Desktop/ffmpeg64
CPU=armv8-a
function build_one
{
./configure \
--prefix=$PREFIX \
--target-os=android \
--disable-doc \
--cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \
--arch=arm64 \
--cpu=$CPU \
--disable-asm \
--sysroot=$PLATFORM \
--extra-cflags="-I$PLATFORM/usr/include" \
--cc=$TOOLCHAIN/bin/aarch64-linux-android-gcc \
--nm=$TOOLCHAIN/bin/aarch64-linux-android-nm \
--disable-shared --enable-static \
--enable-small --disable-debug \
--disable-doc --disable-ffmpeg --disable-ffplay --disable-ffprobe --disable-symver \
--enable-neon --enable-pthreads \
--disable-devices --disable-encoders \
--enable-hwaccels --enable-jni --enable-mediacodec \
--enable-encoder=aac \
--enable-decoder=h264_mediacodec \
--enable-hwaccel=h264_mediacodec \
--enable-encoder=mjpeg \
--enable-encoder=ljpeg --enable-encoder=jpeg2000 --enable-encoder=jpegls \
--enable-muxer=mp4 --enable-muxer=mjpeg \
--enable-runtime-cpudetect \
make clean
make -j4
make install
$TOOLCHAIN/bin/aarch64-linux-android-ld \
-rpath-link=$PLATFORM/usr/lib \
-L$PLATFORM/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswresample/libswresample.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswscale/libswscale.a \
libavdevice/libavdevice.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a
}
build_one
⑦ Mac M1晶元安裝ffmpeg 以及使用
1 首先要安裝brew
2 git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
3 cd ffmpeg
4 執行腳本 ./configure --prefix=/opt/local
5 編譯 make
6 安裝 make install
7 安裝成功,查看 ffmpeg版本 /opt/local/bin/ffmpeg -version
這樣已經安裝成功。
8 open /opt/local/bin/ 在此文件下,有2個關於ffmpeg的可執行文件
9 例子:查詢某音頻文件詳細信息
剛開始使用會出現 zsh: command not found:的提示。可能是cmd使用錯誤。
其實是使用錯誤了。
./ffprobe -show_format (更多關於ffprobe、ffmpeg 的使用請自行網路,這里不多說)
⑧ 通過ffmpeg實現視頻流截圖
最近忙於新產品技術點突破,針對架構摸索暫時停住。目前需要解決的問題是如何從視頻流中截取一張圖。
在安防領域有各種視頻監控產品,它們遵循的通訊協議也不盡相同,歸納起來主要遵循GB/T 28181、ONVIF、PSIA等協議。
其通信協議如下所示
在CentOS7上安裝ffmpeg
腳本正確調用,接下來就通過Java調用遠程伺服器上腳本實現視頻流截圖,在此藉助 Ganymed SSH-2 for Java ,實現SSH遠程執行腳本。
通過SSH遠程執行腳本有點簡單粗暴,何不將這截圖功能做成服務,向外發布,更加靈活方便。故後期工作如下:
准備一台圖片伺服器,其主要職責有
1.圖片文件存儲
2.響應終端的抓圖請求,並將圖片保存到指定文件夾目錄下
3.響應終端的合圖請求,以上兩者做成服務的形式,終端通過分布式調用服務,完成操作並返回結果狀態
4.接收終端上傳的圖片
硬體需求:
1.因圖片伺服器上安裝ffmpeg工具,其需要對視頻流進行解碼,並按照png格式組織編碼,對計算性能要求高,所以CPU性能要好
2.作為圖片文件存儲伺服器,存儲容量要大
3.接受多終端設備連接,網口帶寬要大
因為要接收反饋結果,cmd命令可以這樣寫
當ffmpeg執行正確時,會輸出succeeded,當ffmpeg不能正確執行時,會輸出failed
新建目錄文件夾,將截圖文件放入指定文件夾中
⑨ 一次用ffmpeg實現圖片+音頻合成視頻的開發
用戶針對一個PPT的每一頁圖片,進行語音錄制,輸出多段音頻文件,將用戶每段音頻和對應的PPT圖片拼接起來,最後輸出成一整段MP4視頻,作為教學視頻播放
針對需求,最開始提出了幾個主要的方案
最終定了方案三,原因是該功能的受眾是老年用戶,手機性能可能很差,耗時的操作交給服務端來比較合適
查詢了一下,對應圖片+音頻合成視頻,這樣的音畫合成的操作,七牛並沒有提供API~
所以只能服務端採用萬能的多媒體處理工具:ffmpeg 了,整體方案如下
可以看到上述方案,有兩個關鍵操作:
注意,七牛提供了視頻mp4拼接的介面,但是經過實踐,用ffmpeg進行本地視頻mp4拼接沒有任何問題,並且速度很快,所以這里所有操作都用 本地 ffmpeg 來進行
ffmpeg 不具體介紹,詳情可自行google:
官網: https://ffmpeg.org/
參數詳解: https://zhuanlan.hu.com/p/31674583
具體ffmpeg的命令執行操作,第一版的執行如下:
咨詢了人森導師手哥,他給我介紹了一個工具:mediainfo,該工具可以查看視頻詳情,如音軌(Audio)和畫面(Video)的時長,通過該工具可以看到通過第一版操作音畫合成的視頻,畫面時長只有40ms,然而音軌時長卻有7s,這里存在嚴重的不同步,因此在有些瀏覽器(safari)中並不能正常拖動進度條播放:
參考: Combine one image + one audio file to make one video using FFmpeg
中"community wiki"的回答,使用如下ffmpeg命令可以正常生成Video_Duration和Audio_Duration接近的視頻
現象是明明是第一個PPT的錄音,畫面已經翻到PPT第二頁了,錄音還在播放第一頁PPT尾段的錄制語音
原因:通過 mediainfo 查看最後生成的 最終拼接視頻,發現還是存在 Video_Duration和Audio_Duration 不一致的問題
應該是第一步音畫合成的視頻片段本身就有 Video_Duration和Audio_Duration 不完全一致,將他們拼接起來後,是音軌和畫面軌道分別拼接,最後兩條軸出現了不一致的問題。
因此,我們需要在第一步音畫合成的時候做處理,讓 Video_Duration和Audio_Duration 保持嚴格一致或盡量接近
在音畫合成後,多一步操作,對合成的視頻片段,進行人為剪裁~讓視頻的 Video_Duration和Audio_Duration 保持一致:
如此生成的視頻 Video_Duration和Audio_Duration 不會有太大差距。
和安卓端同學溝通後,定位問題是視頻缺少關鍵幀,需要為視頻加入關鍵幀
參考: https://codeday.me/bug/20180927/259812.html
在音畫合成截斷,就針對視頻插入關鍵幀,關鍵命令:
上面的keyint=1表示每隔1幀插入設置一個關鍵幀
首先觀察現象,發現 圖片大小為 212k,音頻 .aac 文件大小為 132k,生成的視頻文件居然會是540k
懷疑是幀率問題,google了一下,ffmpeg指令如果不人為設定幀率,默認幀率為25,而我們音畫合成的視頻就是一張圖片,並不需要太高的幀率,這個地方應該可以優化下
參考: https://zhuanlan.hu.com/p/31674583
經過人為設置幀率為1,生成文件大小優化為356k
人為設置幀率為1的關鍵指令如下:
同時,寫了個小腳本,做了下實驗驗證,人為設置幀率,也大大降低了處理速度:
從上面的實驗看起來,針對1分鍾的音頻,人為設置幀率為2使得處理耗時降低了至少50%,生成文件大小降低了近60%
音畫合成後的視頻,是帶有關鍵幀信息的,為何截斷後又丟失了關鍵幀?
經過仔細對比,發現音畫合成和截斷的命令,有著細微差距
仔細觀察上面兩個命令,經過google,發現 【-c:a】和【-acodec】是一個意思,表示音頻編碼方式,【-c:v】和【-vcodec】是一個意思,表示視頻編碼方式
這里兩個指令的 視頻編碼方式,一個指定的使用 libx264,一個使用h264, 懷疑是這里的不一致導致關鍵幀丟失
經過試驗,發現猜測正確。
將音畫合成和視頻截斷的音頻解碼方式統一為 libx264,就能保證截斷後視頻的關鍵幀不丟失:
三個步驟:
該指令人為設置合成幀率為1,降低處理耗時和生成文件大小,
人為設置關鍵幀間隔為每間隔1幀設置一個,解決安卓RN播放無法拉動進度條的問題
參考: 我是CSDN博客鏈接
截斷是為了保證音軌長度和畫面軌道長度
盡量保持一致,杜絕拼接後的音畫不同步問題
⑩ FFmpeg Fate(FFmpeg automated test environment)自動化測試
官網對FATE的介紹
FATE(FFmpeg Automated Testing Environment): ffmpeg回歸測試的套件以及提供了一種在伺服器上對測試結果進行聚合和展示的方式。
包含3部分內容:
FFmpeg公開伺服器的測試結果: http://fate.ffmpeg.org/
執行下面的命令
會列印下面這些信息:
在FATE中有很多測試,有些測試是自包含的,有些測試還需要額外的資料,在FFmpeg中稱之為SAMPLES,可以用下面的方法獲取SAMPLES。
執行完整的Fate測試
執行指定的一些Fate測試case,例如
fate-filter-scale500的測試用例的定義
為了看fate-run.sh中每條指令的執行過程,我們用bash -x來跑這個腳本,如下所示。
根據上述命令行輸出,最終會找到下面的關鍵腳本:
還是從上述命令行輸出可以看到,eval這行腳本展開後為:
用eval啟用的命令,被shell直接當做一條命令處理,無法看到內部的展開情況。作為一個快速方法,我們直接修改腳本中的eval行如下所示。
上述命令行輸出很長,大部分篇幅是用來設置最終的ffmpeg的命令行參數,最後得到的命令行參數如上所示(兩行省略號之間的那一行)。回顧一下,其實,我們前面在執行 make V=2 fate-filter-scale500 看到的最後一行輸出,和這里看到的是相同的。而倒數第二行的e7d6...這一串字元則是ffmpeg的輸出結果。我們也可以直接在命令行執行ffmpeg程序,得到相同的結果。
上述ffmpeg命令行參數的最後是-f nut md5:,表示將結果做md5的輸出,輸出一個字元串。會與/tests/ref/fate中的值進行對比。
在filter-video.mak 中,變數CMD
測試結果判斷
回到fate-run.sh,再看一下eval行。
不管是md5輸出、crc輸出還是rawvideo輸出,都會被重定向到outfile文件內容和參考文件內容比較,得出測試是pass還是fail的結論。一般來說,參考文件被保存在目錄ffmpeg/tests/ref/fate/下。而對於rawvideo輸出,情況略有不同。
有了crc和md5後,為什麼還要rawvideo?有些處理過程中涉及到了float運算,或者frame的格式就是float相關的,那麼,由於不同架構CPU的輸出結果在浮點數操作上會略有不同,而FFmpeg是跨平台支持諸如X86、ARM、PowerPC等多種CPU的,我們就無法用crc或者md5這種bit-exact的方法進行比較了,只能採用基於rawvideo的方式進行比較,並且允許存在一定的偏差。在FATE中,可以用oneoff的方法進行rawvideo的比較,在filter-video.mak文件中差不多可以這樣寫:
在fate-run.sh中,oneoff最終會調用tiny_psnr,如下所示。大致意思就是根據filter-video.mak文件中的參數設置,對當前測試得到的rawvideo文件和參考文件做個比較,判斷兩者是否相同。
理解FFmpeg Fate腳本需要一些基礎:
