将amr格式的文件转码成mp3格式存储在自己服务器上的解决方案

1、需求简介

现在的需求是微信公众号内说一段话调用微信的上传接口上传至微信服务器,然后下载到我们本地,此时文件是amr格式,浏览器和很多播放器识别不了,需要转码成mp3格式,存储在我们的文件服务器上,现在在这里记录中间踩过的坑。

2、几个有用的调试技巧

微信上传语音文件的参考网址是:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#30

微信网页调试工具如下:https://mp.weixin.qq.com/debug/

amr文件下载地址:链接: https://pan.baidu.com/s/1bUohbqsF-1KV91g4Ra9Jsg 提取码: utpm 

下载文件要调用的微信服务器地址:http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s

其它的生成accesstoken这些不是本文的重点,不再展开。

3、使用java代码将amr格式的文本转成mp3

3.1、使用jave的jar包转储

引入jar包:

        <dependency>
            <groupId>com.github.dadiyang</groupId>
            <artifactId>jave</artifactId>
            <version>1.0.4</version>
        </dependency>

转码:

File source = new File(tempFilePath);
File target = new File(targetPath);
AudioUtils.amrToMp3(source, target);

参考文档:

https://blog.csdn.net/qllinhongyu/article/details/29817297

http://www.sauronsoftware.it/projects/jave/manual.php

3.2、使用jave-core转码

引入jar包:

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

转码:

public static void changeTemp() throws InputFormatException {
        File source = new File("/Users/daji/Downloads/1.amr");   //源文件
        File target = new File("/Users/daji/Downloads/1.mp3");   //目标文件
        AudioAttributes audio = new AudioAttributes();
        audio.setCodec("libmp3lame");
        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setFormat("mp3");
        attrs.setAudioAttributes(audio);
        Encoder encoder = new Encoder();
        try {

            MultimediaObject multimediaObject  = new MultimediaObject(source);
            encoder.encode(multimediaObject,target, attrs);
        } catch (IllegalArgumentException | EncoderException e) {
            e.printStackTrace();
        }

    }

参考文档:

https://www.jianshu.com/p/a9611651e95e

4、我的处理代码:

我是先把文件从微信服务器下载到本地服务器amr格式的,然后使用上面的工具转码成mp3格式的,之后将mp3文件上传到阿里oss上存储,并把本地的amr文件和mp3文件删除(防止占用磁盘)

4.1下载微信文件到本地:

    public InputStream downloadFileFromWechat(String serviceId) {
        log.info("desc:{},serviceId:{}", "准备连接微信服务器下载文件", serviceId);
        try {
            String accessToken = accessTokenUtil.getToken();
            String urlStr = String.format(WXApiConstant.DOWNLOAD_MEDIA_URL, accessToken, serviceId);
            URL url = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Charset", StandardCharsets.UTF_8.toString());
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.connect();
            InputStream inputStream = connection.getInputStream();
            return inputStream;
        } catch (Exception e) {
            log.info("desc:{},errMsg:{}", "下载微信文件至本地服务器失败", ExceptionUtils.getStackTrace(e));
            throw new BusinessException("下载微信文件至本地服务器失败:" + e.getMessage());
        }
    }

4.2生成文件名:

    public String getFilePath(String fileNamePrefix) {
        String baseFolder = "\\home\\comment"+ File.separator + "voice";
        Date nowDate = new Date();
        String fileFolder = baseFolder + File.separator + new DateTime(nowDate).toString("yyyy") + File.separator
                + new DateTime(nowDate).toString("MM") + File.separator + new DateTime(nowDate).toString("dd");
        File file = new File(fileFolder);
        if (!file.isDirectory()) {
            // 如果目录不存在,则创建目录
            file.mkdirs();
        }
        // 生成新的文件名--微信下载的文件格式为amr
        String fileName = fileNamePrefix + "." + "amr";
        return fileFolder + File.separator + fileName;
    }

4.3将文件存储到硬盘:

    public void saveToDisk(String mediaId,String filePath) {
        InputStream inputStream = this.downloadFileFromWechat(mediaId);
        try(FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
            byte[] data = new byte[8192];
            int len;
            while ((len = inputStream.read(data)) != -1) {
                fileOutputStream.write(data, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

4.4转码文件并上传到oss上,删除本地临时文件:

    public String saveVoiceUrl(String serviceId) throws Exception {
        String fileNamePrefix = String.valueOf(System.currentTimeMillis() + RandomUtils.nextInt(100, 9999));
        String tempFilePath = getFilePath(fileNamePrefix);
        String targetPath = tempFilePath.substring(0,tempFilePath.lastIndexOf('.'))+"."+"mp3";

        //临时保存在硬盘,amr格式,转成mp3格式,存储到oss上
        saveToDisk(serviceId,tempFilePath);

        File source = new File(tempFilePath);
        File target = new File(targetPath);
        AudioUtils.amrToMp3(source, target);

        //上传至oss,返回url
        ossProxy.saveObject(WECHAT_COMMENT_PATH + fileNamePrefix+"."+"mp3", FileCopyUtils.copyToByteArray(target), 1);

        String ossUrl = ossProxy.getUrl(WECHAT_COMMENT_PATH + fileNamePrefix+"."+"mp3", 1);

        //删除文件
        if (source.exists()) {
            boolean deleted = source.delete();
            if (!deleted) {
                log.error("desc:{}, filePath:{}", "语音下载上传至OSS完成,删除本地文件失败", source.getPath());
            }
        }
        if (target.exists()) {
            boolean deleted = target.delete();
            if (!deleted) {
                log.error("desc:{}, filePath:{}", "语音下载上传至OSS完成,删除本地文件失败", source.getPath());
            }
        }
        return ossUrl;
    }

补充:如果你存储在oss的文件地址在浏览器打不开,可以检查本地文件和oss文件的md5是否一样,我当时就是粗心文件copy错了,在线比对地址:http://www.atool9.com/file_hash.php

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、Java实现wav音频文件转换为pcm音频文件(AudioUtils.java) 2、Java实现播放pcm音频文件(PCMPlay.java) WAV:wav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范。所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。 PCM:PCM(Pulse Code Modulation----脉码调制录音)。所谓PCM录音就是将声音等模拟信号变符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构的数字信号,而未经过任何编码和压缩处理。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。 简单来说:wav是一种无损的音频文件格式,pcm是没有压缩的编码方式。 WAV和PCM的关系 WAV可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被PCM编码处理的WAV,但这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互转换之中,例如MP3转换WMA。 简单来说:pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值