前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用jave2进行音频处理

利用jave2进行音频处理

作者头像
菩提树下的杨过
发布2021-05-07 15:07:41
2.3K0
发布2021-05-07 15:07:41
举报
文章被收录于专栏:菩提树下的杨过

很多朋友都知道,ffmpeg是一个功能强大的多媒体处理工具,可惜它并不是java语言开发,如果需要在java项目中使用时,得自己写很多代码,幸好github上有一个开源项目jave2 把ffmpeg做了封装,很大程度上简化了开发,使用方法如下:

先添加依赖项

代码语言:javascript
复制
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-all-deps</artifactId>
    <version>3.1.1</version>
</dependency>

以下是一些常用示例:

1、获取音频文件的编码信息

代码语言:javascript
复制
   MultimediaInfo getMediaInfo() {
        String sourceFilePath = "/Users/jimmy/Downloads/bgm.wav";
        File file = new File(sourceFilePath);
        if (file != null && file.exists()) {
            try {
                MultimediaObject multimediaObject = new MultimediaObject(file);
                MultimediaInfo m = multimediaObject.getInfo();
                return m;
            } catch (Exception e) {
                e.printStackTrace();

            }
        }
        return null;
    }

System.out.println(getMediaInfo()); 输出如下:

ws.schild.jave.info.MultimediaInfo (format=wav (metadata={encoder=Lavf58.27.103}, duration=101850, video=null, audio=ws.schild.jave.info.AudioInfo (decoder=pcm_s16le ([1][0][0][0] / 0x0001), samplingRate=44100, channels=2, bitRate=1411000))

从上面可以看出,该文件是wav格式,时长为101.850秒,编码格式为pcm_s16le,采集率为44100,双声道,bit率为1411000

2、wav转mp3

代码语言:javascript
复制
boolean convert2Mp3() {
        String sourceFilePath = "/Users/jimmy/Downloads/bgm.wav";
        String targetFilePath = "/Users/jimmy/Downloads/bgm.mp3";
        try {
            File source = new File(sourceFilePath);
            File target = new File(targetFilePath);

            //Audio Attributes
            AudioAttributes audio = new AudioAttributes();
            audio.setCodec("libmp3lame");
            audio.setBitRate(64000);
            audio.setChannels(2);
            audio.setSamplingRate(44100);

            //Encoding attributes
            EncodingAttributes attrs = new EncodingAttributes();
            attrs.setInputFormat("wav");
            attrs.setOutputFormat("mp3");
            attrs.setAudioAttributes(audio);

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

        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
        return true;
    }

3、转换编码格式

代码语言:javascript
复制
    static boolean changeCode() {
        String sourceFilePath = "/Users/jimmy/Downloads/bgm.wav";
        String targetFilePath = "/Users/jimmy/Downloads/bgm_2.wav";

        //Audio Attributes
        AudioAttributes audio = new AudioAttributes();
        audio.setCodec("pcm_u8");
        audio.setBitRate(64000);
        audio.setChannels(2);
        audio.setSamplingRate(8000);

        //Encoding attributes
        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setInputFormat("wav");
        attrs.setOutputFormat("wav");
        attrs.setAudioAttributes(audio);

        //Encode
        Encoder encoder = new Encoder();
        try {
            encoder.encode(new MultimediaObject(new File(sourceFilePath)), new File(targetFilePath), attrs);

            //辅助输出,观察编码格式的变化
            MultimediaObject srcObj = new MultimediaObject(new File(sourceFilePath));
            MultimediaObject targetObj = new MultimediaObject(new File(targetFilePath));
            System.out.println(srcObj.getInfo());
            System.out.println(targetObj.getInfo());
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
        return true;
    }

第7行,设置了新的编码pcm_u8

4、分离左右声道

代码语言:javascript
复制
boolean splitChannel() {
        String source = "/Users/jimmy/Downloads/bgm.wav";
        String left = "/Users/jimmy/Downloads/bgm_left.wav";
        String right = "/Users/jimmy/Downloads/bgm_right.wav";
        File leftFile = new File(left);
        File rightFile = new File(right);
        if (leftFile.exists()) {
            leftFile.delete();
        }

        if (rightFile.exists()) {
            rightFile.delete();
        }
        DefaultFFMPEGLocator locator = new DefaultFFMPEGLocator();
        ProcessWrapper ffmpeg = locator.createExecutor();
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(source);
        ffmpeg.addArgument("-map_channel");
        ffmpeg.addArgument("0.0.0");
        ffmpeg.addArgument(left);
        ffmpeg.addArgument("-map_channel");
        ffmpeg.addArgument("0.0.1");
        ffmpeg.addArgument(right);
        BufferedReader br = null;
        try {
            ffmpeg.execute();
            br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));
            String line;
            while ((line = br.readLine()) != null) {
                //输出处理过程中的日志(辅助观察处理过程)
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            //辅助输出,观察编码格式的变化
            MultimediaObject srcObj = new MultimediaObject(leftFile);
            MultimediaObject targetObj = new MultimediaObject(rightFile);
            System.out.println(srcObj.getInfo());
            System.out.println(targetObj.getInfo());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return true;
    }

声道分离后,会生成2个文件,分别对应于左右声道。

5、拼接音频(比如:把某段音频重复N次,合成1个新音频)

代码语言:javascript
复制
boolean mergeAudio() {
//        ffmpeg -i bullet.wav -i bullet.wav -i bullet.wav -filter_complex '[0:0] [1:0] concat=n=3:v=0:a=1 [a]' -map [a] bullet_3.wav

        //先生成要拼接的音频清单
        int times = 5;

        String src = "/Users/jimmy/Downloads/bullet.wav";
        String target = "/Users/jimmy/Downloads/bullet_" + times + ".wav";

        File targetFile = new File(target);
        if (targetFile.exists()) {
            targetFile.delete();
        }

        DefaultFFMPEGLocator locator = new DefaultFFMPEGLocator();
        ProcessWrapper ffmpeg = locator.createExecutor();
        for (int i = 1; i <= times; i++) {
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(src);
        }
        ffmpeg.addArgument("-filter_complex");
        ffmpeg.addArgument("[0:0] [1:0] concat=n=" + times + ":v=0:a=1 [a]");
        ffmpeg.addArgument("-map");
        ffmpeg.addArgument("[a]");

        ffmpeg.addArgument(target);
        BufferedReader br = null;
        try {
            ffmpeg.execute();
            br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));
            String line;
            while ((line = br.readLine()) != null) {
                //输出处理过程中的日志(辅助观察处理过程)
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

6、截取音频中的某一段

代码语言:javascript
复制
void cut() throws EncoderException {
        String src = "/Users/jimmy/Downloads/bgm.wav";
        String target = "/Users/jimmy/Downloads/bgm_1_3.wav";

        File targetFile = new File(target);
        if (targetFile.exists()) {
            targetFile.delete();
        }

        File srcFile = new File(src);
        MultimediaObject srcMultiObj = new MultimediaObject(srcFile);
        MultimediaInfo srcMediaInfo = srcMultiObj.getInfo();

        Encoder encoder = new Encoder();


        EncodingAttributes encodingAttributes = new EncodingAttributes();
        //设置起始偏移量(秒)
        encodingAttributes.setOffset(1.0F);
        //设置切片的音频长度(秒)
        encodingAttributes.setDuration(2.0F);

        //设置音频属性
        AudioAttributes audio = new AudioAttributes();
        audio.setBitRate(srcMediaInfo.getAudio().getBitRate());
        audio.setSamplingRate(srcMediaInfo.getAudio().getSamplingRate());
        audio.setChannels(srcMediaInfo.getAudio().getChannels());

        //如果截取的时候,希望同步调整编码,可以设置不同的编码
//        audio.setCodec("pcm_u8");
        audio.setCodec(srcMediaInfo.getAudio().getDecoder().split(" ")[0]);
        encodingAttributes.setInputFormat("wav");
        encodingAttributes.setAudioAttributes(audio);

        //写文件
        encoder.encode(srcMultiObj, new File(target), encodingAttributes);

    }

最后说一个可能会存在的问题:默认情况下,jave2在执行时,会把ffmpeg可执行文件释放到"java.io.tmpdir"临时目录下,但在tomcat等容器下执行时,如果启用tomcat的用户,与java应用的执行用户不同,可能会存在无写入权限的问题。遇到这种情况,可以先用代码把java.io.tmpdir这个系统变量,指到其它有权限的目录,执行完后,再还原回来

代码语言:javascript
复制
 String oldTmpDir = System.getProperty("java.io.tmpdir");
        try {
            System.setProperty("java.io.tmpdir", "有权限写入的新临时目录");
            // todo (jave2的其它处理)
        }  finally {
            System.setProperty("java.io.tmpdir", oldTmpDir);
        }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-05-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
多媒体处理
多媒体处理(Multimedia Processing,MMP)是数据万象推出的音视频处理服务,集成音视频转码、极速高清、精彩集锦、超分辨率、数字水印等能力,满足传媒、文旅、电商等各行业多媒体处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档