java使用FFmpeg合成视频和音频并获取视频中的音频等操作(实例代码详解)
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。
ffmpeg命令参数如下:
通用选项
-Llicense
-h帮助
-fromats显示可用的格式,编解码的,协议的。。。
-ffmt强迫采用格式fmt
-Ifilename输入文件
-y覆盖输出文件
-tduration设置纪录时间hh:mm:ss[.xxx]格式的记录时间也支持
-ssposition搜索到指定的时间[-]hh:mm:ss[.xxx]的格式也支持
-titlestring设置标题
-authorstring设置作者
-copyrightstring设置版权
-commentstring设置评论
-targettype设置目标文件类型(vcd,svcd,dvd)所有的格式选项(比特率,编解码以及缓冲区大小)自动设置,只需要输入如下的就可以了:
ffmpeg-imyfile.avi-targetvcd/tmp/vcd.mpg
-hq激活高质量设置
-itsoffsetoffset设置以秒为基准的时间偏移,该选项影响所有后面的输入文件。该偏移被加到输入文件的时戳,定义一个正偏移意味着相应的流被延迟了offset秒。[-]hh:mm:ss[.xxx]的格式也支持
视频选项
-bbitrate设置比特率,缺省200kb/s
-rfps设置帧频缺省25
-ssize设置帧大小格式为WXH缺省160X128.下面的简写也可以直接使用:
Sqcif128X96qcif176X144cif252X2884cif704X576
-aspectaspect设置横纵比4:316:9或1.33331.7777
-croptopsize设置顶部切除带大小像素单位
-cropbottomsize–cropleftsize–croprightsize
-padtopsize设置顶部补齐的大小像素单位
-padbottomsize–padleftsize–padrightsize–padcolorcolor设置补齐条颜色(hex,6个16进制的数,红:绿:兰排列,比如000000代表黑色)
-vn不做视频记录
-bttolerance设置视频码率容忍度kbit/s
-maxratebitrate设置最大视频码率容忍度
-minratebitreate设置最小视频码率容忍度
-bufsizesize设置码率控制缓冲区大小
-vcodeccodec强制使用codec编解码方式。如果用copy表示原始编解码数据必须被拷贝。
-sameq使用同样视频质量作为源(VBR)
-passn选择处理遍数(1或者2)。两遍编码非常有用。第一遍生成统计信息,第二遍生成精确的请求的码率
-passlogfilefile选择两遍的纪录文件名为file
高级选项
-ggop_size设置图像组大小
-intra仅适用帧内编码
-qscaleq使用固定的视频量化标度(VBR)
-qminq最小视频量化标度(VBR)
-qmaxq最大视频量化标度(VBR)
-qdiffq量化标度间最大偏差(VBR)
-qblurblur视频量化标度柔化(VBR)
-qcompcompression视频量化标度压缩(VBR)
-rc_init_cplxcomplexity一遍编码的初始复杂度
-b_qfactorfactor在p和b帧间的qp因子
-i_qfactorfactor在p和i帧间的qp因子
-b_qoffsetoffset在p和b帧间的qp偏差
-i_qoffsetoffset在p和i帧间的qp偏差
-rc_eqequation设置码率控制方程默认tex^qComp
-rc_overrideoverride特定间隔下的速率控制重载
-memethod设置运动估计的方法可用方法有zerophodslogx1epzs(缺省)full
-dct_algoalgo设置dct的算法可用的有0FF_DCT_AUTO缺省的DCT1FF_DCT_FASTINT2FF_DCT_INT3FF_DCT_MMX4FF_DCT_MLIB5FF_DCT_ALTIVEC
-idct_algoalgo设置idct算法。可用的有0FF_IDCT_AUTO缺省的IDCT1FF_IDCT_INT2FF_IDCT_SIMPLE3FF_IDCT_SIMPLEMMX4FF_IDCT_LIBMPEG2MMX5FF_IDCT_PS26FF_IDCT_MLIB7FF_IDCT_ARM8FF_IDCT_ALTIVEC9FF_IDCT_SH410FF_IDCT_SIMPLEARM
-ern设置错误残留为n1FF_ER_CAREFULL缺省2FF_ER_COMPLIANT3FF_ER_AGGRESSIVE4FF_ER_VERY_AGGRESSIVE
-ecbit_mask设置错误掩蔽为bit_mask,该值为如下值的位掩码1FF_EC_GUESS_MVS(default=enabled)2FF_EC_DEBLOCK(default=enabled)
-bfframes使用framesB帧,支持mpeg1,mpeg2,mpeg4
-mbdmode宏块决策0FF_MB_DECISION_SIMPLE使用mb_cmp1FF_MB_DECISION_BITS2FF_MB_DECISION_RD
-4mv使用4个运动矢量仅用于mpeg4
-part使用数据划分仅用于mpeg4
-bugparam绕过没有被自动监测到编码器的问题
-strictstrictness跟标准的严格性
-aic使能高级帧内编码h263+
-umv使能无限运动矢量h263+
-deinterlace不采用交织方法
-interlace强迫交织法编码仅对mpeg2和mpeg4有效。当你的输入是交织的并且你想要保持交织以最小图像损失的时候采用该选项。可选的方法是不交织,但是损失更大
-psnr计算压缩帧的psnr
-vstats输出视频编码统计到vstats_hhmmss.log
-vhookmodule插入视频处理模块module包括了模块名和参数,用空格分开
音频选项
-abbitrate设置音频码率
-arfreq设置音频采样率
-acchannels设置通道缺省为1
-an不使能音频纪录
-acodeccodec使用codec编解码
音视频捕获选项
-vddevice设置视频捕获设备。比如/dev/video0
-vcchannel设置视频捕获通道DV1394专用
-tvstdstandard设置电视标准NTSCPAL(SECAM)
-dv1394设置DV1394捕获
-avdevice设置音频设备比如/dev/dsp
高级选项
-mapfile:stream设置输入流映射
-debug打印特定调试信息
-benchmark为基准测试加入时间
-hex倾倒每一个输入包
-bitexact仅使用位精确算法用于编解码测试
-pssize设置包大小,以bits为单位
-re以本地帧频读数据,主要用于模拟捕获设备
-loop循环输入流。只工作于图像流,用于ffserver测试
横向合并视频
ffmpeg-iinput1.mp4-iinput2.mp4-lavfihstackoutput.mp4
上面的命令虽然可以合并视频,两个视频可以正常播放,但是只保留了前面一个的音频。
下面会介绍怎么避开这个坑。
注意这时候input1和input2必须同样的高度,如果不一样的高度可以使用-shortest参数来保证同样的高度。
如果希望合并多个视频,可以使用下面命令行。
ffmpeg-iinput1.mp4-iinput2.mp4-iinput3.mp4-lavfihstack=inputs=3output.mp4
其中input=3表示希望合并的视频的个数
纵向合并视频
ffmpeg-iinput1.mp4-iinput2.mp4-lavfivstackoutput.mp4
网格合并视频
当多个视频时,还可以合并成网格状,比如2x2,3x3这种。但是视频个数不一定需要是偶数,如果是奇数,可以用黑色图片来占位。
ffmpeg-flavfi-icolor=c=black:s=1280x720-vframes1black.png
该命令将创建一张1280*720的图片
然后就可以使用下面这个命令来合并成网格视频了,如果只有三个视频,可以选择上面创建的黑色图片替代。
ffmpeg-itop_left.mp4-itop_right.mp4-ibottom_left.mp4-ibottom_right.mp4\
-lavfi"[0:v][1:v]hstack[top];[2:v][3:v]hstack[bottom];[top][bottom]vstack"
-shortest2by2grid.mp4
上面创建的是正规的2x2网格视频。想象一下,现在只有三个视频,我想把第一个视频摆放在第一行的中间,然后把第二、三个视频摆放在第二行。那么就可以使用下面两个命令了。
ffmpeg-flavfi-icolor=c=black:s=640x720-vframes1black.png ffmpeg-iblack.png-itop_center.mp4-ibottom_left.mp4-ibottom_right.mp4 -lavfi"[0:v][1:v][0:v]hstack=inputs=3[top];[2:v][3:v]hstack[bottom];[top][bottom]vstack" -shortest3_videos_2x2_grid.mp4
合并音频和视频
ffmpeg-ivideo.mp4-iaudio.wav-c:vcopy-c:aaac-strictexperimentaloutput.mp4
如果视频中已经包含了音频,这个时候还可以替换视频中的音频,使用下面命令行。
ffmpeg-ivideo.mp4-iaudio.wav-c:vcopy-c:aaac-strictexperimental -map0:v:0-map1:a:0output.mp4
合并两个音频
ffmpeg-iinput1.mp3-iinput2.mp3-filter_complexamerge-ac2-c:alibmp3lame-q:a4output.mp3
获取视频中的音频
ffmpeg-iinput.mp4-vn-y-acodeccopyoutput.m4a
去掉视频中的音频
ffmpeg-iinput.mp4-anoutput.mp4
现在介绍,怎么合并两个视频并保留两个视频中的音频。也就是抖音中的合拍功能。
1.合并两个视频,但是发现只有一个声音。无所谓。
2.抽取两个视频中的音频,然后合并成一个音频。
3.将这个音频替换到之前的合并视频中。
4.ok了。
5.可以使用ffplay播放了。
附上java代码,可直接使用。使用前需要先将FFmpeg的bin目录配置在环境变量中。配置完成后,在cmd中拼ffmpeg-version
如果能ping通说明配置成功,然后直接使用以下代码即可成功。
packagecom.util; importjava.io.BufferedReader; importjava.io.IOException; importjava.io.InputStream; importjava.io.InputStreamReader; importjava.text.SimpleDateFormat; importjava.util.ArrayList; importjava.util.Date; importjava.util.List; importjava.util.UUID; /** *视频中获取音频文件 */ publicclassVideoUtils{ //FFmpeg全路径 privatestaticfinalStringFFMPEG_PATH="D:\\666\\ffmpeg-20190730-a0c1970-win64-static\\bin\\ffmpeg.exe"; //音频保存路径 privatestaticfinalStringTMP_PATH="D:\\666"; /** *从视频中提取音频信息 *@paramvideoUrl *@return */ publicstaticStringvideoToAudio(StringvideoUrl){ StringaacFile=""; try{ aacFile=TMP_PATH+"/"+newSimpleDateFormat("yyyyMMddHHmmss").format(newDate()) +UUID.randomUUID().toString().replaceAll("-","")+".mp3"; Stringcommand=FFMPEG_PATH+"-i"+videoUrl+"-vn-acodeccopy"+aacFile; System.out.println("videotoaudiocommand:"+command); Processprocess=Runtime.getRuntime().exec(command); process.waitFor(); }catch(Exceptione){ e.printStackTrace(); } return""; } publicstaticvoidmain(String[]args){ try{ //videoToAudio("D:\\laji\\2.mp4"); StringvideoInputPath="D:\\laji\\aa.mp4"; StringaudioInputPath="D:\\laji\\a.mp3"; StringvideoOutPath="D:\\laji\\bb1.avi"; convetor(videoInputPath,audioInputPath,videoOutPath); }catch(Exceptione){ e.printStackTrace(); } System.out.println("---------获取音频文件成功!-----------"); } /** *@paramvideoInputPath原视频的全路径 *@paramaudioInputPath音频的全路径 *@paramvideoOutPath视频与音频结合之后的视频的路径 *@throwsException */ publicstaticvoidconvetor(StringvideoInputPath,StringaudioInputPath,StringvideoOutPath) throwsException{ Processprocess=null; try{ Stringcommand=FFMPEG_PATH+"-i"+videoInputPath+"-i"+audioInputPath+"-c:vcopy-c:aaac-strictexperimental"+ "-map0:v:0-map1:a:0" +"-y"+videoOutPath; process=Runtime.getRuntime().exec(command); process.waitFor(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } //使用这种方式会在瞬间大量消耗CPU和内存等系统资源,所以这里我们需要对流进行处理 InputStreamerrorStream=process.getErrorStream(); InputStreamReaderinputStreamReader=newInputStreamReader(errorStream); BufferedReaderbr=newBufferedReader(inputStreamReader); Stringline=""; while((line=br.readLine())!=null){ } if(br!=null){ br.close(); } if(inputStreamReader!=null){ inputStreamReader.close(); } if(errorStream!=null){ errorStream.close(); } } }
总结
到此这篇关于java使用FFmpeg合成视频和音频并获取视频中的音频等操作(实例代码详解)的文章就介绍到这了,更多相关java使用FFmpeg合成视频和音频内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。