在 ios 和 macos 上解码 .mov 文件时出错 - 在 React 应用程序中处理音频数据时出现 DOMException

问题描述 投票:0回答:1

我正在开发一个 React 应用程序,该应用程序可以处理视频文件并提取音频进行分析。该应用程序在大多数平台上运行良好,但当我尝试在 iPhone 和 Mac 上上传和处理 .mov 文件时,遇到以下错误:

Error decoding audio data: DOMException
Error processing file: DOMException

工作原理:

  1. 视频文件已上传。

  2. 视频文件被转换为数组缓冲区。

  3. 数组缓冲区被传递给 Web Audio API 的

    decodeAudioData
    函数以提取音频数据。

下面是我的代码的一部分

const extractAudioFromVideo = async (file) => {
  return new Promise((resolve, reject) => {
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    const reader = new FileReader();

    reader.onload = function () {
      const arrayBuffer = reader.result;

      audioContext.decodeAudioData(arrayBuffer).then((decodedAudioData) => {
        const offlineAudioContext = new OfflineAudioContext(
          decodedAudioData.numberOfChannels,
          decodedAudioData.duration * decodedAudioData.sampleRate,
          decodedAudioData.sampleRate
        );
        const soundSource = offlineAudioContext.createBufferSource();
        soundSource.buffer = decodedAudioData;
        soundSource.connect(offlineAudioContext.destination);
        soundSource.start();

        offlineAudioContext.startRendering().then((renderedBuffer) => {
          const wavBlob = audioBufferToWav(renderedBuffer);
          resolve(wavBlob);
        }).catch((err) => {
          console.error('Error during offline audio rendering:', err);
          reject(err);
        });
      }).catch((err) => {
        console.error('Error decoding audio data:', err);
        reject(err);
      });
    };

    reader.onerror = function (err) {
      console.error('Error reading file:', err);
      reject(err);
    };

    reader.readAsArrayBuffer(file);
  });
};

可能导致此

DOMException
错误的原因是什么,如何解决?

附加信息:

  • 此问题特定于 iPhone 上的 .mov 文件。

  • 其他视频格式和平台工作正常。

javascript ios reactjs file error-handling
1个回答
0
投票

考虑使用像 ffmpeg.js 这样的库直接在浏览器中处理音频文件的解码和转换。这可以绕过 Web Audio API 的一些限制。

// Example using ffmpeg.js
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';

const ffmpeg = createFFmpeg({ log: true });

const extractAudio = async (file) => {
  await ffmpeg.load();
  ffmpeg.FS('writeFile', 'input.mov', await fetchFile(file));
  await ffmpeg.run('-i', 'input.mov', '-q:a', '0', '-map', 'a', 'output.mp3');
  const data = ffmpeg.FS('readFile', 'output.mp3');

  const audioBlob = new Blob([data.buffer], { type: 'audio/mp3' });
  return audioBlob;
};

© www.soinside.com 2019 - 2024. All rights reserved.