java使用FFmpeg合成视频和音频并获取视频中的音频等操作(实例代码详解)

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

ffmpeg命令参数如下:

通用选项

-L license
-h 帮助
-fromats 显示可用的格式,编解码的,协议的。。。
-f fmt 强迫采用格式fmt
-I filename 输入文件
-y 覆盖输出文件
-t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持
-ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持
-title string 设置标题
-author string 设置作者
-copyright string 设置版权
-comment string 设置评论
-target type 设置目标文件类型(vcd,svcd,dvd) 所有的格式选项(比特率,编解码以及缓冲区大小)自动设置 ,只需要输入如下的就可以了:
ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg
-hq 激活高质量设置
-itsoffset offset 设置以秒为基准的时间偏移,该选项影响所有后面的输入文件。该偏移被加到输入文件的时戳,定义一个正偏移意味着相应的流被延迟了 offset秒。 [-]hh:mm:ss[.xxx]的格式也支持

视频选项

-b bitrate 设置比特率,缺省200kb/s
-r fps 设置帧频 缺省25
-s size 设置帧大小 格式为WXH 缺省160X128.下面的简写也可以直接使用:
Sqcif 128X96 qcif 176X144 cif 252X288 4cif 704X576
-aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777
-croptop size 设置顶部切除带大小 像素单位
-cropbottom size –cropleft size –cropright size
-padtop size 设置顶部补齐的大小 像素单位
-padbottom size –padleft size –padright size –padcolor color 设置补齐条颜色(hex,6个16进制的数,红:绿:兰排列,比如 000000代表黑色)
-vn 不做视频记录
-bt tolerance 设置视频码率容忍度kbit/s
-maxrate bitrate设置最大视频码率容忍度
-minrate bitreate 设置最小视频码率容忍度
-bufsize size 设置码率控制缓冲区大小
-vcodec codec 强制使用codec编解码方式。 如果用copy表示原始编解码数据必须被拷贝。
-sameq 使用同样视频质量作为源(VBR)
-pass n 选择处理遍数(1或者2)。两遍编码非常有用。第一遍生成统计信息,第二遍生成精确的请求的码率
-passlogfile file 选择两遍的纪录文件名为file

高级选项

-g gop_size 设置图像组大小
-intra 仅适用帧内编码
-qscale q 使用固定的视频量化标度(VBR)
-qmin q 最小视频量化标度(VBR)
-qmax q 最大视频量化标度(VBR)
-qdiff q 量化标度间最大偏差 (VBR)
-qblur blur 视频量化标度柔化(VBR)
-qcomp compression 视频量化标度压缩(VBR)
-rc_init_cplx complexity 一遍编码的初始复杂度
-b_qfactor factor 在p和b帧间的qp因子
-i_qfactor factor 在p和i帧间的qp因子
-b_qoffset offset 在p和b帧间的qp偏差
-i_qoffset offset 在p和i帧间的qp偏差
-rc_eq equation 设置码率控制方程 默认tex^qComp
-rc_override override 特定间隔下的速率控制重载
-me method 设置运动估计的方法 可用方法有 zero phods log x1 epzs(缺省) full
-dct_algo algo 设置dct的算法 可用的有 0 FF_DCT_AUTO 缺省的DCT 1 FF_DCT_FASTINT 2 FF_DCT_INT 3 FF_DCT_MMX 4 FF_DCT_MLIB 5 FF_DCT_ALTIVEC
-idct_algo algo 设置idct算法。可用的有 0 FF_IDCT_AUTO 缺省的IDCT 1 FF_IDCT_INT 2 FF_IDCT_SIMPLE 3 FF_IDCT_SIMPLEMMX 4 FF_IDCT_LIBMPEG2MMX 5 FF_IDCT_PS2 6 FF_IDCT_MLIB 7 FF_IDCT_ARM 8 FF_IDCT_ALTIVEC 9 FF_IDCT_SH4 10 FF_IDCT_SIMPLEARM
-er n 设置错误残留为n 1 FF_ER_CAREFULL 缺省 2 FF_ER_COMPLIANT 3 FF_ER_AGGRESSIVE 4 FF_ER_VERY_AGGRESSIVE
-ec bit_mask 设置错误掩蔽为bit_mask,该值为如下值的位掩码 1 FF_EC_GUESS_MVS (default=enabled) 2 FF_EC_DEBLOCK (default=enabled)
-bf frames 使用frames B 帧,支持mpeg1,mpeg2,mpeg4
-mbd mode 宏块决策 0 FF_MB_DECISION_SIMPLE 使用mb_cmp 1 FF_MB_DECISION_BITS 2 FF_MB_DECISION_RD
-4mv 使用4个运动矢量 仅用于mpeg4
-part 使用数据划分 仅用于mpeg4
-bug param 绕过没有被自动监测到编码器的问题
-strict strictness 跟标准的严格性
-aic 使能高级帧内编码 h263+
-umv 使能无限运动矢量 h263+
-deinterlace 不采用交织方法
-interlace 强迫交织法编码 仅对mpeg2和mpeg4有效。当你的输入是交织的并且你想要保持交织以最小图像损失的时候采用该选项。可选的方法是不交织,但是损失更大
-psnr 计算压缩帧的psnr
-vstats 输出视频编码统计到vstats_hhmmss.log
-vhook module 插入视频处理模块 module 包括了模块名和参数,用空格分开

