如何使用JavaScript将录音的Blob流切分成多个5秒的WAV文件并确保其正常播放?

使用javascript切分录音的blob流并生成5秒的wav文件

在使用react-mic进行录音时,遇到一个需求:需要将录音的blob流切分成多个5秒的wav文件。然而,尝试之后发现只有第一个切分的wav文件能够正常播放,其余文件均提示文件损坏。

在前端实现这个需求时,主要面临两个挑战:一是如何正确切分blob流,二是如何确保每个切分后的片段能够正确生成并播放wav文件。以下是代码示例和解决思路:

import React, { useRef, useState } from 'react'import { ReactMic, ReactMicStopEvent } from 'react-mic'import { Button } from 'antd'const AudioRecorder = () => {    const [record, setRecord] = useState(false)    const resRef = useRef([])    const audioChunksRef = useRef([])    const intervalRef = useRef(null)    const firstBlob = useRef(undefined)    const createWavHeader = (numChannels, sampleRate, byteLength) => {        const header = new ArrayBuffer(44);        const view = new DataView(header);        view.setUint32(0, 1380533830, false); // "RIFF"        view.setUint32(4, byteLength + 36, false);        view.setUint32(8, 1718449184, false); // "WAVE"        view.setUint32(12, 1684108385, false); // "fmt "        view.setUint32(16, 16, true); // 16 for PCM        view.setUint16(20, 1, true); // PCM        view.setUint16(22, numChannels, true);        view.setUint32(24, sampleRate, true);        view.setUint32(28, sampleRate * numChannels * 2, true);        view.setUint16(32, numChannels * 2, true);        view.setUint16(34, 16, true); // 16 bits        view.setUint32(36, 1684108385, false); // "data"        view.setUint32(40, byteLength, true);        return header;    };    const saveFile = async () => {        const chunksList = resRef.current;        for (let i = 0; i  {        setRecord(true)        audioChunksRef.current = [] // 清空之前的录音数据        // 每5秒分割一次录音        intervalRef.current = setInterval(() => {            const curBlob = new Blob(audioChunksRef.current, { type: 'audio/wav' })            const startIndex = audioChunksRef.current.indexOf(firstBlob.current as Blob)            const blob = curBlob.slice(startIndex === -1 ? 0 : startIndex, -1, 'audio/wav')            firstBlob.current = audioChunksRef.current.at(-1)            // 处理当前录音数据            console.log('分割当前录音数据:', blob)            resRef.current.push(blob)        }, 5000)    }    const stopRecording = () => {        setRecord(false)        intervalRef.current && clearInterval(intervalRef.current) // 清除定时器    }    const onData = (recordedBlob: Blob) => {        audioChunksRef.current.push(recordedBlob) // 保存录音数据    }    const onStop = (recordedBlob: ReactMicStopEvent) => {        console.log('录音完成:', recordedBlob)    }    const saveFile1 = () => {        const chunksList = resRef.current        chunksList.map(async (v, i) => {            const fileName = 'aaa.wav'            const file: File = new File([v], fileName, { type: 'audio/wav' })            const fileSize = file.size            console.log('fileSize', fileSize)            // 创建下载链接            const url = URL.createObjectURL(file)            const a = document.createElement('a')            a.href = url            a.download = `recording${i}.wav` // 设置下载文件的名称            a.click() // 触发下载            // 释放URL资源            URL.revokeObjectURL(url)        })    }    const saveFinalResult = () => {        const fileName = 'aaa.wav'        const file: File = new File(audioChunksRef.current, fileName, { type: 'audio/wav' })        const fileSize = file.size        console.log('fileSize', fileSize)        // 创建下载链接        const url = URL.createObjectURL(file)        const a = document.createElement('a')        a.href = url        a.download = `recording${Date.now()}.wav` // 设置下载文件的名称        a.click() // 触发下载        // 释放URL资源        URL.revokeObjectURL(url)    }    return (        
)}export default AudioRecorder

在尝试切分blob流和生成wav文件的过程中,发现手动添加wav头信息并不能解决问题。其原因在于wav文件的结构比较严格,切分后如果不正确地添加头部信息,文件可能会损坏。

解决这个问题的一个建议是使用ffmpeg的wasm版本,这是一个可以在浏览器中运行的音视频处理库。通过它,你可以轻松地对音频进行切分并生成正确的wav文件格式。可以考虑使用ffmpeg.wasm项目来实现这个功能。

以上就是如何使用JavaScript将录音的Blob流切分成多个5秒的WAV文件并确保其正常播放?的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1504141.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 02:35:52
下一篇 2025年12月20日 02:36:05

