使用jave(ffmpeg)将.amr音频转码成mp3

微信上的语音文件拿下来都是amr格式的,好像不分安卓和苹果。

ffmpeg这个工具可以实现音频、视频的格式转换。

java这里,有个现成的包jave,groupId是ws.schild

在maven库里可以看到ws.schild其下有好几个包

jave-core
jave-nativebin-win32
jave-nativebin-win64
jave-nativebin-linux32
jave-nativebin-linux64
jave-nativebin-osx64

jave-all-deps 是最完整的,它的pom.xml引用了所有版本的文件

看名字就能看出,jave-core是核心包,其它几个是windows、linux、maxosx系统下的本地文件

我用的是2.7.3版本,linux下的

<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-core</artifactId>
    <version>2.7.3</version>
</dependency>

<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-linux64</artifactId>
    <version>2.7.3</version>
</dependency>

其实nativebin里面就是一个类似ffmpeg.exe的文件

程序在运行时拼接参数,再调用对应的ffmpeg去执行

 比如 Encoder的encode方法,其中有一段非常朴素的if/else判断,addArgument方法就是向一个list里追加参数

            String codec = videoAttributes.getCodec();
            if (codec != null)
            {
                ffmpeg.addArgument("-vcodec");
                ffmpeg.addArgument(codec);
            }
            String tag = videoAttributes.getTag();
            if (tag != null)
            {
                ffmpeg.addArgument("-vtag");
                ffmpeg.addArgument(tag);
            }
            Integer bitRate = videoAttributes.getBitRate();
            if (bitRate != null)
            {
                ffmpeg.addArgument("-vb");
                ffmpeg.addArgument(String.valueOf(bitRate.intValue()));
            }
            Integer frameRate = videoAttributes.getFrameRate();
            if (frameRate != null)
            {
                ffmpeg.addArgument("-r");
                ffmpeg.addArgument(String.valueOf(frameRate.intValue()));
            }
            VideoSize size = videoAttributes.getSize();
            if (size != null)
            {
                ffmpeg.addArgument("-s");
                ffmpeg.addArgument(String.valueOf(size.getWidth()) + "x"
                        + String.valueOf(size.getHeight()));
            }

            if (videoAttributes.isFaststart())
            {
                ffmpeg.addArgument("-movflags");
                ffmpeg.addArgument("faststart");
            }

            if (videoAttributes.getX264Profile() != null)
            {
                ffmpeg.addArgument("-profile:v");
                ffmpeg.addArgument(videoAttributes.getX264Profile().getModeName());
            }

            if (videoAttributes.getVideoFilters().size() > 0)
            {
                for (VideoFilter videoFilter : videoAttributes.getVideoFilters())
                {
                    ffmpeg.addArgument("-vf");
                    ffmpeg.addArgument(videoFilter.getExpression());
                }
            }

            Integer quality = videoAttributes.getQuality();
            if (quality != null)
            {
                ffmpeg.addArgument("-qscale:v");
                ffmpeg.addArgument(String.valueOf(quality.intValue()));
            }

打断点可以看到,最后ffmpeg.execute()执行的时候程序用list拼成一个数组,用Runtime去执行

        int argsSize = args.size();
        String[] cmd = new String[argsSize + 2];
        cmd[0] = ffmpegExecutablePath;
        for (int i = 0; i < argsSize; i++)
        {
            cmd[i + 1] = args.get(i);
        }
        cmd[argsSize + 1] = "-hide_banner";  // Don't show banner
        if (LOG.isDebugEnabled())
        {
            StringBuilder sb = new StringBuilder();
            for (String c : cmd)
            {
                sb.append(c);
                sb.append(' ');
            }
            LOG.debug("About to execute {}", sb.toString());
        }
        Runtime runtime = Runtime.getRuntime();
        ffmpeg = runtime.exec(cmd);
        if (destroyOnRuntimeShutdown)
        {
            ffmpegKiller = new ProcessKiller(ffmpeg);
            runtime.addShutdownHook(ffmpegKiller);
        }
        if (openIOStreams)
        {
            inputStream = ffmpeg.getInputStream();
            outputStream = ffmpeg.getOutputStream();
            errorStream = ffmpeg.getErrorStream();
        }

大体执行原理是这样。

因为是用java拼参数去调用一个执行文件的方式,所以我没办法用输入输出流做入参。转换代码是用指定源文件和目标文件的字符串路径的方式告诉程序要操作的文件是哪一个。所以,在生产里我用的是先创建临时文件,格式转换后再在finanlly里用Files.deleteIfExists删除的方式。

