• 根据音频绘制频谱


    根据音频链接绘制频谱图

    封装

    // 可以这样使用 也可以 import { AudioContext } from 'standardized-audio-context';
    const getAudioContext = 
      window.AudioContext ||
      window.webkitAudioContext ||
      window.mozAudioContext ||
      window.msAudioContext;
    
    const clearArr = []
    
    export const stopAudio = () => { clearArr.forEach(f => f()) }
    
    /**
     * 获取音频文件频谱数据 
     */
    export function getAuidoData() {
        let analyser, dataArray;
        let loadOver = false;
        var audioCtx = new getAudioContext({
            latencyHint: "playback"
        }); // 创建和播放需要间隔一端时间
        analyser = audioCtx.createAnalyser();
        analyser.fftSize = 2048;
    
        const destroy = () => { audioCtx.close() }
    
        let stop = false;
        const cbs = []
        const run = () => {
            if (stop) return;
            requestAnimationFrame(() => {
                var bufferLength = analyser.frequencyBinCount;
                dataArray = new Uint8Array(bufferLength);
                analyser.getByteFrequencyData(dataArray);
                cbs.forEach(f => f(dataArray))
                run()
            });
        };
    
        const load = (url, data, onended = () => { }) => {
            let audioBuffer;
    
            // 通过fetch 请求音频获取 arrayBuffer 类型数据
            const getData = () => { 
                // 方法一 使用fetch请求
                return fetch(url)
                    .then((res) => res.arrayBuffer())
                    .then((arrayBuffer) => {
                        return new Promise((resolve, reject) => {
                            // 兼容低版本的iphone7中 audioCtx.decodeAudioData 返回的不是一个promise,必须通过回调函数
                            audioCtx.decodeAudioData(arrayBuffer, resolve, err => {
                                console.log('decodeAudioData-er', err);
                                reject(err)
                            })
                        })
                    })
                    .then((buffer) => (audioBuffer = buffer));
    
                // 方法二 把接口返回blob转 arrayBuffer 
                // ios ajax返回的二进制数据没有 arrayBuffer 方法
                // return data
                //     .arrayBuffer()
                //     .then((arrayBuffer) => audioCtx.decodeAudioData(arrayBuffer))
                //     .then((buffer) => (audioBuffer = buffer));
            };
            getData().then(function () {
                // 创建音频源
                const source = audioCtx.createBufferSource();
                source.buffer = audioBuffer;
                source.connect(analyser);
                analyser.connect(audioCtx.destination);
    
                // 创建音量节点
                // const gainNode = audioCtx.createGain();
                // gainNode.gain.value = 1 // 设置声音大小
    
                console.log('source.start');
                source.start(); // 开始播放
                run();
                source.onended = () => {
                    console.log('source.onended'); 
                    onended()
                    stop = true
                }; // 播放完成
                loadOver = true;
    
                clearArr.push(() => { source.stop() })
            }).catch(err => {
                console.log('getdata-err', err);
            });
        };
    
        const change = (cb = () => { }) => cbs.push(cb)
       
        return { load, change, destroy };
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    方式 1,直接传递二进制音频数据

    // 获取二进制数据
    
    // data:二进制音频数据
    const blobData = new Blob([data], { type: "audio/mpeg" });
    const url = window.URL.createObjectURL(blobData);
    const upWave = getAuidoData();
    upWave.change((data) => {
      // draw({data}) // 绘制
    });
    await new Promise((c) => upWave.load(url, "", c));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    方式 2 使用音频链接

    const upWave = getAuidoData();
    upWave.change((data) => {
      // draw({data}) // 绘制
    });
    await new Promise((c) => upWave.load("xxx.mp3", "", c));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:在有些设备(iphone7)上,录音和播放不能同时进行, 在一些iphone上 同时进行回导致 播放声音音量较小
    注意:在有些设备上,

    绘制实现

    绘制实现

  • 相关阅读:
    31、成语大全API接口,免费好用
    怎么查找Linux服务器是否有后门账户
    【React】useMemo
    RabbitMQ安装与简单使用
    Unity3D 基础——通过四元数控制对象旋转
    神经网络遗传算法函数极值寻优
    Deep Learning for Monocular Depth Estimation: A Review.基于深度学习的深度估计
    html如何携带参数自动跳转页面
    详解Redis之Lettuce实战
    使用数据分析,识别设备异常
  • 原文地址:https://blog.csdn.net/weixin_42448623/article/details/134506400