1. 程式人生 > >FFMPEG轉碼及切片

FFMPEG轉碼及切片

由於優優好房上有些視訊需要批量切片,首先想到的就是FFmpeg。

一開始查閱了大量的部落格,論壇,文章,踩了很多坑,後面參照FFmpeg的編譯指南,搞定

在此就不贅述ffmpeg的安裝

http://trac.ffmpeg.org/wiki/CompilationGuide

我選擇的是centos

http://trac.ffmpeg.org/wiki/CompilationGuide/Centos

 

ffmpeg包括一組軟體,ffmpeg用於對媒體檔案進行處理,ffserver是一個http的流媒體伺服器,ffplay是一個基於SDL的簡單播放器。兩個庫檔案libavcodec和libavformat。

ffmpeg作為媒體檔案處理軟體,基本用法如下: 
ffmpeg [global_options] {[input_file_options] -i ‘input_file’} ... {[output_file_options] ‘output_file’} ...
輸入輸出檔案通常就是待處理的多媒體檔案了。可以是純粹的音訊檔案,純粹的視訊檔案,或者混合的。 
大部分常見的格式都能夠“通殺”。象常見的各種mpeg,AVI封裝的DIVX和Xvid等等

對ffmpeg命令選項的瞭解,先從下面的命令開始
ffmpeg -h
ffmpeg -h long
ffmpeg -h full
man ffmpeg需要安裝ffmpeg的手冊頁條目

各選項引數的解釋,詳情參見 http://www.ffmpeg.org/ffmpeg.html

在切片這塊:

ffmpeg -i 1.mp4 -f segment -segment_time 10 -segment_format mpegts -segment_list list_file.m3u8 -c copy -bsf:v h264_mp4toannexb -map 0 output_file-%d.ts

這條命令的限制是:要求生成ts分片的輸入視訊是視訊是h.264編碼,音訊是aac編碼的視訊檔案,從優酷網上下載的視訊片段都是符合這個條件的。

上面這段是網上看的,其中的bsf位元流過濾器設定是h264_mp4toannexb

,這個要求視訊是h.264編碼。否則後期切片就會很慢,畢竟需要進行轉碼。如果伺服器沒有顯示卡支援,通過硬轉碼會很耗時。

這個我們是在windows上進行h.264編碼,使用格式化工廠,然後再寫shell指令碼,批量切片,批量把一個目錄的視訊生成到另外一個目錄,並以視訊的檔名建立目錄儲存切片檔案,ffprobe獲取視訊資訊,對超過尺寸的視訊進行處理再切片,對沒有超過尺寸的視訊直接切片。

最後附上指令碼,希望對你有幫助

#!/bin/bash

deepcopydir(){  
    for file2 in `ls -a $1`  
    do  
        if [ x"$file2" != x"." -a x"$file2" != x".." ];then  
            if [ -d "$1/$file2" ];then  
                dirpath="$1/$file2"  
                #建立檔案
                mkdir -v ${dirpath/videodir/videom3u8}
                deepcopydir "$1/$file2"  
            fi  
        fi  
    done  
}

formatvideo(){
    for file2 in `ls -a $1`  
    do  
        if [ x"$file2" != x"." -a x"$file2" != x".." ];then  
            if [ -d "$1/$file2" ];then  
                formatvideo "$1/$file2"  
            elif [ -f "$1/$file2" ];then  
		videopath="$1/$file2"
                #獲取目錄
                dirpath=$(dirname $videopath)
                #獲取帶字尾檔名
                filename=$(basename $videopath)
                #字尾
                after=${filename##*.}
                #檔名
                name=${filename%.*}
                ##echo $videopath  $dirpath $filename $after $name
                m3u8file=${dirpath/videodir/videom3u8}
                mkdir $m3u8file/$name
                ##ffmpeg -i $videopath -c:v libx264 -c:a copy -f hls -threads 8 -hls_time 30 -hls_list_size 0 $m3u8file/$name/index.m3u8

                videoinfo=$(ffprobe -v quiet -print_format json -show_format -show_streams $videopath | jq '.streams[0]' )
                width=$(echo $videoinfo | jq '.width') 
                height=$(echo $videoinfo | jq '.height') 
                if [ $width -lt 960 -o $height -lt 540 ]; then 
                        echo "$width,$height"
                        ffmpeg -i $videopath -f segment -segment_time 5 -segment_format mpegts -segment_list $m3u8file/$name/index.m3u8 -c copy -bsf:v h264_mp4toannexb -map 0 $m3u8file/$name/index%d.ts 
                else 
                        echo "width=$width,height=$height"
                        ffmpeg -i $videopath -f segment -segment_time 5 -segment_format mpegts -segment_list $m3u8file/$name/index.m3u8 -c copy -bsf:v h264_mp4toannexb -map 0 $m3u8file/$name/index%d.ts 
                fi 
            fi  
        fi  
    done  
}

root='/tmp/'
olddir="${root}videodir"
newdir="${root}videom3u8"
#初始化新的根目錄
mkdir -p $newdir
deepcopydir $olddir $newdir
#遍歷檔案編碼
formatvideo $olddir