音频选项

-ab bitrate 设置音频码率
-ar freq 设置音频采样率
-ac channels 设置通道 缺省为1
-an 不使能音频纪录
-acodec codec 使用codec编解码

音视频捕获选项

-vd device 设置视频捕获设备。比如/dev/video0
-vc channel 设置视频捕获通道 DV1394专用
-tvstd standard 设置电视标准 NTSC PAL(SECAM)
-dv1394 设置DV1394捕获
-av device 设置音频设备 比如/dev/dsp

高级选项

-map file:stream 设置输入流映射
-debug 打印特定调试信息
-benchmark 为基准测试加入时间
-hex 倾倒每一个输入包
-bitexact 仅使用位精确算法 用于编解码测试
-ps size 设置包大小,以bits为单位
-re 以本地帧频读数据,主要用于模拟捕获设备
-loop 循环输入流。只工作于图像流,用于ffserver测试

横向合并视频

ffmpeg -i input1.mp4 -i input2.mp4 -lavfi hstack output.mp4

上面的命令虽然可以合并视频,两个视频可以正常播放,但是只保留了前面一个的音频。

下面会介绍怎么避开这个坑。

注意这时候input1和input2必须同样的高度,如果不一样的高度可以使用-shortest参数来保证同样的高度。

如果希望合并多个视频,可以使用下面命令行。

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -lavfi hstack=inputs=3 output.mp4

其中input=3表示希望合并的视频的个数

纵向合并视频

ffmpeg -i input1.mp4 -i input2.mp4 -lavfi vstack output.mp4

网格合并视频

当多个视频时,还可以合并成网格状,比如2x2,3x3这种。但是视频个数不一定需要是偶数,如果是奇数,可以用黑色图片来占位。

ffmpeg -f lavfi -i color=c=black:s=1280x720 -vframes 1 black.png

该命令将创建一张1280*720的图片

然后就可以使用下面这个命令来合并成网格视频了,如果只有三个视频,可以选择上面创建的黑色图片替代。

ffmpeg -i top_left.mp4 -i top_right.mp4 -i bottom_left.mp4 -i bottom_right.mp4 \
-lavfi "[0:v][1:v]hstack[top];[2:v][3:v]hstack[bottom];[top][bottom]vstack"
-shortest 2by2grid.mp4

上面创建的是正规的2x2网格视频。想象一下,现在只有三个视频,我想把第一个视频摆放在第一行的中间,然后把第二、三个视频摆放在第二行。那么就可以使用下面两个命令了。

ffmpeg -f lavfi -i color=c=black:s=640x720 -vframes 1 black.png

ffmpeg -i black.png -i top_center.mp4 -i bottom_left.mp4 -i bottom_right.mp4
-lavfi "[0:v][1:v][0:v]hstack=inputs=3[top];[2:v][3:v]hstack[bottom];[top][bottom]vstack"
-shortest 3_videos_2x2_grid.mp4

合并音频和视频

ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental output.mp4

如果视频中已经包含了音频,这个时候还可以替换视频中的音频,使用下面命令行。

ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental
-map 0:v:0 -map 1:a:0 output.mp4

合并两个音频

ffmpeg -i input1.mp3 -i input2.mp3 -filter_complex amerge -ac 2 -c:a libmp3lame -q:a 4 output.mp3

获取视频中的音频

ffmpeg -i input.mp4 -vn -y -acodec copy output.m4a

去掉视频中的音频

ffmpeg -i input.mp4 -an output.mp4

现在介绍,怎么合并两个视频并保留两个视频中的音频。也就是抖音中的合拍功能。
1.合并两个视频,但是发现只有一个声音。无所谓。
2.抽取两个视频中的音频,然后合并成一个音频。
3.将这个音频替换到之前的合并视频中。
4.ok了。
5.可以使用ffplay播放了。

