Html5頁面播放M4a音頻文件

業(yè)務場景:
手機app端錄音,然后上傳至后臺服務器,前端從后臺服務器獲取錄音,在PC端WEB頁面播放。
實際問題:
首先app錄音文件默認是m4a格式,而在PC端WEB H5頁面,<audio>標簽并沒有明確寫著支持m4a格式,如果app端生成的錄音不做相關設置,而用默認設置,在H5上確實是播放不了的。
其實一開始,我沒有想太多,也是想著把m4a文件轉成mp3給前臺用。
在網上查了一番,很多都說用jave-1.0.2.2.jar,然而其實這個包很舊,而且在windows上是可以轉,但centos8上不支m4a格式轉碼,在系統(tǒng)上有兼容性問題。信我,別用它。
然后又在碼庫里找了比較靠譜的是這個包,這里附個鏈接: https://github.com/a-schild/jave2,這個包也是基于ffmpeg的,提供了支持win64、osx64、linux64的依賴,建義在maven打包時,根據(jù)開發(fā)或生產環(huán)境的不同,打包時引用相應環(huán)境的依賴。
下面附上我的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配置,用來切換不同環(huán)境的配置--> <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(); //在有需要時添加,可根據(jù)不同系統(tǒng)環(huán)境,查看支持處理的文件格式 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(); } /** * 錄音轉碼處理監(jiān)聽器,可監(jiān)聽文件處理結果,對于錯誤信息很有用 */ 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環(huán)境是可以正常轉換的,開一始,我的生產環(huán)境也用了這份。
后來,我去找了m4a和mp3、mp4的區(qū)別,發(fā)現(xiàn) mp4是使用了MPEG-4進行封裝的AAC編碼,而M4A的本質和音頻MP4相同,它是區(qū)別純音頻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文件也很小。
到此這篇關于Html5頁面播放M4a音頻文件的文章就介紹到這了,更多相關Html5播放M4a 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持腳本之家!
相關文章
HTML5 video循環(huán)播放多個視頻的方法步驟
這篇文章主要介紹了HTML5 video循環(huán)播放多個視頻的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來2020-08-06HTML5 通過Vedio標簽實現(xiàn)視頻循環(huán)播放的示例代碼
這篇文章主要介紹了HTML5 通過Vedio標簽實現(xiàn)視頻循環(huán)播放的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨2020-08-05- 這篇文章主要介紹了HTML5播放實現(xiàn)rtmp流直播,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-16
html5視頻自動橫過來自適應頁面且點擊播放功能的實現(xiàn)
這篇文章主要介紹了h5視頻自動橫過來自適應頁面且點擊播放,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-03- 這篇文章主要介紹了html5中嵌入視頻自動播放的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起2020-05-25
html5 移動端視頻video的android兼容(去除播放控件、全屏)
這篇文章主要介紹了html5 移動端視頻video的android兼容,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起2020-03-26- 這篇文章主要介紹了HTML5自定義mp3播放器源碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-06
- 這篇文章主要介紹了HTML5自定義視頻播放器源碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-06
- 這篇文章主要介紹了html5自定義video標簽的海報與播放按鈕功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-04
解決HTML5中的audio在手機端和微信端的不能自動播放問題
這篇文章主要介紹了解決HTML5中的audio在手機端和微信端的不能自動播放問題,需要的朋友可以參考下2019-11-04