Bootstrap

【Vue】audio标签播放amr音频文件

一. 需求

前端播放 amr 音频文件,想使用 audio标签(该标签支持 mp3、ogg 和 wav格式)

二. 思路

  1. 最初,设想的是java端将 amr 音频文件转为 mp3,但是实践了一下 基本都是要基于 ffmpeg,不想整那么麻烦,所以就想着前端处理。(以下大致实现写了下,但必须有 ffmpeg)。如下 2.1示例
    技术:Vue2 + ffmpeg + jave
  2. 然后,前端想使用 audio 标签,但是呢该标签不支持播放 amr,因此想着把 amr 转换为 wav或mp3。如下 2.2 将 amr 转为 wav
    技术:Vue2 + amrnb.js

2.1 基于 ffmpeg 将 amr转为 mp3

  1. 先准备好 ffmpeg (因本人没有实践,就不过多介绍了)
  2. 下载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>
  1. 实现
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
  1. 使用 amrnb.js 库,链接地址:点击跳转下载
  2. 跳转到以上链接后,使用git拉取代码/下载zip文件
    在这里插入图片描述
  3. 将 步骤 2 的 js放于 public/static 下
    在这里插入图片描述
  4. 在index.html文件中添加 步骤2 的路径
    在这里插入图片描述
  5. 实现
    (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>

;