Html5页面播放M4a音频文件

2023-12-02 0 906

业务场景:

手机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 {
@Override
public void sourceInfo(MultimediaInfo multimediaInfo) {
System.out.println("MyListener.sourceInfo:" + JSON.toJSON(multimediaInfo).toString());
}

@Override
public void progress(int i) {
System.out.println("MyListener.progress:" + i);
}

@Override
public 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编码是解决问题的关键。

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

Html5页面播放M4a音频文件

Html5页面播放M4a音频文件

Html5页面播放M4a音频文件

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

如第三图中所示:

setOutPutFormat(MediaRecorder.OutputFormat.MPEG_4)

setAudioEncoder(MediaRecorder.AudioEncoder.AAC)

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

到此这篇关于Html5页面播放M4a音频文件的文章就介绍到这了,更多相关Html5播放M4a 内容请搜索悠久资源网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持悠久资源网!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 HTML5 Html5页面播放M4a音频文件 https://www.u-9.cn/sheji/html5/27652.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务