代码如下

    public void putFile(ChatVoice chat) throws Exception {
        
        Path source = null;
        File target = null;
        try {
            source = Files.createTempFile(chat.getMsgid(), ".amr");
            target = File.createTempFile(chat.getMsgid(), ".mp3");
            Files.write(source, bs);
            
            amrToMp3(source.toFile(), target);

            /* target的其它处理逻辑 */
            //......

        }finally {
            Files.deleteIfExists(source);
            Files.deleteIfExists(target.toPath());
        }
    }

    public void amrToMp3(File source, File target) throws EncoderException   {
        
        //Audio Attributes
        AudioAttributes audio = new AudioAttributes();
        audio.setCodec("libmp3lame");   //lame是一个mp3编码库

//        audio.setBitRate(128000);   
//        audio.setChannels(2);
//        audio.setSamplingRate(44100);

        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setFormat("mp3");
        attrs.setAudioAttributes(audio);

        //Encode
        Encoder encoder = new Encoder();
        encoder.encode(new MultimediaObject(source), target, attrs);
    }

另外也可以视频格式转换,例子网上到处都有。

代码里audio对象可以设置一些参数,这个我不太懂,大约不特别指定就好,按官方代码指定了采样率和通道数后生成的mp3尺寸大了很多,播放效果还是随着源文件的质量来。

在windows下的cmd窗口运行 ffmpeg-amd64.exe --helpfmpeg-amd64.exe --help full

可以看到太多的参数选项,真的很多。

在官方网址里 https://github.com/a-schild/jave2 可以看到一些说明和调用示例

尤其是 More advanced examples 里  https://github.com/a-schild/jave2/blob/master/Examples.md


本文代码基本上是从官网上抄来的,剩下的也是看了网上很多大同小异的文章。

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: jave-1.0.2.jar是一个Java库文件。它被用于在Java应用程序中处理音频和视频文件。这个库提供了一系列的类和方法,使开发者能够方便地读取、写入、换和处理各种音频和视频文件格式。 使用jave-1.0.2.jar,我们可以轻松地从一个音频或视频文件中提取音频或视频数据,并将其保存到不同的文件格式中。例如,我们可以从一个视频文件中提取音频,然后将提取出来的音频保存为MP3或WAV格式。 此外,jave-1.0.2.jar还可以用于将不同格式的音频或视频文件互相换。我们可以把一个MP4视频AVI格式,或者将一个WAV音频文件MP3格式,以满足不同设备或应用程序的需求。 jave-1.0.2.jar库还提供了对音频和视频文件的基本编辑功能。我们可以使用该库对音频文件进行剪辑、合并或添加特定效果。对于视频文件,我们可以从中截取某个片段或者添加滤镜和场效果。 总之,jave-1.0.2.jar是一个功能丰富的Java库文件,能够轻松地处理音频和视频文件。它提供了一系列的类和方法,使得开发者能够方便地读取、写入、换和编辑各种音视频文件格式。无论是提取音频换文件格式还是进行基本的编辑,jave-1.0.2.jar都是一个强大而实用的工具。 ### 回答2: jave-1.0.2.jar是一个Java程序库,用于处理音频和视频文件。它提供了一组API,可以用于解码、码、剪辑和合并音视频文件。这个库的主要目的是简化开发人员处理音视频文件的过程,使其更加高效和方便。 使用jave-1.0.2.jar,开发人员可以轻松地读取音视频文件的信息并对其进行操作。它支持多种常见的音视频编码格式,如MP3、WAV、AVI、MP4等。开发人员可以使用这些功能来获取音视频文件的元数据,如持续时间、编码格式、比特率等,并可以根据需要进行换、剪辑或合并等操作。 除了基本的音视频处理功能,jave-1.0.2.jar还提供了一些其他有用的功能。例如,它可以生音频波形图,以便开发人员可以更好地分析音频数据。此外,它还支持音频和视频的实时播放,可以在处理音视频文件时进行实时预览。 总之,jave-1.0.2.jar是一个强大且方便的音视频处理库,适用于需要处理音视频文件的Java项目。它提供了丰富的功能,可以帮助开发人员轻松地读取、码、剪辑和合并音视频文件,并支持实时预览和波形图生等功能。对于需要处理音视频文件的开发人员来说,jave-1.0.2.jar是一个非常有价值的工具。 ### 回答3: jave-1.0.2.jar是一个Java库文件,用于处理音频和视频文件的换和处理。它提供了一组方便的类和方法,使开发人员能够在Java应用程序中轻松地实现音频和视频文件的码、裁剪、合并等功能。 使用jave-1.0.2.jar,开发人员可以通过简单的代码调用其提供的方法来实现各种音视频处理需求。例如,可以使用该库将一个视频文件换为不同的格式,调整音频的音量,裁剪视频的特定片段,合并多个音频文件等等。 此外,jave-1.0.2.jar还提供了一些额外的功能,如从视频文件中提取出音频流,从音频文件中提取出波形数据等等。这些功能可以帮助开发人员更好地理解音频和视频文件的结构,进一步扩展和定制处理的能力。 总之,jave-1.0.2.jar是一个强大的Java库,适用于需要处理音频和视频文件的应用程序开发。它提供了丰富的功能和易于使用的接口,使得开发人员可以快速实现各种音视频处理需求。无论是码、剪辑、合并还是提取其他数据,jave-1.0.2.jar都可以在开发过程中提供很大的帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值