web前端实时音频播放并绘制波形

web前端实时音频播放并绘制波形

初始

最新项目需要用到拉取实时声音流数据播放声音以及显示对应的波形图。如果是声音文件我们可以用 wavesurfer.js这个框架很轻松的绘制波形,但是实时声音怎么转换呢,以下是我的解决方案
在这里插入图片描述

1.后端通过websocket推流

后端需要将数据转换成PCM格式
在这里插入图片描述

2.前端实现

我们用到下面2个库:
1.pcm-player (播放声音)
2.recorder-core (绘制波形)

安装:

npm install pcm-player
npm install recorder-core

1.首先我们先封装websocket(网上也有很多教程),直接上代码

var ws = null
let lockReconnect = false;
/**
 * @param {*} path ws url
 * @param {*} callback 数据处理回调
 * @param {*} isHandleData 是否处理转换数据
 * @returns ws
 */
const websocket = (path, callback, isHandleData = false) => {
    cancel();//取消上一次连接
    ws = new WebSocket(path);
    ws.binaryType = "arraybuffer"
    // 建立连接
    ws.onopen = (event) => {
        console.log('websocket 建立连接');
        // 连接关闭
        ws.onclose = (event) => {
            console.log('websocket 连接断开,重新连接');
            reconnect(path, callback);
        };
        // 接收到消息
        ws.onmessage = (event) => {
            const data = handleData(event, isHandleData);
            if (callback) callback(data)
        };
    };
    ws.onerror = (event) => {
        console.log('websocket 连接失败,重新连接');
        reconnect(path, callback);
    };
    return ws;
}
// 重新连接
const reconnect = (path, callback) => {
    if (lockReconnect) {
        return;
    }
    lockReconnect = true;
    setTimeout(function () {
        console.log("重新链接…")
        lockReconnect = false;
        websocket(path, callback)
    }, 2000);
}

// 处理返回数据
const handleData = (event, isHandleData) => {
    const data = isHandleData ? JSON.parse(event.data) : event
    return data;
}
// 取消连接 清除ws实例
const cancel = () => {
    if (ws) {
        ws.onclose = () => { }
        ws?.close()
    }
    ws = null
}

export default websocket

2.在vue中使用完整代码

<template>
  <div id="wave_audio"></div>
</template>

<script>
import Recorder from 'recorder-core'
import PCMPlayer from 'pcm-player'
//需要使用到的音频格式编码引擎的js文件统统加载进来
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
//以上三个也可以合并使用压缩好的recorder.xxx.min.js
//比如 import Recorder from 'recorder-core/recorder.mp3.min' //已包含recorder-core和mp3格式支持
//可选的扩展支持项
import 'recorder-core/src/extensions/wavesurfer.view'
import websocket from './websocket'
var player = null
var wave = null
export default {
  mounted() {
    this.initPlay()
    this.initWave()
    this.initWebsocket(
      'ws://192.168.8.210:8877/live?url=rtmp://139.224.194.14:10085/hls/wrpYcD27g?sign=wrtY5D27gz&&&ffmpeg=true'
    )
  },
  methods: {
    initPlay() {
      player = new PCMPlayer({
        encoding: '16bitInt', //编码 可能的值 8bitInt / 16bitInt / 32bitInt / 32bitFloat 默认值:16bitInt
        channels: 1, // PCM 数据中的通道数
        sampleRate: 32000, // PCM 数据的采样率
        flushTime: 2000, //  以毫秒为单位播放的 PCM 数据的刷新间隔。默认 1000ms
      })
    },
    initWave() {
      const waveOption = {
        elem: '#wave_audio',
        scale: 2, //缩放系数,应为正整数,使用2(3? no!)倍宽高进行绘制,避免移动端绘制模糊
        fps: 50, //绘制帧率,不可过高,50-60fps运动性质动画明显会流畅舒适,实际显示帧率达不到这个值也并无太大影响
        duration: 3500, //当前视图窗口内最大绘制的波形的持续时间,此处决定了移动速率
        direction: 1, //波形前进方向,取值:1由左往右,-1由右往左
        position: 0, //绘制位置,取值-1到1,-1为最底下,0为中间,1为最顶上,小数为百分比
        centerHeight: 1, //中线基础粗细,如果为0不绘制中线,position=±1时应当设为0
        //波形颜色配置:[位置,css颜色,...] 位置: 取值0.0-1.0之间
        linear: [0, 'rgba(14, 224, 238, 1)', 1, 'rgba(14, 224, 238, .6)'],
        centerColor: 'rgba(14, 224, 238, 1)', //中线css颜色,留空取波形第一个渐变颜色
      }
      wave = Recorder.WaveSurferView(waveOption)
    },
    initWebsocket(url) {
      websocket(url, this.handle)
    },
    handle(event) {
      const dataAudio = new Uint8Array(event.data)
      player && player.feed(dataAudio) // 播放声音
      const data = new Uint16Array(event.data)
      wave && wave.input(data, 20, 32000) // 添加波形数据
    },
    destroyPlay() {
      player && player.destroy()
      player = null
    },
  },
  beforeDestroy() {
    this.destroyPlay()
  },
}
</script>

