微信语音不再难播:React + benz-amr-recorder组合拳

667 阅读3分钟

一. 前言

近年来,语音通信越来越普及,尤其是微信的语音消息。然而,微信的语音消息采用的是AMR(Adaptive Multi-Rate)格式,这是一种无法直接在浏览器中播放的格式。要想在Web前端实现AMR微信语音播放,我们可以借助benz-amr-recorder库将AMR音频转换为浏览器兼容的音频格式。本文以一个React示例为引导,展示如何实现一个可以播放AMR格式语音的播放器。

二. 准备工作

1. 安装依赖

在您的React项目中运行以下命令以安装所需依赖:

# 使用npm
npm install benz-amr-recorder

# 使用yarn
yarn add benz-amr-recorder

2. 开发思路

为了使示例更接近实际应用场景,我们将实现以下功能:

  1. 上传本地AMR语音文件,预览并播放。
  2. 显示已上传的文件列表,点击文件名可以直接播放对应的语音。
  3. 对已上传的文件进行批量播放。

三. 实现AMR语音播放器

1. 创建AMR音频上传功能

创建一个AmrFileUpload.js文件,作为单独的上传组件,代码如下:

import React from 'react';

const AmrFileUpload = ({ onFileUpload }) => {
  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (file) {
      onFileUpload(file);
    }
  };

  return (
    <div>
      <input type="file" accept=".amr" onChange={handleFileChange} />
    </div>
  );
};

export default AmrFileUpload;

2. 创建文件列表显示组件

创建一个FileList.js文件,用来展示已上传的文件列表,代码如下:

import React from 'react';

const FileList = ({ fileList, onFileClick }) => {
  const handleClick = (file) => {
    onFileClick(file);
  };

  return (
    <div>
      <ul>
        {fileList.map((file, index) => (
          <li key={index} onClick={() => handleClick(file)}>
            {file.name}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default FileList;

3. 关联各部分并实现播放器组件

首先,在App.js文件中引入我们创建的组件,并添加各组件之间的交互功能。通过状态提升的方式将AmrFileUploadFileList组件所需数据传递给播放器组件。最后,利用benz-amr-recorder库解码AMR文件并播放。

代码如下:

// 引入依赖
import React, { useState } from 'react';
import AmrFileUpload from './AmrFileUpload';
import FileList from './FileList';
import Amr from 'benz-amr-recorder';

const App = () => {
  const [audioUrl, setAudioUrl] = useState(null);
  const [fileList, setFileList] = useState([]);

  // 监听文件上传并添加到文件列表
  const onFileUpload = (file) => {
    const newFileList = [...fileList, file];
    setFileList(newFileList);
  };

  // 加载并播放AMR音频
  async function loadAndPlay(file) {
    const reader = new FileReader();
    reader.onload = async (e) => {
      const blob = new Blob([e.target.result], { type: 'audio/amr' });

      const amr = new Amr();
      amr.initWithBlob(blob).then(() => {
        setAudioUrl(amr.getUrl());
      }).catch(err => {
        console.error('解码AMR音频失败:', err);
      });
    };
    reader.readAsArrayBuffer(file);
  }

  // 处理文件列表项点击事件
  const onFileClick = (file) => {
    loadAndPlay(file);
  };

  return (
    <div className="App">
      <AmrFileUpload onFileUpload={onFileUpload} />
      <FileList fileList={fileList} onFileClick={onFileClick} />
      {audioUrl && <audio src={audioUrl} controls />}
    </div>
  );
}

export default App;

四. 示例代码使用说明

  1. 确保已关闭浏览器跨域限制,因为本例中涉及到本地文件读取操作。
  2. AmrFileUpload.jsFileList.js组件放入React项目的src目录中,并在需要的地方导入使用。
  3. 运行React项目,你可以在页面上看到一个文件上传控件和一个文件列表区域。
  4. 通过文件上传控件,选择本地的AMR音频文件,文件名会显示在文件列表中。
  5. 点击文件列表中的文件名,将加载并播放对应的AMR音频。

五. 总结

通过使用benz-amr-recorder库,我们可以轻松实现AMR音频的解码和播放。我们通过不同的组件实现了播放器的功能,并通过状态提升的方式将它们关联在一起。