• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    Html5页面播放M4a音频文件

    发布者: 涵韵 | 发布时间: 2025-6-16 12:25| 查看数: 110| 评论数: 0|帖子模式

    业务场景:

    手机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
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <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">
    3.         <modelVersion>4.0.0</modelVersion>
    4.        
    5.         <groupId>com</groupId>
    6.         <artifactId>test</artifactId>
    7.         <version>1.0.0-SNAPSHOT</version>
    8.         <packaging>pom</packaging>

    9.     <properties>      
    10.         <jave.version>2.7.1</jave.version>
    11.     </properties>

    12.         <dependencyManagement>
    13.                 <dependencies>           
    14.             <!--录音转换,jave-all-deps 包涵了所有平台的依赖,由于打包太大,建议打包时选指定的依赖-->
    15.             <!--<dependency>-->
    16.                 <!--<groupId>ws.schild</groupId>-->
    17.                 <!--<artifactId>jave-all-deps</artifactId>-->
    18.                 <!--<version>${jave.version}</version>-->
    19.             <!--</dependency>-->
    20.             <!--录音转换,指定平台依赖,jave-core必需指定-->
    21.             <dependency>
    22.                 <groupId>it.sauronsoftware</groupId>
    23.                 <artifactId>jave</artifactId>
    24.                 <groupId>ws.schild</groupId>
    25.                 <artifactId>jave-core</artifactId>
    26.                 <version>${jave.version}</version>
    27.             </dependency>
    28.         </dependencies>
    29.     </dependencyManagement>

    30.    
    31.     <!--激活profile配置,用来切换不同环境的配置-->
    32.     <profiles>
    33.         <profile>
    34.             <id>dev</id>
    35.             <properties>
    36.                 <profiles.actives>dev</profiles.actives>
    37.             </properties>
    38.             <activation>
    39.                 <activeByDefault>true</activeByDefault>
    40.                 <activeByDefault>false</activeByDefault>
    41.             </activation>
    42.             <dependencies>
    43.                 <dependency>
    44.                     <groupId>ws.schild</groupId>
    45.                     <artifactId>jave-nativebin-linux64</artifactId>
    46.                     <version>${jave.version}</version>
    47.                 </dependency>
    48.             </dependencies>
    49.         </profile>

    50.         <profile>
    51.             <id>pro</id>
    52.             <properties>
    53.                 <profiles.actives>pro</profiles.actives>
    54.             </properties>
    55.             <activation>
    56.                 <activeByDefault>false</activeByDefault>
    57.             </activation>
    58.             <dependencies>
    59.                 <dependency>
    60.                     <groupId>ws.schild</groupId>
    61.                     <artifactId>jave-nativebin-linux64</artifactId>
    62.                     <version>${jave.version}</version>
    63.                 </dependency>
    64.             </dependencies>
    65.         </profile>

    66.         <profile>
    67.             <id>test</id>
    68.             <properties>
    69.                 <profiles.actives>test</profiles.actives>
    70.             </properties>
    71.             <activation>
    72.                 <activeByDefault>true</activeByDefault>
    73.             </activation>
    74.             <dependencies>
    75.                 <dependency>
    76.                     <groupId>ws.schild</groupId>
    77.                     <artifactId>jave-nativebin-win64</artifactId>
    78.                     <version>${jave.version}</version>
    79.                 </dependency>
    80.             </dependencies>
    81.         </profile>
    82.     </profiles>

    83. </project>
    复制代码
    录音文件转换代码:
    1. package com.utils;

    2. import com.alibaba.fastjson.JSON;
    3. import com.qirui.framework.common.base.syslog.SysLog;
    4. import com.qirui.framework.common.base.syslog.SysLogAnnotation;
    5. import com.qirui.framework.common.base.syslog.SysLogPrint;
    6. import com.qirui.framework.common.utils.RequestUtil;
    7. import org.springframework.stereotype.Component;
    8. import ws.schild.jave.*;

    9. import java.io.BufferedOutputStream;
    10. import java.io.File;
    11. import java.io.FileOutputStream;
    12. import java.io.IOException;

    13. /**
    14. * @ClassName AudioTransUtil
    15. * @Description 录音转换
    16. * @Author admin
    17. * @Version 1.0.0
    18. **/
    19. @Component
    20. public class AudioTransUtil {
    21.     static {
    22.     // 项目是springboot jar包, jar包内的代码要读取外面文件夹的文件,需要处理一下读取路径,
    23.     // 这里是把录音源文件和转换文件放在springboot jar包的同级文件夹下
    24.         String path = AudioTransUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();

    25.         if(path.contains("jar")){
    26.             //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!/
    27.             //去掉 "file:"
    28.             path = path.substring(path.indexOf("/"), path.length());
    29.         }
    30.         if(System.getProperty("os.name").contains("dows")) {
    31.             path = path.substring(1, path.length());
    32.             //widonws的jar包
    33.             if(path.contains("jar")){
    34.                 path = path.substring(0, path.indexOf(".jar"));
    35.                 rootPath = path.substring(0, path.lastIndexOf("/"));
    36.             }else{
    37.                 rootPath =  path.replace("/target/classes/", "");
    38.             }
    39.         }else if(System.getProperty("os.name").contains("Mac")){
    40.             rootPath = path.replace("/target/classes/", "");
    41.         }
    42.         else {
    43.             path = path.substring(0, path.indexOf(".jar"));
    44.             rootPath = path.substring(0, path.lastIndexOf("/"));
    45.         }
    46.     }


    47.     protected static final String rootPath;
    48.     /**
    49.      *目录路径
    50.      */
    51.     private static final StringBuilder dirPathStr = new StringBuilder(rootPath).append("/temp/audio/");
    52.     private static final String MP3 = "mp3";

    53.     @SysLogAnnotation(descript = "录音转换格式")
    54.     public String trans2Mp3(byte[] sourceAudioBytes, String sourceAudioName){
    55.         //文件路径
    56.         String soureAudioFilePathStr = new StringBuilder(dirPathStr).append(sourceAudioName).toString();
    57.         String sourceAudioType = sourceAudioName.substring(sourceAudioName.indexOf(".")+1);
    58.         String targetAudioFilePathStr = new StringBuilder(soureAudioFilePathStr).toString().replace(sourceAudioType, MP3);

    59.         BufferedOutputStream bos = null;
    60.         FileOutputStream fos = null;
    61.         try{
    62.             File dir = new File(dirPathStr.toString());
    63.             if(!dir.exists()){
    64.                 dir.mkdirs();
    65.             }

    66.             File sourceAudioFile = new File(soureAudioFilePathStr);
    67.             fos = new FileOutputStream(sourceAudioFile);
    68.             bos = new BufferedOutputStream(fos);
    69.             bos.write(sourceAudioBytes);

    70.             File targetAudioFile = new File(targetAudioFilePathStr);

    71.             AudioAttributes audioAttributes = new AudioAttributes();
    72.             audioAttributes.setCodec("libmp3lame");
    73.             audioAttributes.setBitRate(new Integer(32000));
    74. //            audioAttributes.setChannels(new Integer(2));
    75. //            audioAttributes.setSamplingRate(new Integer(22050));

    76.             EncodingAttributes attrs = new EncodingAttributes();
    77.             attrs.setFormat("mp3");
    78.             attrs.setAudioAttributes(audioAttributes);

    79.             Encoder encoder = new Encoder();

    80.             //在有需要时添加,可根据不同系统环境,查看支持处理的文件格式
    81.             System.out.println("encoder.getVideoDecoders():" + JSON.toJSON(encoder.getVideoDecoders()).toString());
    82.             System.out.println("encoder.getSupportedDecodingFormats():" + JSON.toJSON(encoder.getSupportedDecodingFormats()).toString());

    83.             MyJaveListener myJaveListener = new MyJaveListener();

    84.             encoder.encode(new MultimediaObject(sourceAudioFile), targetAudioFile, attrs, myJaveListener);
    85.         }catch (Exception e){
    86.             e.printStackTrace();
    87.         }finally {
    88.             try {
    89.                 if(null != bos){
    90.                     bos.close();
    91.                 }
    92.                 if(null != fos){
    93.                     fos.close();
    94.                 }
    95.             } catch (IOException e) {
    96.                 e.printStackTrace();
    97.             }
    98.         }

    99.         SysLog sysLog = new SysLog();
    100.         sysLog.setLogId(RequestUtil.getAccessLogId());
    101.         sysLog.setParams(targetAudioFilePathStr);
    102.         sysLog.setDescript("录音转换路径");
    103.         SysLogPrint.printSysLogBody(sysLog);

    104.         return targetAudioFilePathStr;
    105.     }

    106.     // 删除本地临时录音
    107.     public void deleteTempAudio(String fileName){
    108.         //文件路径
    109.         String fileNameTemp = fileName.substring(fileName.lastIndexOf("/")+1, fileName.length());
    110.         String soureAudioFilePathStr = new StringBuilder(dirPathStr).append(fileNameTemp).toString();
    111.         String sourceAudioType = fileName.substring(fileName.indexOf(".")+1);
    112.         String targetAudioFilePathStr = new StringBuilder(soureAudioFilePathStr).toString().replace(sourceAudioType, MP3);

    113.         File file = new File(soureAudioFilePathStr);
    114.         file.delete();
    115.         file = new File(targetAudioFilePathStr);
    116.         file.delete();
    117.     }

    118.     /**
    119.      * 录音转码处理监听器,可监听文件处理结果,对于错误信息很有用
    120.      */
    121.     private class MyJaveListener implements EncoderProgressListener {
    122.         @Override
    123.         public void sourceInfo(MultimediaInfo multimediaInfo) {
    124.             System.out.println("MyListener.sourceInfo:" + JSON.toJSON(multimediaInfo).toString());
    125.         }

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

    130.         @Override
    131.         public void message(String s) {
    132.             System.out.println("MyListener.message:" + s);
    133.         }
    134.     }
    135. }
    复制代码
    上面的代码,在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,
    如第三图中所示:
    1. setOutPutFormat(MediaRecorder.OutputFormat.MPEG_4)

    2. setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
    复制代码
    这样,生成的m4a录音文件,就可以直接在浏览器H5页面中播放了,完全不需要后台,在整个程序个不仅少了代码的转码时间,本身m4a文件也很小。
    到此这篇关于Html5页面播放M4a音频文件的文章就介绍到这了,更多相关Html5播放M4a 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

    来源:https://www.jb51.net/html5/768832.html
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表