业务场景:

手机app端录音,然后上传至后台服务器,前端从后台服务器获取录音,在PC端WEB页面播放。

实际问题:

首先app录音文件默认是m4a格式,而在PC端WEB H5页面,<audio>标签并没有明确写着支持m4a格式,如果app端生成的录音不做相关设置,而用默认设置,在H5上确实是播放不了的。


其实一开始,我没有想太多,也是想着把m4a文件转成mp3给前台用。

在网上查了一番,很多都说用jave-1.0.2.2.jar,然而其实这个包很旧,而且在windows上是可以转,但centos8上不支m4a格式转码,在系统上有兼容性问题。信我,别用它

然后又在码库里找了比较靠谱的是这个包,这里附个链接: https://github.com/a-schild/jave2,这个包也是基于ffmpeg的,提供了支持win64、osx64、linux64的依赖,建义在maven打包时,根据开发或生产环境的不同,打包时引用相应环境的依赖。

下面附上我的m4a转mp3的java代码:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com</groupId><artifactId>test</artifactId><version>1.0.0-SNAPSHOT</version><packaging>pom</packaging><properties>       <jave.version>2.7.1</jave.version></properties><dependencyManagement><dependencies>           <!--录音转换,jave-all-deps 包涵了所有平台的依赖,由于打包太大,建议打包时选指定的依赖--><!--<dependency>--><!--<groupId>ws.schild</groupId>--><!--<artifactId>jave-all-deps</artifactId>--><!--<version>${jave.version}</version>--><!--</dependency>--><!--录音转换,指定平台依赖,jave-core必需指定--><dependency><groupId>it.sauronsoftware</groupId><artifactId>jave</artifactId><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>${jave.version}</version></dependency></dependencies></dependencyManagement><!--激活profile配置,用来切换不同环境的配置--><profiles><profile><id>dev</id><properties><profiles.actives>dev</profiles.actives></properties><activation><activeByDefault>true</activeByDefault><activeByDefault>false</activeByDefault></activation><dependencies><dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-linux64</artifactId><version>${jave.version}</version></dependency></dependencies></profile><profile><id>pro</id><properties><profiles.actives>pro</profiles.actives></properties><activation><activeByDefault>false</activeByDefault></activation><dependencies><dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-linux64</artifactId><version>${jave.version}</version></dependency></dependencies></profile><profile><id>test</id><properties><profiles.actives>test</profiles.actives></properties><activation><activeByDefault>true</activeByDefault></activation><dependencies><dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-win64</artifactId><version>${jave.version}</version></dependency></dependencies></profile></profiles></project>

录音文件转换代码:

package com.utils;import com.alibaba.fastjson.JSON;
import com.qirui.framework.common.base.syslog.SysLog;
import com.qirui.framework.common.base.syslog.SysLogAnnotation;
import com.qirui.framework.common.base.syslog.SysLogPrint;
import com.qirui.framework.common.utils.RequestUtil;
import org.springframework.stereotype.Component;
import ws.schild.jave.*;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;/*** @ClassName AudioTransUtil* @Description 录音转换* @Author admin* @Version 1.0.0**/
@Component
public class AudioTransUtil {static {// 项目是springboot jar包, jar包内的代码要读取外面文件夹的文件,需要处理一下读取路径,// 这里是把录音源文件和转换文件放在springboot jar包的同级文件夹下String path = AudioTransUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();if(path.contains("jar")){//file:/F:/ideaWorkspace/test/smp-admin/framework-client/target/framework-client-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/framework-service-0.0.1-SNAPSHOT.jar!///去掉 "file:"path = path.substring(path.indexOf("/"), path.length());}if(System.getProperty("os.name").contains("dows")) {path = path.substring(1, path.length());//widonws的jar包if(path.contains("jar")){path = path.substring(0, path.indexOf(".jar"));rootPath = path.substring(0, path.lastIndexOf("/"));}else{rootPath =  path.replace("/target/classes/", "");}}else if(System.getProperty("os.name").contains("Mac")){rootPath = path.replace("/target/classes/", "");}else {path = path.substring(0, path.indexOf(".jar"));rootPath = path.substring(0, path.lastIndexOf("/"));}}protected static final String rootPath;/***目录路径*/private static final StringBuilder dirPathStr = new StringBuilder(rootPath).append("/temp/audio/");private static final String MP3 = "mp3";@SysLogAnnotation(descript = "录音转换格式")public String trans2Mp3(byte[] sourceAudioBytes, String sourceAudioName){//文件路径String soureAudioFilePathStr = new StringBuilder(dirPathStr).append(sourceAudioName).toString();String sourceAudioType = sourceAudioName.substring(sourceAudioName.indexOf(".")+1);String targetAudioFilePathStr = new StringBuilder(soureAudioFilePathStr).toString().replace(sourceAudioType, MP3);BufferedOutputStream bos = null;FileOutputStream fos = null;try{File dir = new File(dirPathStr.toString());if(!dir.exists()){dir.mkdirs();}File sourceAudioFile = new File(soureAudioFilePathStr);fos = new FileOutputStream(sourceAudioFile);bos = new BufferedOutputStream(fos);bos.write(sourceAudioBytes);File targetAudioFile = new File(targetAudioFilePathStr);AudioAttributes audioAttributes = new AudioAttributes();audioAttributes.setCodec("libmp3lame");audioAttributes.setBitRate(new Integer(32000));
//            audioAttributes.setChannels(new Integer(2));
//            audioAttributes.setSamplingRate(new Integer(22050));EncodingAttributes attrs = new EncodingAttributes();attrs.setFormat("mp3");attrs.setAudioAttributes(audioAttributes);Encoder encoder = new Encoder();//在有需要时添加,可根据不同系统环境,查看支持处理的文件格式System.out.println("encoder.getVideoDecoders():" + JSON.toJSON(encoder.getVideoDecoders()).toString());System.out.println("encoder.getSupportedDecodingFormats():" + JSON.toJSON(encoder.getSupportedDecodingFormats()).toString());MyJaveListener myJaveListener = new MyJaveListener();encoder.encode(new MultimediaObject(sourceAudioFile), targetAudioFile, attrs, myJaveListener);}catch (Exception e){e.printStackTrace();}finally {try {if(null != bos){bos.close();}if(null != fos){fos.close();}} catch (IOException e) {e.printStackTrace();}}SysLog sysLog = new SysLog();sysLog.setLogId(RequestUtil.getAccessLogId());sysLog.setParams(targetAudioFilePathStr);sysLog.setDescript("录音转换路径");SysLogPrint.printSysLogBody(sysLog);return targetAudioFilePathStr;}// 删除本地临时录音public void deleteTempAudio(String fileName){//文件路径String fileNameTemp = fileName.substring(fileName.lastIndexOf("/")+1, fileName.length());String soureAudioFilePathStr = new StringBuilder(dirPathStr).append(fileNameTemp).toString();String sourceAudioType = fileName.substring(fileName.indexOf(".")+1);String targetAudioFilePathStr = new StringBuilder(soureAudioFilePathStr).toString().replace(sourceAudioType, MP3);File file = new File(soureAudioFilePathStr);file.delete();file = new File(targetAudioFilePathStr);file.delete();}/*** 录音转码处理监听器,可监听文件处理结果,对于错误信息很有用*/private class MyJaveListener implements EncoderProgressListener {@Overridepublic void sourceInfo(MultimediaInfo multimediaInfo) {System.out.println("MyListener.sourceInfo:" + JSON.toJSON(multimediaInfo).toString());}@Overridepublic void progress(int i) {System.out.println("MyListener.progress:" + i);}@Overridepublic void message(String s) {System.out.println("MyListener.message:" + s);}}
}

上面的代码,在centos8环境是可以正常转换的,开一始,我的生产环境也用了这份。


后来,我去找了m4a和mp3、mp4的区别,发现 mp4是使用了MPEG-4进行封装的AAC编码,而M4A的本质和音频MP4相同,它是区别纯音频MP4文件和包含视频的MP4文件而由苹果(Apple)公司使用的扩展名。

那么疑问来了,竟然m4a和mp4的本质相同,那么竟然浏览器H5可以播放mp4,为什么m4a不行,原因在音频的编码上,AAC编码是解决问题的关键。

下面附上安卓内部输出录音代码中的几个关键截图:

默认如果不设置,AudioEncoder是0,0并不是AAC编码,我们需要在输出格式上设置MPEG_4,并把编码格式设置成AAC,

如第三图中所示:

setOutPutFormat(MediaRecorder.OutputFormat.MPEG_4)

setAudioEncoder(MediaRecorder.AudioEncoder.AAC)

这样,生成的m4a录音文件,就可以直接在浏览器H5页面中播放了,完全不需要后台,在整个程序个不仅少了代码的转码时间,本身m4a文件也很小。

如有帮助,请不吝打赏,谢谢。

H5页面播放M4a音频文件相关推荐

