互聯(lián)網(wǎng)網(wǎng)站建設(shè)制作中國(guó)最好的網(wǎng)絡(luò)營(yíng)銷(xiāo)公司
? ? ? 有一個(gè)視頻如a.mp4,此視頻采用幀率為30生成,共有299幀,這里通過(guò)FFmpeg命令分隔成1秒一個(gè)個(gè)的小視頻,即每個(gè)小視頻幀數(shù)為30幀。
? ? ? 用到的FFmpeg參數(shù)如下所示:
? ? ? (1).-i:指定輸入視頻文件的名稱(chēng);
? ? ? (2).-c:指定編解碼器;copy是一個(gè)特殊編解碼器,它直接復(fù)制輸入流到輸出流中,不會(huì)改變其內(nèi)容,不進(jìn)行重新編碼;指定copy可保持質(zhì)量,進(jìn)行無(wú)損復(fù)制;
? ? ? (3).-map:指定輸入文件的映射;指定輸入文件的索引號(hào)或名稱(chēng),索引號(hào)從0開(kāi)始,可以是多個(gè)輸入文件中的一個(gè);
? ? ? (4).-segment_time:指定每個(gè)輸出文件的時(shí)長(zhǎng),默認(rèn)值為2秒;注意:僅使用此參數(shù)有時(shí)可能分隔不準(zhǔn)確;
? ? ? (5).-reset_timestamps:在每個(gè)視頻段的開(kāi)頭重置時(shí)間戳;它的目的是簡(jiǎn)化生成的視頻段的播放;它為bool類(lèi)型,默認(rèn)為0;
? ? ? (6).-g:設(shè)置幀率,指定每秒視頻中包含的幀的數(shù)量,會(huì)影響視頻的播放速度;或用于設(shè)置GOP(group of picture)大小,即用來(lái)設(shè)置多少幀插入一個(gè)關(guān)鍵幀(I幀);
? ? ? (7).-sc_threshold:場(chǎng)景切換閾值(scene change threshold),默認(rèn)值為0;這個(gè)閾值的設(shè)定會(huì)影響到關(guān)鍵幀的插入頻率,較小的閾值會(huì)導(dǎo)致更頻繁地插入關(guān)鍵幀,而較大的閾值則會(huì)減少關(guān)鍵幀的插入;
? ? ? (8).-f:force format,后跟segment用于將多媒體數(shù)據(jù)流分隔成多個(gè)獨(dú)立的輸出文件;
? ? ? (9).-segment_time_delta:用于設(shè)置分隔時(shí)間的近似值;在選擇分隔的開(kāi)始時(shí)間時(shí)指定準(zhǔn)確時(shí)間,默認(rèn)值為0;此選項(xiàng)在分割視頻內(nèi)容時(shí)非常有用,視頻內(nèi)容始終在GOP邊界處分割,以防在指定分割時(shí)間之前找到關(guān)鍵幀;
? ? ? 當(dāng)指定delta時(shí),如果關(guān)鍵幀(key-frame)的PTS(Presentation Time Stamp, 音視頻幀在時(shí)間軸上的展示時(shí)間點(diǎn),它通常以毫秒為單位,表示從文件開(kāi)始播放到當(dāng)前幀的時(shí)間間隔)滿(mǎn)足以下關(guān)系,則關(guān)鍵幀將開(kāi)始一個(gè)新的分隔:
? ? ? PTS >= start_time - time_delta
? ? ? (10).-loglevel:用于控制日志的詳細(xì)程度;后可跟的參考可為:quiet:只顯示致命錯(cuò)誤;fatal:顯示致命錯(cuò)誤和錯(cuò)誤;debug:顯示調(diào)試信息;等
? ? ? (11).output%03d.mp4:輸出文件命名格式,其中%03d是一個(gè)占位符,用于生成具有三位數(shù)字編號(hào)的文件名,如生成的視頻文件,依次為output000.mp4, output001.mp4...
? ? ? 執(zhí)行分隔的命令如下所示:
ffmpeg -i a.mp4 -c copy -map 0 -segment_time 1 -segment_time_delta 9999999 -reset_timestamps 1 -g 30 -sc_threshold 0 -loglevel debug -f segment output%03d.mp4
? ? ? 執(zhí)行結(jié)果如下圖所示:
? ? ? 分隔正確與不正確時(shí)輸出信息對(duì)比如下:還沒(méi)有分析出對(duì)segment_time_delta設(shè)置不同的值會(huì)產(chǎn)生不同結(jié)果的原因:a.mp4共299幀,不添加segment_time_delta參數(shù),第一個(gè)分隔的視頻為60幀;添加此參數(shù),當(dāng)值很小時(shí),還是第一個(gè)分隔的視頻為60幀;當(dāng)此值設(shè)為0.05時(shí),第二個(gè)分隔的視頻為60幀;當(dāng)此值設(shè)為0.1時(shí),第四個(gè)分隔的視頻為60幀;當(dāng)此值設(shè)為0.2時(shí),第7個(gè)分隔的視頻為60幀;當(dāng)此值設(shè)為0.25時(shí),第8個(gè)分隔的視頻為60幀;當(dāng)此值設(shè)為0.27時(shí),第9個(gè)分隔的視頻為59幀;當(dāng)此值為0.3時(shí),可完全正確分隔;當(dāng)此值很大時(shí),如為9999999,也可完全正確分隔。
? ? ? 獲取每個(gè)視頻的總幀數(shù)的腳本show_video_frames_number.sh如下:
#! /bin/bashif [ $# != 1 ]; thenecho "it takes an input parameter: mp4 video file directory"
fitmp_file=tmp.txt
find $1 -name "*.mp4" > ${tmp_file}while IFS='' read -r line || [[ -n "$line" ]]; doecho -n "video file: ${line}: "./ffprobe.exe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 ${line}sleep .2
done < ${tmp_file}rm ${tmp_file}
? ? ? 當(dāng)segment_time_delta分別設(shè)置為0.2和0.3時(shí)分隔的結(jié)果如下所示:
? ? ? 注:
? ? ? (1).通過(guò)執(zhí)行:ffmpeg.exe -h full ,可獲取每個(gè)參數(shù)的介紹;
? ? ? (2).可在https://ffmpeg.org/ffmpeg-formats.html 中查看參數(shù)的詳細(xì)介紹。
? ? ? GitHub:https://github.com/fengbingchun/OpenCV_Test