附上java代码,可直接使用。使用前需要先将FFmpeg的bin目录配置在环境变量中。配置完成后,在cmd中拼 ffmpeg -version

如果能ping通说明配置成功,然后直接使用以下代码即可成功。

package com.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 视频中获取音频文件
 */
public class VideoUtils {
 //FFmpeg全路径
 private static final String FFMPEG_PATH = "D:\\666\\ffmpeg-20190730-a0c1970-win64-static\\bin\\ffmpeg.exe";
 //音频保存路径
 private static final String TMP_PATH = "D:\\666";

 /**
  * 从视频中提取音频信息
  * @param videoUrl
  * @return
  */
 public static String videoToAudio(String videoUrl){
  String aacFile = "";
  try {
   aacFile = TMP_PATH + "/" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
     + UUID.randomUUID().toString().replaceAll("-", "") + ".mp3";
   String command = FFMPEG_PATH + " -i "+ videoUrl + " -vn -acodec copy "+ aacFile;
   System.out.println("video to audio command : " + command);
   Process process = Runtime.getRuntime().exec(command);
   process.waitFor();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return "";
 }

 public static void main(String[] args){
 try {
// videoToAudio("D:\\laji\\2.mp4");
 String videoInputPath = "D:\\laji\\aa.mp4";
 String audioInputPath = "D:\\laji\\a.mp3";
 String videoOutPath = "D:\\laji\\bb1.avi";
 convetor(videoInputPath,audioInputPath,videoOutPath);
 } catch (Exception e) {
 e.printStackTrace();
 }
 System.out.println("---------获取音频文件成功!-----------");

 }
 /**
  * @param videoInputPath 原视频的全路径
  * @param audioInputPath 音频的全路径
  * @param videoOutPath 视频与音频结合之后的视频的路径
  * @throws Exception
  */
 public static void convetor(String videoInputPath, String audioInputPath, String videoOutPath)
   throws Exception {
  Process process = null;
  try {
   String command =FFMPEG_PATH + " -i " + videoInputPath + " -i " + audioInputPath + " -c:v copy -c:a aac -strict experimental " +
    " -map 0:v:0 -map 1:a:0 "
    + " -y " + videoOutPath;
   process = Runtime.getRuntime().exec(command);
   process.waitFor();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源,所以这里我们需要对流进行处理
  InputStream errorStream = process.getErrorStream();
  InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
  BufferedReader br = new BufferedReader(inputStreamReader);

  String line = "";
  while ((line = br.readLine()) != null) {
  }
  if (br != null) {
   br.close();
  }
  if (inputStreamReader != null) {
   inputStreamReader.close();
  }
  if (errorStream != null) {
   errorStream.close();
  }

 }

}

总结

到此这篇关于java使用FFmpeg合成视频和音频并获取视频中的音频等操作(实例代码详解)的文章就介绍到这了,更多相关java使用FFmpeg合成视频和音频内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Javacv使用ffmpeg实现音视频同步播放

    最近用javaCV的ffmpeg包的FFmpegFrameGrabber帧捕捉器对捕捉到的音频帧和视频帧做了同步的播放.采用的同步方法是视频向音频同步. 程序和源码 具体的思路如下: (1)首先介绍ffmpeg是如何捕捉视频文件的图像和声音的 FFmpegFrameGrabber fg = new FFmpegFrameGrabber("a video file path or a url); 得到帧捕捉器对象后,调用它的grab()方法就会返回捕捉到的Frame对象.这个Frame可以是视频帧

  • Java实现对视频进行截图的方法【附ffmpeg下载】

    本文实例讲述了Java实现对视频进行截图的方法.分享给大家供大家参考,具体如下: 之前介绍过Java使用ffmpeg进行视频转换,这里演示一下ffmpeg进行视频截图的方法. 具体代码如下: import java.io.File; import java.util.List; //生成视频文件的首帧为图片 //windows下的版本 public class CreatePh { // public static final String FFMPEG_PATH = "E:/ffmpeg/ff

  • Java通过调用FFMPEG获取视频时长

    FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的. 由此看来FFmpeg很强大,很多主流的音频.视频处理软件都使用了FFmpeg. FFmpeg下载下来解压,cmd进入到FFmpeg.exe目录中,即可在命令行下进行各种操作,查看视频信息命令:f

  • java调用ffmpeg实现视频转换的方法

    本文实例讲述了java调用ffmpeg实现视频转换的方法.分享给大家供大家参考.具体分析如下: 这里环境我是在windows平台下测试的... 需要在e:\下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4个文件.   还要在e:\input下放各种文件名为a的以下各种视频文件:还要e:\output:java程序执行后能得到一个a.flv的已转换的文件. ffmpeg.exe能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov

  • Java使用FFmpeg处理视频文件的方法教程

    前言 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频的文章,大多都讲的比较简单,楼主在实操过程中踩了很多坑也填了很多坑,希望这份详细的踩坑&填坑指南能帮助到大家: 1. 什么是FFmpeg 点我了解 2. 开发前准备 在使用Java调用FFmpeg处理音视频之前,需要先安装FFmpeg,安装方法分为两种: 引入封装了FFmpeg的开源框架 在系统中手动安装FFmpeg 2.1 引入封装

  • java使用FFmpeg合成视频和音频并获取视频中的音频等操作(实例代码详解)

    FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序. ffmpeg命令参数如下: 通用选项 -L license -h 帮助 -fromats 显示可用的格式,编解码的,协议的... -f fmt 强迫采用格式fmt -I filename 输入文件 -y 覆盖输出文件 -t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持 -ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持 -title

  • python获取时间及时间格式转换问题实例代码详解

    整理总结一下python中最常用的一些时间戳和时间格式的转换 第一部分:获取当前时间和10位13位时间戳 import datetime, time '''获取当前时间''' n = datetime.datetime.now() print(n) '''获取10位时间戳''' now = time.time() print(int(now)) '''获取13位时间戳''' now2 = round(now*1000) print(now2) 运行结果为: 2018-12-06 11:00:30

  • python 获取当前目录下的文件目录和文件名实例代码详解

    os模块下有两个函数: os.walk() os.listdir() # -*- coding: utf-8 -*- import os def file_name(file_dir): for root, dirs, files in os.walk(file_dir): print(root) #当前目录路径 print(dirs) #当前路径下所有子目录 print(files) #当前路径下所有非目录子文件 输出格式为: 当前文件目录路径 当前路径下子文件目录(若存在, 不存在则为 []

  • Java获取彩色图像中的主色彩的实例代码

    本文讲述了Java获取彩色图像中的主色彩的实例代码.分享给大家供大家参考,具体如下: 一:基本思路 对于一张RGB色彩空间的彩色图像,很多时间我们想通过程序获得该图像有几种主要的色彩,但是对一般图像来说,在色彩交界处都是通过像素混合来实现自然过渡,所以直接扫描图像的像素值,得到的不同颜色值可能多达上百中,而实际上图像可能只有3-4种的主要色彩,如何去掉那些混合颜色,准确提取出来这3-4中的主色彩,根据一般图像的特征,图像在不同色彩的边界处混合不同的颜色值,此可以视为图像的边缘特性之一,因此可以根

  • java 获取对象中为null的字段实例代码

    下面一段简单的代码给大家分享java 获取对象中为null的字段,具体代码如下所述: private static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> emptyNames

  • java使用RSA与AES加密解密的实例代码详解

    首先了解下,什么是堆成加密,什么是非对称加密? 对称加密:加密与解密的密钥是相同的,加解密速度很快,比如AES 非对称加密:加密与解密的秘钥是不同的,速度较慢,比如RSA •先看代码(先会用在研究) 相关依赖: <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.58</versio

  • Java回调函数实例代码详解

    首先说说什么叫回调函数? 在WINDOWS中,程序员想让系统DLL调用自己编写的一个方法,于是利用DLL当中回调函数(CALLBACK)的接口来编写程序,使它调用,这个就 称为回调.在调用接口时,需要严格的按照定义的参数和方法调用,并且需要处理函数的异步,否则会导致程序的崩溃. 这样的解释似乎还是比较难懂,这里举个简 单的例子: 程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序.程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法.目的达到

  • Java 从网上下载文件的几种方式实例代码详解

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package com.github.pandafang.tool; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.chan

  • java多线程之停止线程的方法实例代码详解

    和线程停止相关的三个方法 /* 中断线程.如果线程被wait(),join(),sleep()等方法阻塞,调用interrupt()会清除线程中断状态,并收到InterruptedException异常.另外interrupt();对于isAlive()返回false的线程不起作用. */ public void interrupt(); /* 静态方法,判断线程中断状态,并且会清除线程的中断状态.所以连续多次调用该方法,第二次之后必定返回false.另外,isAlive()用于判断线程是否处于

  • java匿名内部类实例代码详解

    这篇文章主要介绍了java匿名内部类实例代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Person.java package insof; public class Person extends Object{ String name; static int age; public Person() { this.name = "tom"; System.out.println("执行的是构造方法");

随机推荐