  1. 使用微信API实现H5页面播放音频文件

    之前在处理H5页面播放音频文件的时候,总是需要搞一个https才能正常播放,一次无意浏览到了一个自动播放音频的页面,发现了使用微信Api可以不使用https也能播放音频文件.作为记录,简单页面实现如下 ...

  2. 实现在线播放Wav音频文件,支持IE和Google

    最近在弄一个在线播放Wav音频文件的功能,发现audio只支持在google浏览器下才能访问,ie是不支持的,但是ie支持embed标签的播放. getWebIE:function(){var use ...

  3. h5页面怎么处理文件流_一种H5页面效果生成视频文件的方法及系统与流程

    本发明涉及计算机技术领域,尤其涉及一种H5页面效果生成视频文件的方法及系统. 背景技术: 现有的视频合成方法均是将视频需要合成的各个元素拆分出来,针对每个元素进行合成视频,复杂度高,一旦需要添加新的动 ...

  4. Java 采集声音_通过java采集PC麦克风音频及播放wav音频文件

    AudioFormat对象 sampleRate 采样率 每秒音频采样数量 sampleSizeInBits 采样位数 每个采样的位数 channels 声道 1: Mono 单声道,2:Stereo ...

  5. Python播放MP3音频文件

    Python播放MP3音频文件(转载) 按推荐顺序排列 ①使用playsound库 from playsound import playsoundplaysound('xx.mp3') ②使用pyga ...

  6. Linux下使用C++播放wav音频文件

    Linux下使用C++播放wav音频文件 安装openal第三方库 上代码 安装openal第三方库 unbuntu下安装命令:sudo apt-get install libopenal-dev 安 ...

  7. windows下使用Qt播放PCM音频文件(通过QAudioOutput和QIODevice)

    在博主之前的博文<windows下使用FFmpeg生成PCM音频文件并播放(通过命令的方式)>(链接https://blog.csdn.net/u014552102/article/det ...

  8. AVAudioPlayer播放在线音频文件

    AVAudioPlayer播放在线音频文件 一:原里: AVAudioPlayer是不支持播放在线音频的,但是AVAudioPlayer有一个 initWithData的方法:我们可以把在线音频转换为 ...

  9. iOS用AVAudioPlayer播放m4a音频

    音频文件sound.m4a放到Supporting Files目录 引用头文件 #import <AVFoundation/AVFoundation.h> 定义一个全局的属性: @prop ...

最新文章

  1. codeigniter mysql -1_在CodeIgniter中使用现有的MySQL数据库
  2. IAR7.51提示秘钥无效IAR 以及 CCDebug驱动(包含win7 64bit)
  3. 19) maven 项目结构:聚集
  4. Pytorch 基本概念
  5. pythoncanny边缘检测自适应阈值_一种自适应阈值的Canny边缘检测算法
  6. Mujoco安装 最简单方法
  7. 数据可视化实验一之单变量数据的统计图表可视化
  8. 音视频技术开发周刊 | 247
  9. python点图为什么显示不出来怎么办_Python底图不显示打印的点
  10. 设置elment ui plus 的el table的边框线
  11. h5中返回上一页常见的问题
  12. [日推荐]『忆年共享空间』小而美的私密相册空间
  13. 我为什么反对提“全栈工程师”?
  14. windows全局激活conda(包括cmd,powershell,pycharm)
  15. java面试题 sql_SQL 面试题目及答案 | java面试题
  16. java 图片 rgb_简单的java图片处理——如何用Java读出一张图片的RGB值?
  17. JS判断日期是否超过六个月
  18. 海外版“双十一”;广发一张卡,国内国外无差别使用;分期无手续费。
  19. 运筹说 第83期丨我国网络计划奠基人——华罗庚
  20. 详解SYN Flood攻击原理与防范

热门文章

  1. 年底买基金的六大建议!
  2. Redis开发设计规范及案例分析
  3. nextclou安装配置和优化
  4. Spring-Redis实现分布式环境下主子域名Session共享
  5. 如何寻找适合的投稿SCI期刊
  6. iOS保存图片到相册
  7. 数据挖掘常用算法总结
  8. x265 命令行参数大全
  9. VBA和Python双语对照,Excel编程学习更简单
  10. JOJ——基于爬虫的在线测评系统(Online Judge)