目录

浅析计算广告

技术人生 X 人生技术

FFmpeg视频解码简单使用

这周主要在解决视频转码的问题,其实原本也没有什么问题,只是因为出现了部分开机视频文件在部分机器上卡死不能正常播放的问题,导致了外面一大批机器死机。对于一个做互联网电视的公司来说,电视死机那是致命的。所以最近才要严格限制视频格式以及进行主动转码测试验证,确保完全没问题的视频文件,才能进行投放。

ffmpeg 是一款免费的,高效的视频转码工具,网上关于 ffmpeg 的使用有很多的介绍,这里我就不提了(主要是我也不知道。。。(@ο@)~ 😁),可以参考 雷神 的技术博客。天妒英才,希望天堂没有代码,雷神走好。

这次的转码工具是 Linux 系统下的 sh 脚本,主要有两个部分

1、基本配置

基本配置主要根据项目的实际需求配置相应的参数,比如帧率,比特率,分辨率,时长,采样率,声道。。。具体数据就不对外公布了。

2、执行命令

 1echo "--------------------------------------"
 2echo "intput file         : "${infile}
 3echo "output file         : "${outfile}
 4echo "output file format  : "${outFormat}
 5echo "duration limit      : "${durationLimit}
 6echo "video mode          : "${videoMode}
 7echo "video codec         : "${videoCodec}
 8echo "video profile       : "${videoProfile}
 9echo "video level         : "${videoLevel}
10echo "video bitrate       : "${videoBitRate}
11echo "video Frame rate    : "${videoFrameRate}
12echo "video resolution    : "${videoResolution}
13echo "video aspect ration : "${videoAspectRation}
14echo "video ref frames    : "${videoRefFrame}
15echo "audio codec         : "${audioCodec}
16echo "audio profile       : "${audioProfile}
17echo "audio sampling rate : "${audioSamplingRate}
18echo "audio channels      : "${audioChannels}
19echo "--------------------------------------"
20command="./ffmpeg -i "${1}" -c:v "${videoCodec}" "${videoMode}" -refs "${videoRefFrame}" -b-pyramid none -profile:v "${videoProfile}" -level "${videoLevel}" -b:v "${videoBitRate}" -r "${videoFrameRate}" -s "${videoResolution}" -aspect "${videoAspectRation}" -c:a "${audioCodec}" -profile:a "${audioProfile}" -ar "${audioSamplingRate}"  -ac "${audioChannels}" -t "${durationLimit}" -f "${outFormat}" "${2}" -y"

通过以上方法转码后使用 MediaInfo 软件进行视频信息的查看,可以看到视频信息参数值都是转码后的值了。ffmpeg 的功能非常强大,这里使用的脚本是北京分公司那边提供的,在进行部分修改过后可以达到我们需要的要求。


上面的 shell 脚本可以根据指定参数进行视频的转码,但是有个小问题,就是每次只能转码一个视频,在视频资源很多的情况下。。。这将是个浩大的工程。所以在此基础上我写了个自动化脚本,回头只要执行这个自动化脚本就可以一次性转码多个视频。这个自动化脚本的功能很简单,就是把转码前文件夹里面的视频文件进行遍历转码,然后存放到转码后的文件夹里面,回头只要将需要转码的视频拷贝到转码前文件夹里面,运行自动化脚本就可以了。由于这个自动化脚本是我自己写的。。所以就可以简单粗暴的直接上代码了。。。。。。

 1#!/bin/sh
 2OLD_IFS=$IFS
 3IFS=$'\n'
 4videoResolution=1920x1080
 5audio=
 6function checkVideo()
 7{
 8   for line in `cat ../temp.txt`
 9   do
10    #时长
11    if [[ $line =~ "Duration" ]];then
12	echo $line >> string.txt
13	dura=`awk -F"," '{print $1}' string.txt | awk -F":" '{print ($4+0)}'`
14	rm -rf string.txt
15	if [ `expr "$dura" \< 15.1` -eq 0 ];then
16	  echo "---------->视频时间超出15秒..."
17	  exit 1
18	else
19	   echo "---------->视频时长为${dura}"
20	fi
21     fi
22     #分辨率
23     if [[ $line =~ "Video" ]];then
24	IFS=","
25	array=($line)
26	IFS=$'\n'
27	for i in ${array[@]}
28	 do
29	  if [[ $i =~ "1920x1080" ]];then
30	    videoResolution=1920x1080
31      	  elif [[ $i =~ "1280x720" ]];then
32	   videoResolution=1280x720
33	  fi
34	done
35      fi
36     #音频aac判断
37     if [[ $line =~ "Audio" ]];then
38	echo $line >> string.txt
39	audio=`awk -F":" '{print $4}' string.txt`
40	rm -rf string.txt
41	if [[ $audio =~ "aac" ]];then
42	   audio="aac"
43	else
44	   echo "---------->音频格式错误,应为aac..."
45	   exit 1
46	fi
47     fi
48     done
49}
50
51cd ./aftertrans
52echo "---------->正在清除aftertrans目录的数据..."
53rm -rf after_*
54echo "---------->数据清除完成..."
55cd ../beforetrans
56echo "---------->进入beforetrans目录..."
57rm -rf string.txt
58echo "---------->即将开始遍历文件进行转码操作..."
59for file in `ls`
60 do
61   temp_file=`basename $file`
62   echo "---------->输入文件:$temp_file"
63   echo "---------->输出文件:./aftertrans/after_$temp_file"
64   echo "---------->当前检测文件:$temp_file "
65   ~/transcode-tools/ffmpeg -i $temp_file &> ../temp.txt
66   echo "---------->即将对$temp_file 开始检测..."
67   checkVideo
68   echo "---------->$temp_file 检测完成...即将进行转码"
69   echo "---------->"
70   echo "------->"
71   echo "---->"
72   #echo "~/aftertrans/after_`date +%Y%m%d%H%M%S`_$temp_file"
73   ~/transcode-tools/transcode_2.sh ~/beforetrans/$temp_file "~/aftertrans/after_`date +%Y%m%d%H%M%S`_$temp_file" $videoResolution
74   echo "---------->$temp_file 转码完成了..."
75   echo "------->"
76   echo "---->"
77 done

上面代码中 beforetrans 是个文件夹,里面存放的是转码前的视频文件,aftertrans 文件夹里面存放的是转码后的文件夹,string.txt 是个临时文件