WebRtc实时音波

摘要:

最近在做音视频相关业务,用的到了webRtc技术,掌握这些方法可以结合业务做,麦克风检测、录制音频,都是可以的;基本操作和其它方法都写好在methods中了;

全局变量
typescript 复制代码
// 后续会创建AnalyserNode对象
let analyser: any = null;
// 后续赋值canvas标签对象
let canvas: any = null;
// canvas 2d对象
let canvasCtx: any = null;
let audioSteam: any = { // 获取音视频MediaStream对象
    current: null
}
HTML
html 复制代码
<div>
    // 绘制音波
    <canvas id="devDetectionMicroCanvas" className={style.audio_canvas}></canvas>
    // 实时播放
    <audio id="devDetectionMicroRef" autoPlay></audio>
</div>
获取音视频流
typescript 复制代码
// 使用getUserMedia API获取音频流。
navigator.mediaDevices.getUserMedia({
    audio: true
}).then(stream => {
    /* MediaStream赋值到全局对象,后续使用 */
    audioSteam.current = stream;
    /* 获取当前采集设备名称 */
    methods.handleStreamGetMicroName();
    /* 把媒体流赋值给audio标签进行试试播放 */
    methods.handleAudioPlay();
    /* 开始准备制作试试音波 */
    methods.handleCanvasAudioContext();
})
.catch(error => {
    let errorMessage = error + '';
    if (errorMessage.includes('Permission denied')) {
        errorMessage = '请开启麦克风权限';
    } else if (errorMessage.includes('Requested device not found')) {
        errorMessage = '请检测麦克风是否插入';
    };
    console.log('error', errorMessage)
});
其它方法
typescript 复制代码
const methods = {
    // 处理canvas和audioContext
    handleCanvasAudioContext() {
         // 1. 使用AudioContext API创建一个AudioContext对象,并将音频流添加到它上面
        const audioContext = new AudioContext();
        const source = audioContext.createMediaStreamSource(stream);
        // 2. 创建AnalyserNode对象,并将其连接到source节点。
        analyser = audioContext.createAnalyser();
        source.connect(analyser);
        // 3. 获取实时音频数据并将其转换为可视化数据。例如,可以使用getByteTimeDomainData()方法获取时域数据,并将其转换为音波。
        canvas = document.getElementById("devDetectionMicroCanvas");
        canvasCtx = canvas.getContext("2d");
        // 4.启动波纹动画
        methods.drawWaveform();
    },
    // 波纹动画
    drawWaveform() {
        const stream = audioSteam.current;
        // 获取时域数据
        const dataArray = new Uint8Array(analyser.fftSize);
        analyser.getByteTimeDomainData(dataArray);

        // 绘制音波
        canvasCtx.clearRect(0, 0, canvas.width, canvas.height);
        canvasCtx.lineWidth = 2;
        canvasCtx.strokeStyle = "rgb(69, 255, 56)";
        canvasCtx.beginPath();
        const sliceWidth = canvas.width * 1.0 / analyser.fftSize;
        let x = 0;
        for(let i = 0; i < analyser.fftSize; i++) {
            const v = dataArray[i] / 128.0;
            const y = v * canvas.height / 2;
            if(i === 0) {
                canvasCtx.moveTo(x, y);
            } else {
                canvasCtx.lineTo(x, y);
            }
            x += sliceWidth;
        }
        canvasCtx.stroke();
        requestAnimationFrame(methods.drawWaveform);
    },
    // 获取采集设备名称
    handleStreamGetMicroName(){
        if (audioSteam.current) {
            const audioTrack = audioSteam.current.getAudioTracks()[0];
            // audioTrack.label;
            console.log('当前采集设备名称', audioTrack.label);
        }
    },
    // 处理audio播放
    handleAudioPlay() {
        const stream = audioSteam.current;
        const elm: HTMLVideoElement | any = document.getElementById('devDetectionMicroRef');
        if (elm) {
            elm.srcObject = stream;
        }
    },
    // 停止麦克采集
    stopAudioSteam() {
        if (audioSteam.current) {
            audioSteam.current.getTracks().forEach((sender: any) => {
                sender.stop();
            });
        }
    },
}
相关推荐
Y学院7 分钟前
vue的组件通信
前端·javascript·vue.js
患得患失9498 分钟前
【ThreeJs】【伪VR】用 Three.js 实现伪 VR 全景看房系统:低成本实现 3D 级交互体验
javascript·3d·vr
PairsNightRain10 分钟前
React Concurrent Mode 是什么?怎么使用?
前端·react.js·前端框架
小岛前端23 分钟前
React 剧变!
前端·react.js·前端框架
teeeeeeemo35 分钟前
Webpack 模块联邦(Module Federation)
开发语言·前端·javascript·笔记·webpack·node.js
岁月宁静1 小时前
AI聊天系统 实战:打造优雅的聊天记录复制与批量下载功能
前端·vue.js·人工智能
小小弯_Shelby1 小时前
uniApp App内嵌H5打开内部链接,返回手势(左滑右滑页面)会直接关闭H5项目
前端·uni-app
IT_陈寒1 小时前
SpringBoot性能飞跃:5个关键优化让你的应用吞吐量提升300%
前端·人工智能·后端
加洛斯2 小时前
Vue 知识篇(2):浅谈Vue中的DOM与VNode
前端·javascript·vue.js
kunge1v52 小时前
学习爬虫第三天:数据提取
前端·爬虫·python·学习