相关推荐

  • 如何计算DOM元素相对于特定父元素的偏移量?

    精准定位:计算DOM元素相对父元素的偏移量 在复杂的DOM结构中,准确获取元素相对于特定父元素的偏移量(left和top属性)至关重要。 以下示例将演示如何高效地实现此功能。 假设我们有如下DOM结构: 我们需要计算id=”node-root”及其所有子孙节点相对于id=”wrapper”的偏移量。…

    2025年12月20日
    000
  • 如何解决OpenCV.js投影变换后结果为空白透明图片的问题?

    如何解决opencv.js投影变换结果为空白的透明图片问题 在使用opencv.js进行图像处理时,有时候会遇到投影变换后图像结果为空白的透明图片的问题。以下是我遇到的问题以及解决方法。 我在处理图像时,代码能够成功识别出文档的四个坐标,但到了投影变换这一步,得到的结果总是空白的透明图片,并且没有报…

    好文分享 2025年12月20日
    000
  • 如何通过点击按钮动态修改HTML元素的hover颜色?

    利用CSS变量和JavaScript实现按钮点击动态修改元素悬停颜色 本文介绍如何通过点击按钮来动态改变HTML元素的悬停颜色,提升网页交互体验。我们将使用CSS变量和JavaScript来实现这一功能。 目标是:点击按钮,修改已存在的元素悬停样式。 为此,我们将利用CSS变量定义悬停颜色,并通过J…

    2025年12月20日
    000
  • 在使用Vue3和Vant框架时,如何隐藏密码输入框的眼睛图标?

    解决Vant密码输入框眼睛图标显示问题 在使用Vue3和Vant框架构建项目时,开发者常常会遇到密码输入框显示眼睛图标的问题。 这并非Vant框架的bug,而是浏览器自身对密码输入框的默认行为。不同浏览器在处理密码可见性时,可能会显示或隐藏眼睛图标,导致显示不一致。 许多开发者希望完全去除这个眼睛图…

    2025年12月20日
    000
  • JS POST请求失败,但POSTMAN成功:如何排查浏览器Fetch API请求问题?

    浏览器Fetch API POST请求失败,但Postman却成功? 使用JavaScript的Fetch API发送POST请求时,遇到一个难题:浏览器执行失败,但Postman却能成功发送相同的请求。本文将分析可能原因及解决方法。 问题:开发者使用Fetch API发送POST请求,请求体包含J…

    2025年12月20日
    000
  • 如何在Konva.js中实现命令类Command类以支持撤销和重做功能?

    Konva.js中基于命令模式的撤销重做功能实现 本文介绍如何在Konva.js绘图应用中,利用命令模式实现撤销(Ctrl+Z)和重做(Ctrl+Y)功能。 我们将图形操作封装成命令对象,并使用命令栈管理这些操作,从而实现图形编辑的回退和前进。 首先,定义一个基础Command类: class Co…

    2025年12月20日
    000
  • 如何在Tampermonkey中实现对多个链接的GET请求并依次判断条件?

    Tampermonkey中依次处理多个GET请求并进行条件判断 在Tampermonkey脚本中,需要对多个链接发起GET请求,并根据返回结果依次进行条件判断,直到满足条件或处理完所有链接。 直接使用GM_xmlhttpRequest并发请求并不能满足“依次判断”的需求,因为GM_xmlhttpRe…

    2025年12月20日
    000
  • 在Vue中如何实现类似微信聊天记录的滚动加载效果?

    Vue.js模拟微信聊天记录滚动加载效果 本文演示如何在Vue.js应用中实现类似微信聊天记录的滚动加载效果。当用户滚动到顶部时,加载更多聊天记录,并保持滚动条在当前位置,而非回到顶部。 以下代码提供了一个完整的实现方案: {{ item }} import { ref, onMounted, ne…

    好文分享 2025年12月20日
    000
  • 在使用vant框架的密码输入框时,眼睛图标为什么会消失?如何解决?

    Vue3 Vant密码输入框自定义显示/隐藏密码图标 在使用Vue3和Vant框架开发时,您可能会遇到Vant密码输入框自带密码显示/隐藏功能缺失或显示异常的问题。 这通常是因为浏览器默认的密码输入框样式与Vant组件样式冲突导致的。 解决方法是自定义密码显示/隐藏功能,并隐藏浏览器默认的图标。 问…

    2025年12月20日
    200
  • 如何在前端实现多品牌高拍仪的拍照上传功能?

    前端集成多品牌高拍仪拍照上传功能 在现代办公场景中,高拍仪已成为高效扫描和上传文档的常用工具。然而,市面上高拍仪品牌和型号众多,给前端开发者集成统一的拍照上传功能带来挑战。本文探讨如何构建一个前端解决方案,兼容多种品牌的高拍仪。 挑战与需求 目标是开发一个前端程序,能够调用不同品牌的高拍仪进行拍照并…

    2025年12月20日
    000
  • 为什么vue-router跳转后控制台网络中没有页面请求信息?

    Vue-Router跳转后控制台无网络请求的原因 使用vue-router进行页面跳转时,浏览器控制台的网络选项卡可能不会显示新的请求,这与vue-router基于spa(单页应用)的架构有关。 刷新页面则会显示请求,这是因为刷新会触发服务器端重新加载整个页面。 让我们更清晰地解释: 当您使用Vue…

    好文分享 2025年12月20日
    300
  • 如何在Quill编辑器中实现文本标注的嵌套效果?

    Quill编辑器:巧妙实现文本标注嵌套 在Quill编辑器中进行文本标注时,处理重叠标注的嵌套效果至关重要。本文提供一种解决方案,有效解决多个标注索引重叠的情况。 首先,我们回顾下常见的需求和代码片段: 示例数据: const response = { “errorwordlist”: [ { “a…

    2025年12月20日
    000
  • console.log输出结果差异:两次调用为何不同?

    console.log输出差异的深入解析 本文分析一段代码中console.log函数输出结果的差异,并解释其根本原因。代码片段涉及URL参数解析和console.log的不同调用方式,导致输出结果存在细微差别。 代码首先定义getUrlParams函数,用于解析URL参数,返回一个包含所有参数的对…

    2025年12月20日
    100
  • 企业微信中的JS资源缓存问题如何解决?

    企业微信JS资源缓存难题及应对策略 企业微信环境下的JS资源缓存问题,常常导致项目升级后部分用户无法体验最新功能。例如,新增埋点追踪功能后,同一用户在同一时间段访问同一页面,却可能加载到不同版本的JS资源(带埋点或不带埋点)。这并非个例,而是企业微信内置浏览器强缓存策略所致:资源一旦缓存,除非手动刷…

    2025年12月20日
    000
  • Async/Await中回调函数如何优雅退出?

    在Async/Await中优雅地终止回调函数 使用async/await进行异步操作时,如何安全地从一个执行时间不确定的回调函数中退出,是一个常见挑战。本文将针对一个场景,演示如何在async/await环境下有效控制回调函数的退出。 问题: 代码使用MutationObserver监听按钮属性变化…

    2025年12月20日
    100
  • 如何用CSS实现图片序列的流畅播放效果?

    如何打造流畅的图片序列播放效果? 许多应用场景需要模拟视频播放,但素材并非视频,而是多张图片。直接替换图片路径播放容易因图片加载时间差异导致黑屏或卡顿。本文提供一种高效流畅的解决方案。 简单的逐张加载图片容易出现延迟,因此,我们采用更优的方案:将所有图片拼接成一张大图。假设图片尺寸相同,将它们水平拼…

    2025年12月20日
    000
  • 如何解决JavaScript中井号(#)函数名在Android WebView中的兼容性问题?

    Android WebView与JavaScript井号(#)函数名兼容性:问题及解决方案 开发中,JavaScript命名规范通常建议使用字母、数字、下划线和美元符号,避免以数字开头。然而,第三方库或框架可能包含特殊命名,例如使用井号(#)开头的函数名,这在Android WebView中可能引发…

    2025年12月20日
    200
  • Vue3中如何确保点击不同消息时只有当前消息显示编辑框?

    vue3中为什么id是唯一的,input却同时会展示? 在使用vue3开发聊天记录编辑功能时,我们遇到了一个问题:虽然每个消息的id是唯一的,但每次点击不同的消息进行编辑时,所有被编辑的消息都显示出来了,而不是只有当前点击的消息显示编辑框。这个问题让我非常困惑,因为我已经确保了每个消息的meg_id…

    好文分享 2025年12月20日
    000
  • Vue+ElementUI表格渲染延迟:如何解决异步请求导致的数据显示问题?

    Vue+ElementUI表格数据渲染延迟及优化策略 在Vue和ElementUI项目中,表格数据渲染延迟是一个常见问题。本文将分析一个案例,该案例中表格部分字段在页面加载时无法显示,只有在打开浏览器开发者工具后才显示。 问题描述: 一个使用el-table组件显示申请记录的页面,需要从后端获取申请…

    2025年12月20日
    100
  • 使用excelJs导出Excel时如何优化单元格保护设置以提升性能?

    使用exceljs库导出Excel:性能优化策略 在使用exceljs库导出包含单元格保护设置的Excel文件时,如果采用逐个单元格设置保护属性的方式,尤其在处理大量数据时,效率会非常低下,导致导出速度缓慢甚至卡顿。本文探讨两种优化策略,显著提升导出性能。 问题:开发者希望导出Excel表格,部分列…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信