美文网首页
2021-03-22 ffmpeg命令详解

2021-03-22 ffmpeg命令详解

作者: lancelot123 | 来源:发表于2021-03-22 15:49 被阅读0次

    ffmpeg相关文章网址(用于记录一些好的文章地址~)
    ffmpeg命令详解

    https://blog.csdn.net/zzcchunter/article/details/68060989

    java使用ffmpeg进行视频转换

    https://blog.csdn.net/zhengdesheng19930211/article/details/64443620

    java使用ffmpeg插件捕获视频帧数

    https://blog.csdn.net/qq_24138151/article/details/78133889

    1、ffmpeg介绍
    ffmpeg是一个命令行工具,相关详细的命令操作可以在官网查询到详细解释,ffmpeg支持音频、视频多种编解码格式,功能强大。

    ffmpeg项目由以下几个部分组成

       ffmpeg(fast forword mpeg): 音视频文件转换命令行工具
    
       ffplay( fast forword play): 用ffmpeg实现的简单媒体播放器
    
       ffserver (fast forword server): 用ffmpeg实现的基于http,rstp多媒体服务器
    
       ffprobe( fast forword probe): 用来输入分析输入流
    
       libavcodec: 一个包含了所有ffmpeg音视频编解码器的库,为了保证最优性能和高可复用性,大多数编解码器从头开发
    
       libavformat : 一个包含了所有的普通音视频格式的解析器和产生器的库
    

    2、ffmpeg安装
    fmpeg的官方网站是:http://ffmpeg.org/,编译好的windows可用版本的下载地址: http://ffmpeg.zeranoe.com/builds/,可下载下来进行在本机使用。

       下载的版本区分Static、Shared、Dev,区别在于:Static里面只有3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe,每个exe的体积都很大,相关的Dll已经被编译到exe里面去了。Shared里面除了3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe之外,还有一些Dll,比如说avcodec-54.dll之类的。Shared里面的exe体积很小,他们在运行的时候,到相应的Dll中调用功能。
    

    Dev版本是用于开发的,里面包含了库文件xxx.lib以及头文件xxx.h,这个版本不包含exe文件。

    可选择最新版本下载,下载后会有ffmpeg.exe、ffplay.exe、ffprobe.exe三个可执行程序,相关的ffmpeg支持的dll库都被编译在可执行文件中。

    ffmpeg.exe用作转码,ffplay.exe用来播放文件,ffprobe.exe用来查看文件格式,在此不做介绍。

    在Linux环境下安装ffmpeg

    (1)下载ffmpeg,根据自己需求下载不同版本:http://www.ffmpeg.org/download.html

    (2)解压缩 tar -zxvf ffmpeg-2.0.1.tar.gz

    (3)配置, 生成Makefile。可以指定ffmpeg的编码功能,感兴趣的可以详细去了解下这块的编译,

    ./configure --enable-shared --disable-yasm --prefix=/usr/local/ffmpeg

    如果执行结果不对,可以根据提示信息,并查看帮助,解决问题

    ./configure --help

    (4)编译安装

    make&make install

    (5)安装之后在/usr/local/ffmpeg会看到有三个目录

    bin 执行文件目录
    lib 静态,动态链接库目录
    include 编程用到的头文件

    (6)编译测试程序

    gcc -o ffmpegtest ffmpegtest.c -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat -lavcodec –lavtuil

    (7)执行程序

    ./ffmpegtest或直接执行/usr/local/ffmpeg/lib目录下的./ffmpeg进行测试。

    3、ffmpeg使用
    使用ffmpeg进行音频转换,由amr转为mp3

    public void changeAmrToMp3(String sourcePath, String targetPath) throws Exception {

        String webroot = "d:\\ffmpeg\\bin";
    
        Runtime run = null;
    
        try {
    
            run = Runtime.getRuntime();
    
            long start=System.currentTimeMillis();
    
            System.out.println(new File(webroot).getAbsolutePath());
    
            //执行ffmpeg.exe,前面是ffmpeg.exe的地址,中间是需要转换的文件地址,后面是转换后的文件地址。-i是转换方式,意思是可编码解码,mp3编码方式采用的是libmp3lame
    
            //wav转pcm
    
            //Process p=run.exec(new File(webroot).getAbsolutePath()+"/ffmpeg -y -i "+sourcePath+" -acodec pcm_s16le -f s16le -ac 1 -ar 16000 "+targetPath);
    
            //mp3转pcm
    
            Process p=run.exec(new File(webroot).getAbsolutePath()+"/ffmpeg -y -i "+sourcePath+" -ar 44100 -ac 2 -acodec mp3 "+targetPath);
    
            //释放进程
    
            p.getOutputStream().close();
    
            p.getInputStream().close();
    
            p.getErrorStream().close();
    
            p.waitFor();
    
            long end=System.currentTimeMillis();
    
            System.out.println(sourcePath+" convert success, costs:"+(end-start)+"ms");
    
        } catch (Exception e) {
    
            e.printStackTrace();
    
        }finally{
    
            //run调用lame解码器最后释放内存
    
            run.freeMemory();
    
        }
    

    }

    (1)主要参数:

    -i 设定输入流

    (2)音频参数:
    -ar 设定采样率 对应sampleRate
    -ac 设定声音的Channel数 对应channel
    -acodec 设定声音编解码器,未设定时则使用与输入流相同的编解码器
    -an 不处理音频

    -ab bitrate 设置音频码率

    (3)转换不同格式的音频文件:

    需要转换的音频格式

    1-mp3,2-wav(8k8bitPCM),3-wav(8k16bitPCM),4-wav(8k8bitALAW),5-wav(8k16bitALAW),6-wav(11k16bitPCM)

    注:11k16bit即8k16bitPCM 采样率位11025

    8k16bit alaw 同 8k8bit alaw
    

    (4)音频文件截取指定时间部分

    ffmpeg.exe -i 124.mp3 -vn -acodec copy -ss 00:00:00 -t 00:01:32 output.mp3

    解释:-i代表输入参数

          -acodec copy output.mp3 重新编码并复制到新文件中
    
           -ss 开始截取的时间点
    
           -t 截取音频时间长度
    

    (5)设置输出文件的最大值

    -fs (file size首字母缩写)   ffmpeg -i input.avi -fs 1024K output.mp4

    计算输出文件大小  (视频码率+音频码率) * 时长 /8 = 文件大小K

    4、项目中使用ffmpeg将mp3文件转成wav文件(补充)
    前段时间项目中需要将微信录音中speex高清音频转成wav音频格式,查了相关资料及咨询了大佬总算搞定了,详见:

    https://blog.csdn.net/scropio0zry/article/details/84929451

    整理相关代码后,发现也可以用于ffmpeg转换,这里做一下相关整理

    import java.text.MessageFormat;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;

    import org.apache.commons.lang3.exception.ExceptionUtils;
    import org.springframework.stereotype.Service;

    import com.common.utils.logback.LogUtil;
    import com.common.utils.uuid.GuidUtil;
    import com.common.FileUtil;
    import com.common.PropertiesDef;

    @Service
    public class Mp3ToWavService {

    private ExecutorService pool = Executors.newCachedThreadPool();
    
    public byte[] mp3ToWav(byte[] data,int mediaType) {
        byte[] body = null;
        //录音文件下拉地址
        String path = PropertiesDef.ORIGIN_PATH;
        String mp3Name = GuidUtil.getUUID() + ".mp3";
        String wavName = GuidUtil.getUUID() + ".wav";
        try {
            if (FileUtil.save(path, mp3Name, data)) {
                String command = "";
                // 将mp3转换成wav 采样率16000 16kbs wav音频文件
                // FFMPEG_PATH ffmpeg路径 如:D:/ffmpeg/bin/ffmpeg.exe
                command = MessageFormat.format("{0} -i {1} -ar 16000 -acodec pcm_s16le {2}",PropertiesDef.FFMPEG_PATH,
                        path + mp3Name, path + wavName);
                int n = execCommand(command, 10000);
                // 获取文件流
                if (n == 0) {
                    body = FileUtil.getFile(PropertiesDef.ORIGIN_PATH, wavName);
                }
            }
        } catch (Exception e) {
            LogUtil.logError("mp3转wav失败", ExceptionUtils.getStackTrace(e));
    
        } finally {
            // 执行完毕,删除下拉音频文件
             FileUtil.deleteFile(PropertiesDef.ORIGIN_PATH + mp3Name);
             FileUtil.deleteFile(PropertiesDef.ORIGIN_PATH + wavName);
        }
    
        return body;
    }
    
    public int execCommand(String command, long timeout) {
        Process process = null;
        Future<Integer> executeFuture = null;
        try {
            process = Runtime.getRuntime().exec(command);
            final Process p = process;
            Callable<Integer> call = new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    p.waitFor();
                    return p.exitValue();
                }
            };
            
            //使用线程池防止Process阻塞
            executeFuture = pool.submit(call);
            return executeFuture.get(timeout, TimeUnit.MILLISECONDS);
            
        } catch (Exception e) {
            LogUtil.logError("mp3转wav:execCommand 执行命令失败,command:{},错误原因:{}", command,
                    ExceptionUtils.getStackTrace(e));
            return 1;
        }finally {
            if (executeFuture != null) {
                try {
                    executeFuture.cancel(true);
                } catch (Exception ignore) {
                }
            }
            if (process != null) {
                process.destroy();
            }
        }
    
    }
    

    }
    FileUtil工具类

    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;

    import org.apache.commons.lang.exception.ExceptionUtils;

    import com.common.utils.logback.LogUtil;

    public class FileUtil {

    public static boolean save(String filePath, String fileName, byte[] content) {
        try {
            File filedir = new File(filePath);
            if (!filedir.exists()) {
                filedir.mkdirs();
            }
            File file = new File(filedir, fileName);
            OutputStream os = new FileOutputStream(file);
            os.write(content, 0, content.length);
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            LogUtil.logError(
                    "保存文件流异常,函数名称:save,fileName:{},filePath:{},异常原因:{}",
                    fileName, filePath, ExceptionUtils.getStackTrace(e));
            return false;
        } catch (IOException e) {
            LogUtil.logError(
                    "保存文件流异常,函数名称:save,fileName:{},filePath:{},异常原因:{}",
                    fileName, filePath, ExceptionUtils.getStackTrace(e));
            return false;
        }
        return true;
    }
    
    public static byte[] getFile(String filePath, String fileName){
         byte[] buffer = null;  
            try {  
                File file = new File(filePath,fileName);  
                FileInputStream fis = new FileInputStream(file);  
                ByteArrayOutputStream bos = new ByteArrayOutputStream();  
                byte[] b = new byte[1024 * 4];  
                int n;  
                while ((n = fis.read(b)) != -1) {  
                    bos.write(b, 0, n);  
                }  
                buffer = bos.toByteArray();  
                fis.close();  
                bos.close();  
            } catch (Exception e) {  
                LogUtil.logError(
                        "获取文件流异常,函数名称:getFile,fileName:{},filePath:{},异常原因:{}",
                        fileName, filePath, ExceptionUtils.getStackTrace(e)); 
            }
         return buffer;  
    }
    

    ————————————————
    版权声明:本文为CSDN博主「scorpio0zry」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/scropio0zry/article/details/82389203

    相关文章

      网友评论

          本文标题:2021-03-22 ffmpeg命令详解

          本文链接:https://www.haomeiwen.com/subject/sknzcltx.html