likes
comments
collection
share

🌟前端如何播放AMR格式的音频文件🌟## 前言 最近在做的一个需求里,有一个播放音频的功能。上游给到的音频文件是 `

作者站长头像
站长
· 阅读数 52

前言

最近在做的一个需求里,有一个播放音频的功能。上游给到的音频文件是 .amr 格式,我也是第一次见这种格式的音频。

我就像往常一样,直接通过一个 audio 标签来引入,结果发现根本播放不了。

import React from "react";

const Amr = () => {
  return (
    <div>
      <audio controls src="/test.amr"/>
    </div>
  );
};

export default Amr;

🌟前端如何播放AMR格式的音频文件🌟## 前言 最近在做的一个需求里,有一个播放音频的功能。上游给到的音频文件是 `

github.com/yxl/opencor…

在后续搜了一些资料发现,浏览器是不支持直接播放 amr 格式的音频的,需要转成 wav 或者 mp3 等格式。

常见的音频格式

以下是常见的一些音频格式以及他们的特点、优缺点,不感兴趣的同学可以直接跳过

  1. MP3 (MPEG-1 Audio Layer III) :

    • 特点:MP3 是最常见的音频格式之一,具有良好的压缩性能,能够显著减小音频文件的大小,同时保持相对较高的音质。
    • 优点:广泛支持,几乎所有的音频播放器都能够播放MP3格式的文件。适用于网络流媒体、音乐下载和存储等场景。
    • 缺点:MP3 是有损压缩格式,压缩过程中会损失一些音频信息,因此相对于无损格式,音质略有降低。
  2. AAC (Advanced Audio Coding) :

    • 特点:AAC 是一种高级音频编码格式,通常具有比MP3更高的音频质量,并且相对于相同音质的MP3文件,AAC文件的大小更小。
    • 优点:音质较好,文件大小相对较小,支持多通道编码(例如立体声和环绕声)。
    • 缺点:虽然AAC是一种有损压缩格式,但与MP3相比,AAC通常需要更多的计算资源进行编码和解码。
  3. WAV (Waveform Audio File Format) :

    • 特点:WAV 是一种无损音频格式,保留了音频文件的原始音频数据,因此音质非常高。
    • 优点:无损压缩,不会丢失任何音频信息,音质非常高,适用于专业音频录制和编辑。
    • 缺点:文件体积较大,不适合用于网络流媒体传输和存储。
  4. FLAC (Free Lossless Audio Codec) :

    • 特点:FLAC 是一种开源的无损音频编码格式,压缩率通常比WAV更高,但仍然保持了音频的完整性。
    • 优点:无损压缩,音质高,压缩率较高,适用于音乐存储和传输,尤其是对音频质量要求较高的场景。
    • 缺点:相对于有损格式如MP3和AAC,FLAC文件的解码需要更多的计算资源,不适合在资源受限的设备上播放。
  5. OGG (Ogg Vorbis) :

    • 特点:OGG 是一种自由、开放的多媒体容器格式,通常使用Vorbis音频编解码器来编码音频。
    • 优点:开源、免费,音质较好,支持标签和元数据,适用于网络音频流传输和存储。
    • 缺点:相对于MP3和AAC,OGG的普及率较低,不是所有的播放器都支持OGG格式。
  6. AMR(Adaptive Multi-Rate)

    • 特点:AMR是专门为语音信号设计的编码格式,因此对于语音的编码和解码具有良好的性能和效果。
    • 优点:由于AMR采用了有损压缩,因此生成的音频文件通常比较小,适合在网络传输和存储时节省带宽和空间,特别适用于语音通信场景,如手机通话、语音信箱等,能够提供较好的语音质量和效率
    • 缺点:虽然AMR的压缩效率较高,但在压缩过程中会丢失一些音频信息,因此相对于无损格式,音质会有所降低

上面提到的格式中,浏览器直接支持播放的有:

  1. MP3
  2. AAC
  3. OGG,在一些主流浏览器中被支持,如Firefox、Chrome等。但并非所有的浏览器都支持OGG格式。
  4. WAV

转码处理

也就是说我们需要把它转换成一些浏览器可以播放的格式,主要是使用到这个库——opencore-amr-js。它是一个 amr 解码器的 js 版本实现。

具体实现代码如下:

import React, { useEffect, useState } from "react";

const Amr = () => {
  const [url, setUrl] = useState("");

  const readBlob = (blob) => {
    return new Promise((resolve) => {
      const reader = new FileReader();
      reader.onload = function (e) {
        const data = new Uint8Array(e.target.result);
        resolve(data);
      };
      reader.readAsArrayBuffer(blob);
    });
  };
  const convertAmrToWav = async (origin) => {
    const res = await fetch(origin);
    const blob = await res.blob();
    const data = await readBlob(blob);
    const buffer = window.AMR.toWAV(data);
    const url = URL.createObjectURL(
      new Blob([buffer], { type: "audio/x-wav" })
    );
    setUrl(url);
  };

  useEffect(() => {
    convertAmrToWav("/test.amr");
  }, []);

  return (
    <div>
      <audio controls src={url} />
    </div>
  );
};

export default Amr;

实现过程如下:

  1. fetch 获取到音频的元数据
  2. 转成 Uint8Array 格式
  3. 调用 AMR 进行转换
  4. 播放

🌟前端如何播放AMR格式的音频文件🌟## 前言 最近在做的一个需求里,有一个播放音频的功能。上游给到的音频文件是 `

可以看到,可以正常播放了。

需要注意的是,这个包还是有点大的, gzip 压缩之后还有大概 140KB 左右。

需要注意的地方

由于我们需要 fetch 获取音频,但很多时候这种音频都是存在对象存储里面。我们的应用大概率跟对象存储是不同域的,这个时候 fetch 的时候就会被跨域策略拦截。

如果你是使用node来启动前端服务,那么可以按照下面类似的方式去配置:

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const path = require('path');

const app = express();

// 创建代理服务器
const proxyMiddleware = createProxyMiddleware({
  target: 'http://oss.com',
  changeOrigin: true,
  pathRewrite: { '^/source': '/source' },
});

// 将代理中间件应用于指定的路径
app.use('/source', proxyMiddleware);

// 将 dist 目录下的静态文件提供给客户端
app.use(express.static(path.join(__dirname, 'dist')));

// 启动 Express 服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Proxy server is running on port ${PORT}`);
});

假如说我们的音频地址是oss.com/source/audi… ,那么在前端 fetch 的时候就使用如下方式去请求:

fetch('/source/audio.amr')

还有一种是你使用 nginx 作为静态资源服务器,也是同样配置一个反向代理,大致的配置如下:

server {
    listen 80;  # 监听的端口号

    server_name your_domain.com;  

    location /oss {
        proxy_pass http://oss.com/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location / {
        alias /www/wwwroot/dist
    }
}

最好的方案

让后端把音频格式转成 wav 或者 mp3

最后

以上就是本文的全部内容,如果你觉得有意思的话,点点关注点点赞吧~

转载自:https://juejin.cn/post/7415911762129010688
评论
请登录