视频截取和队列处理的shell实现

来源:百度文库 编辑:神马文学网 时间:2024/04/27 22:52:49
视频截取和队列处理的shell实现大 |中 |小
[2007/06/05 21:07 | bywirlfly ]
经过一次不痛快的和他人合作之后,我写了这段shell脚本,主要用于视频文件的转换队列处理,和视频大文件的截取.涉及到诸如3gp,asf,wmv,avi,mp4,mpeg,mov,vob,rm,rmvb等格式的转换成flv,同时分段截取各种格式的大文件.主要采用的工具无非就是开源的ffmpeg,mencoder,MediaInfo,前两者转换和截取,后者获取视频元数据.多谢sleetdrop推荐.
对于视频文件的元数据而言,是否都存在都柏林元数据,特征元数据是否值得信赖是一个问题,因此在脚本中做了一些信任机制的处理,脚本写的很清晰,应该不是太难懂,而且里面都做了撇脚的英文注释.已经通过功能测试,至于压力测试,正在进行中.不过对于脚本运行环境,是在ffmpeg+mencoder环境下运行的,对于怎样搭建ffmpeg+mencoder,可以参考这篇文章.
可能会要应用于实际比较恶劣的情况中,因此还需要对代码进行改进,甚至可能要用到shc,日志功能和错误处理功能还要加强,还有就是根据不同格式和不同质量的视频文件,采用不同的方法进行转换也是在下一步策划之中.如果大家有什么更好的方法,或者对此进行了改进,请共享出来吧.
引用
#!/bin/bash
#
#file:  convert_videos.sh
#usage:
#desc:  convert many other formats of videos to flv format
#author:        Spark Zheng
#version:       V1.0
#date:  2007-05-31
declare -a video_format         #video formats
declare -a video_size           #video sizes
declare -a video_metadata       #array of the metadata geted by MediaInfo
declare -i flag                 #delay flag, wait for queue
declare -i file_size            #the video file size, we trust it!
VIDEO_IN_DIR=/home/zhengyu/video_again                                  #video queue dir
VIDEO_OUT_DIR=/home/zhengyu/flv                                         #the flv videos moved to
VIDEO_BAK_DIR=/home/zhengyu/video_bak                                   #video which has handled moved to, need?
VIDEO_FORMAT_FILE=/home/zhengyu/code/shell/convert_formats.list         #formats, just define it
VIDEO_SIZE_FILE=/home/zhengyu/code/shell/convert_sizes.list             #sizes, frame sizes, just define it
DEBUG=1                         #debug flag: 1 to debug, 0 to cancel
MediaInfo_dir=/usr/local/bin    #MediaInfo tool‘s dir
ffmpeg_dir=/usr/local/bin       #ffmpeg tool‘s dir
mencoder_dir=/usr/local/bin     #mencoder tool‘s dir
file_limit=10485760             #file size to check: 10M(10*1024*1024)
diff_time_max=600               #diff between caculate time and get time: 10 minute(600 second)
diff_time_min=-600              #same as diff_time_max
bit_rate_max=41943040           #trust when below the max bit rate: 40Mbps(40*1024*1024)
bit_rate_min=1024               #trust when over the min bit rate: 1Kbps(1*1024)
time_to_trucate=1800            #trucate the video when playtime is over: 30 minute(1800 second)
video_format=($(cat $VIDEO_FORMAT_FILE))
video_size=($(cat $VIDEO_SIZE_FILE))
flag=0                          #first init flag with 0
pid=$$
#####################functions start#############################
#function: get_metadata
#usage: fill the video_metadata array with useful arguments
#return: 0
function get_metadata()
{
#       video_metadata[0]=$(cat tmp|grep "PlayTime"|awk -F: ‘{if(NR==1) print $2}‘)
#       video_metadata[1]=$(cat tmp|grep "Bit rate"|awk -F: ‘{if(NR==1) print $2}‘)
#       video_metadata[2]=$(cat tmp|grep "File size"|awk -F: ‘{if(NR==1) print $2}‘)
#       video_metadata[3]=$(cat tmp|grep "Format"|awk -F: ‘{if(NR==1) print $2}‘)
#       video_metadata[4]=$(cat tmp|grep "Width"|awk -F: ‘{if(NR==1) print $2}‘)
#       video_metadata[5]=$(cat tmp|grep "Height"|awk -F: ‘{if(NR==1) print $2}‘)
#       video_metadata[6]=$(cat tmp|grep "Frame rate"|awk -F: ‘{if(NR==1) print $2}‘)
#you may add it like above, as an example.
video_metadata=($(awk -F: ‘BEGIN{PT=1;pt=0;BR=1;br=0;F=1;f=0;FMT=1;fmt="";W=1;w=0;H=1;h=0;FR=1;fr=0;}
{if(($0 ~ "PlayTime")&&(PT==1))
{PT=0; split($2,array," "); if(array[1]~"h"){pt+=3600*int(array[1]);} else if(array[1]~"mn") {pt+=60*int(array[1]);} else if(array[1]~"s") {pt+=int(array[1]);} if(array[2]~"mn") {pt+=60*int(array[2]);} else if(array[2]~"s") {pt+=int(array[2]);} }
if(($0 ~ "Bit rate")&&(BR==1))
{BR=0; split($2,array," "); if(array[2]~"Mbps") {br=1024*1024*int(array[1]);} else if(array[2]~"Kbps") {br=1024*int(array[1]);} else {br=int(array[1]);}}
if(($0 ~ "File size")&&(F==1))
{F=0; split($2,array," "); if(array[2]~"MiB") {f=1024*1024*int(array[1]);} else if(array[2]~"KiB") {f=1024*int(array[1]);} else {f=int(array[1]);}}
if(($0 ~ "Codec")&&(FMT==1))
{FMT=0; split($2,array," "); fmt=array[1];}
if(($0 ~ "Width")&&(W==1))
{W=0; split($2,array," "); w=int(array[1]);}
if(($0 ~ "Height")&&(H==1))
{H=0; split($2,array," "); h=int(array[1]);}
if(($0 ~ "Frame rate")&&(FR==1))
{FR=0; split($2,array," "); fr=int(array[1]);}}
END{print pt" "br" "f" "fmt" "w" "h" "fr;}‘ /tmp/$0.tmp))
return 0
}
#function: check_metadata
#usage: to decide the metadata we get by get_metadata() weather were trusted
#return: >0 not trusted, =0 trusted
function check_metadata()
{
if [ $DEBUG -gt 0 ]
then
echo ${video_metadata[0]}
echo ${video_metadata[1]}
echo ${video_metadata[2]}
echo ${video_metadata[3]}
echo ${video_metadata[4]}
echo ${video_metadata[5]}
echo ${video_metadata[6]}
echo ""
fi
#not trust bit rates
if [ ${video_metadata[1]} -gt $bit_rate_max -o ${video_metadata[1]} -lt $bit_rate_min ]
then
return 15
fi
diff_cacul=$(expr 8 \* $file_size / ${video_metadata[1]} - ${video_metadata[0]})
#not trust play times
if [ $diff_cacul -gt $diff_time_max -o $diff_cacul -lt $diff_time_min  ]
then
[ $DEBUG -gt 0 ] && echo "\$diff_cacul is $diff_cacul"
return 14
fi
#need to check the format?
return 0
}
#function: convert_video
#usage: use ffmpeg/mencoder to convert the videos, trucate videos when necessary
#return: 0
function convert_video()
{
if [ -z "$1" ]
then
return 13
fi
if [ -z "$2" ]
then
trucate_flag=0          #0 means not to trucate the video file
else
trucate_flag=$2
fi
#any other smart method to get the flv_file? another method is directly assigned with $1.flv,maybe better
#       flv_file=$(echo $1 | awk ‘{split($0,array,".");for(i in array) {;} array[i]=""; for(j in array) {if(j