You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否为HLS音频流添加three.js AudioAnalyser?尝试后频率数据始终为0

为HLS音频流添加Three.js AudioAnalyser/Web API AnalyserNode的可行方案

问题分析

你的HLS音频流可正常播放,但Three.js AudioAnalyser返回的平均频率始终为0,Web API AnalyserNode的尝试也未成功,核心原因包括:

  • 初始化分析器后立即调用频率获取方法,此时音频未开始播放或源未正确关联
  • Three.js Audio未绑定实际的audio元素
  • Web API尝试中误用createMediaStreamSource(该方法需要MediaStream对象,而非audio元素)

解决方案一:使用Three.js AudioAnalyser

实现步骤

  1. 监听HLS流加载完成事件,确保音频源就绪后再初始化分析器
  2. 将audio元素关联到Three.js Audio对象
  3. 通过requestAnimationFrame循环实时获取频率数据(单次调用无法获取动态变化的音频数据)

完整代码

let audioContext = new (window.AudioContext || window.webkitAudioContext)();
let streamAudio = document.querySelector('#player');
let hls;
let listener, audio, analyser;
const fftSize = 256;

if (Hls.isSupported()) {
    hls = new Hls();
    hls.loadSource('https://stream.revma.ihrhls.com/zc2593/hls.m3u8');
    hls.attachMedia(streamAudio);
    
    // 监听HLS清单解析完成事件,确保音频源就绪
    hls.on(Hls.Events.MANIFEST_PARSED, () => {
        // 初始化Three.js音频监听器
        listener = new THREE.AudioListener();
        perspectiveCamera.add(listener);
        
        // 创建Three.js Audio对象并关联audio元素
        audio = new THREE.Audio(listener);
        audio.setMediaElementSource(streamAudio);
        
        // 初始化音频分析器
        analyser = new THREE.AudioAnalyser(audio, fftSize);
        
        // 播放音频并开始实时获取频率数据
        streamAudio.play().then(() => {
            function updateFrequency() {
                const averageFrequency = analyser.getAverageFrequency();
                console.log(averageFrequency);
                requestAnimationFrame(updateFrequency);
            }
            updateFrequency();
        });
    });
}

plyr.setup(streamAudio);

解决方案二:使用Web API AnalyserNode

实现步骤

  1. 使用createMediaElementSource创建音频源(对应audio元素)
  2. 正确连接音频节点链:source -> analyser -> audioContext.destination
  3. 循环获取频率数据并计算平均值

完整代码

let audioContext = new (window.AudioContext || window.webkitAudioContext)();
let streamAudio = document.querySelector('#player');
let hls;
let analyser, frequencyData;
const fftSize = 256;

if (Hls.isSupported()) {
    hls = new Hls();
    hls.loadSource('https://stream.revma.ihrhls.com/zc2593/hls.m3u8');
    hls.attachMedia(streamAudio);
    
    hls.on(Hls.Events.MANIFEST_PARSED, () => {
        // 创建媒体元素音频源
        const source = audioContext.createMediaElementSource(streamAudio);
        analyser = audioContext.createAnalyser();
        analyser.fftSize = fftSize;
        
        // 连接音频节点
        source.connect(analyser);
        analyser.connect(audioContext.destination);
        
        // 创建存储频率数据的数组
        frequencyData = new Uint8Array(analyser.frequencyBinCount);
        
        streamAudio.play().then(() => {
            function updateFrequency() {
                // 获取当前频率数据
                analyser.getByteFrequencyData(frequencyData);
                // 计算平均频率
                let total = 0;
                frequencyData.forEach(val => total += val);
                const averageFrequency = total / frequencyData.length;
                console.log(averageFrequency);
                requestAnimationFrame(updateFrequency);
            }
            updateFrequency();
        });
    });
}

plyr.setup(streamAudio);

关键注意事项

  • 必须在用户交互事件(如点击)中初始化AudioContext或触发播放,否则浏览器会因自动播放政策阻止音频
  • 确保音频流的CORS配置正确,你的audio标签已添加crossorigin="anonymous",符合要求
  • 频率数据是动态变化的,必须通过循环实时获取,单次调用无法得到有效数据

内容的提问来源于stack exchange,提问作者Nate LeGrand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:57:45