<style lang="less" scoped>
#wave_audio {
  width: 100%;
  height: 100%;
}
</style>
### 回答1: c@naudio是一种音频处理库,它提供了播放音频显示波形图的功能。通过c@naudio库,我们可以使用各种编程语言(如C#)来实现这一功能。 首先,我们需要将音频文件加载到程序中。使用c@naudio的AudioFileReader类,我们可以读取音频文件的数据。然后,我们可以使用c@naudio的WaveOut类来创建一个音频输出设备,并将音频数据发送到该设备以播放音频。 接下来,我们需要实时显示波形图。c@naudio提供了一个叫做WaveViewer的控件,它可以在界面上显示音频波形图。我们可以将WaveViewer控件添加到我们的用户界面中,并将其与音频数据相关联。当音频数据发生变化时,WaveViewer控件会自动更新波形图。 为了实现实时显示波形图,我们可以使用c@naudio的WaveIn类来录制音频数据。WaveIn类提供了一个事件,当有新的音频数据可供显示时,该事件就会触发。我们可以在该事件的处理程序中,将新的音频数据传递给WaveViewer控件,并请求其重新绘制波形图。 在程序运行期间,c@naudio会根据音频数据的采样率和位深度来绘制波形图。通过不断接收新的音频数据,并将其传递给WaveViewer控件,我们可以实现实时显示波形图的功能。 综上所述,使用c@naudio库,我们可以方便地实现音频播放实时显示波形图的功能。 ### 回答2: c@naudio是一个功能强大的音频处理库,它可以用来播放音频文件并实时显示波形图。要实现这个功能,我们可以按照以下步骤进行操作: 1. 首先,我们需要导入c@naudio库,并设置音频的输入源,可以是一个音频文件或音频设备。 2. 接下来,我们需要创建一个WaveStream对象来读取音频数据。可以使用WaveFileReader类从音频文件中读取数据,或使用WaveIn类来从音频设备中读取实时数据。 3. 在播放音频之前,我们可以创建一个WaveOut对象来输出音频数据。通过将WaveStream对象分配给WaveOut对象的Device属性,我们可以将音频发送到指定的音频设备进行播放。 4. 在音频播放过程中,我们可以实时读取音频数据并通过计算每个样本的振幅值来绘制波形图。可以使用WaveStream对象的Read方法读取音频数据,并使用Math.Abs方法计算振幅值。 5. 最后,我们可以使用图形库(如System.Drawing)来绘制波形图。根据每个样本的振幅值,我们可以将其绘制为垂直线或曲线,并将整个波形绘制在应用程序的用户界面上。 通过以上步骤,我们可以实现使用c@naudio播放音频实时显示波形图的功能。这样用户就可以同时听到音频并观察其波形图,以更直观地了解音频的声音特征。 ### 回答3: c@naudio是一个在C#中播放音频的开源库。它提供了一些方便的类和方法,以便开发人员可以轻松地加载、播放和处理音频文件。 要在c@naudio中实现实时显示波形图,我们可以这样做: 1. 引用c@naudio库:首先,我们需要将c@naudio库添加到我们的项目中。可以通过NuGet包管理器来添加。 2. 创建一个WaveStream对象:在使用c@naudio播放音频之前,我们需要创建一个WaveStream对象来加载并读取音频文件。WaveStream是c@naudio库中用于处理和播放音频数据的基本类。 3. 创建一个WaveOutEvent对象:使用WaveOutEvent类,我们可以创建一个可以播放音频的WaveOut设备。这个类提供了一些方法和事件,用于控制和监视音频播放。 4. 打开音频文件并创建WaveChannel32对象:在播放音频之前,我们需要打开我们要播放音频文件,并将其与WaveOutEvent对象关联。可以使用WaveChannel32类来读取音频数据,并将其转换为可播放的格式。 5. 创建一个BufferedWaveProvider对象:BufferedWaveProvider是一个用于缓存音频数据的类。我们可以将它与WaveChannel32对象关联,以便在播放音频时能够获得音频数据。 6. 创建一个SampleAggregator对象:SampleAggregator是一个用于分析音频数据并生成波形数据的类。我们可以将其与BufferedWaveProvider对象关联,并使用它来实时计算和显示音频波形图。 7. 播放音频:通过调用WaveOutEvent对象的Play方法,我们可以开始播放音频。同时,SampleAggregator对象将开始分析音频数据并生成波形图。 8. 实时显示波形图:在UI线程中,我们可以使用SampleAggregator对象的事件和方法来实时显示音频波形图。每当有新的音频数据可用时,我们可以处理并更新波形图。 通过上述步骤,我们可以使用c@naudio库在C#中播放音频,并实时显示相应的波形图。这样,我们可以轻松地在应用程序中添加音频播放波形显示的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值