这里写目录标题
一. 需求
前端播放 amr 音频文件,想使用 audio标签(该标签支持 mp3、ogg 和 wav格式)
二. 思路
- 最初,设想的是java端将 amr 音频文件转为 mp3,但是实践了一下 基本都是要基于 ffmpeg,不想整那么麻烦,所以就想着前端处理。(以下大致实现写了下,但必须有 ffmpeg)。如下 2.1示例
技术:Vue2 + ffmpeg + jave - 然后,前端想使用 audio 标签,但是呢该标签不支持播放 amr,因此想着把 amr 转换为 wav或mp3。如下 2.2 将 amr 转为 wav
技术:Vue2 + amrnb.js
2.1 基于 ffmpeg 将 amr转为 mp3
- 先准备好 ffmpeg (因本人没有实践,就不过多介绍了)
- 下载jar包并置于项目中
(1)下载路径:点击跳转
(2)下载压缩包
(3)解压压缩包并找到jar包
(4)放在java项目中
(5)pom.xml文件导入该依赖
<dependency>
<groupId>jave</groupId>
<artifactId>jave</artifactId>
<version>1.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/jave-1.0.2.jar</systemPath>
</dependency>
- 实现
package com.sihongan.emergdrillbox.utils.fileUtil;
import it.sauronsoftware.jave.*;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.File;
import java.io.IOException;
@Component
public class AudioFileConversionUtil {
public static File convertAudioToMp3(MultipartFile multipartFile) throws IllegalAccessException, IOException, UnsupportedAudioFileException, EncoderException {
if(multipartFile == null){
throw new IllegalAccessException("File is null");
}
// MultipartFile 转为 File 格式
File file = new File(multipartFile.getOriginalFilename());
multipartFile.transferTo(file);
// 临时存放地址
String tempPath = "D:\\tempAudio.mp3";
File target = new File(tempPath);
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
Encoder encoder = new Encoder();
encoder.encode(file, target, attrs);
return target;
}
}
2.2. 使用 amrnb.js 将 amr 转为 wav
2.2.1 路径地址转wav
- 使用 amrnb.js 库,链接地址:点击跳转下载
- 跳转到以上链接后,使用git拉取代码/下载zip文件
- 将 步骤 2 的 js放于 public/static 下
- 在index.html文件中添加 步骤2 的路径
- 实现
(1)音频链接(http://1xxx.vod2.myqcloud.com/xxxx/xxx/xxx.amr) 转为 wav
(2)思路:先通过链接获取文件内容,再将该内容转为 File 文件,最后将 File 转为 wav
<template>
<div>
<audio v-if="audioUrl != ''" id="audioPlayer" ref="audioPlayer" controls></audio>
</div>
</template>
<script>
// 禁用eslint
/* eslint-disable */
import { getDetail,getAudioUrl } from '@/api/xxx'
export default{
data(){
return{
audioUrl:''
}
},
watch:{
$route:{
handler(route){
this.fetchData(route.params.id,route.params.dataId)
}
}
},
methods:{
fetchData(id,dataId){
Promise.all([getDetail(id),getAudioUrl(dataId)]).then(res=>{
this.fileConver(res[1].audioUrl)
})
},
fileConver(audioURL) {
// 获取文件内容
this.fetchFileAndCreateBlob(audioURL).then((blob) => {
// 创建一个伪造的File对象
const file = new File([blob], 'file.amr', { type: 'audio/amr' })
// 将amr格式的音频文件转为wav格式
this.amrConvertWav(file)
})
},
fetchFileAndCreateBlob(fileUrl) {
return fetch(fileUrl).then((response) => response.blob()).then((blob) => blob)
},
//文件格式转化 amr-wav
amrConvertWav(file) {
const audioElement = document.getElementById('audioPlayer')
if (!file) {
audioElement.src = ''
return
}
const reader = new FileReader()
reader.onload = function (e) {
if (file.name.indexOf('.amr') !== -1) {
const data = new Uint8Array(e.target.result)
if (AMRWB.getAMRHeader(data) === AMRWB.AMR_HEADER) {
// 二进制文件头为:#!AMR-WB文件头
AMRWB.decodeInit()
const buffer = AMRWB.toWAV(data) // amr转wav
AMRWB.decodeExit()
const url = URL.createObjectURL(
new Blob([buffer], {
type: 'audio/wav',
})
)
audioElement.src = url
} else if (AMR.getAMRHeader(data) === AMR.AMR_HEADER) {
// 二进制文件头为:#!AMR文件头
const buffer = AMR.toWAV(data) // amr转wav
const url = URL.createObjectURL(
new Blob([buffer], {
type: 'audio/wav',
})
)
audioElement.src = url
} else {
alert('文件格式不支持!')
}
} else {
const buffer = e.target.result
const url = URL.createObjectURL(
new Blob([buffer], {
type: 'audio/x-wav',
})
)
audioElement.src = url
}
}
reader.readAsArrayBuffer(file)
},
}
}
</script>
2.2.1 File文件转wav
少了将 链接转File的步骤,直接传文件即可
<template>
<div>
<div>
<input type="file" onchange="fileChange(event)" accept=".mp3,.wav,.ogg,.amr,.m4a">
</div>
<audio id="audio" src="" controls></audio>
</div>
</template>
<script>
export default{
data(){
return{
}
},
methods:{
fileChange(e) {
const file = e.target.files[0]
const audioElement = document.getElementById('audio')
if (!file) {
audioElement.src = ''
return
}
const reader = new FileReader()
reader.onload = function(e) {
if (file.name.indexOf('.amr') !== -1) {
const data = new Uint8Array(e.target.result)
if (AMRWB.getAMRHeader(data) === AMRWB.AMR_HEADER) {
// #!AMR-WB文件头
AMRWB.decodeInit()
const buffer = AMRWB.toWAV(data) // amr转wav
AMRWB.decodeExit()
const url = URL.createObjectURL(new Blob([buffer], {
type: 'audio/wav'
}))
audioElement.src = url
} else if (AMR.getAMRHeader(data) === AMR.AMR_HEADER){
// #!AMR文件头
const buffer = AMR.toWAV(data) // amr转wav
const url = URL.createObjectURL(new Blob([buffer], {
type: 'audio/wav'
}))
audioElement.src = url
} else {
alert('文件格式不支持!')
}
} else {
const buffer = e.target.result
const url = URL.createObjectURL(new Blob([buffer], {
type: 'audio/x-wav'
}))
audioElement.src = url
}
}
reader.readAsArrayBuffer(file)
}
}
}
</script>