【问题标题】:Safari web audio visualizer works with mp3 file but not with streamSafari 网络音频可视化器适用于 mp3 文件,但不适用于流
【发布时间】:2020-05-08 02:00:02
【问题描述】:

我正在尝试流式传输音频并通过画布将其可视化,但是当我需要让它与连续流一起使用时,它似乎只能与静态文件(在本例中为 mp3)一起使用。

使用 getByteFrequencyData 看起来 bufferArray 充满了零,或者使用 getByteTimeDomainData 充满了 128。

重要提示

  1. 它不是音频源来自的实际 MP3 文件,而是定期更新的缓冲流,出于专有原因,我无法共享实际 URL,但它看起来像这样,例如“@987654321 @"。 MP3 格式实际上是在标题中传递的。

  2. 不能使用 fetch 或其他 XHR 请求,因为 URL 在上线时需要可共享。

  3. 无法更改标题格式

请看下面的代码sn-ps。

示例文件 静态mp3文件:https://s3-us-west-2.amazonaws.com/s.cdpn.io/481938/Find_My_Way_Home.mp3 流端点:http://rfcmedia.streamguys1.com/MusicPulse.mp3

HTML

<button id="btn">Start</button>
<canvas id="canvas" style="background:black;width:512px;height:255px;"></canvas>

JS

window.onload = () => {
    document.getElementById('btn').addEventListener('click', () => {
        const audio = new Audio()
        audio.autoplay = false
        audio.crossOrigin = 'anonymous'
        audio.src = 'http://rfcmedia.streamguys1.com/MusicPulse.mp3'


        const player = document.getElementById('audio_player')
        const canvas = document.getElementById('canvas')
        const canvasCtx = canvas.getContext('2d')
        const audioContext = new (window.AudioContext ||
            window.webkitAudioContext)()
        const analyser = audioContext.createAnalyser()
        analyser.connect(audioContext.destination)

        const audioSourceNode = audioContext.createMediaElementSource(audio)
        audioSourceNode.connect(analyser)

        const data = new Uint8Array(analyser.frequencyBinCount)

        const render = () => {
            analyser.getByteFrequencyData(data)

            canvasCtx.clearRect(0, 0, canvas.width, canvas.height)
            const center = canvas.height / 2
            let diff = 10
            let shape = {
                x: diff,
                y1: center,
                y2: center
            }

            for (let i = 0; i < data.length; i++) {
                let height = data[i] / 2

                if (height) {
                    shape.y1 = center - height
                    shape.y2 = center + height

                    const { x, y1, y2 } = shape

                    const lingrad = canvasCtx.createLinearGradient(0, 0, 0, 180)
                    lingrad.addColorStop(0, '#5d8db6')
                    lingrad.addColorStop(0.515, '#5d8db6')
                    lingrad.addColorStop(0.52, '#fff')
                    lingrad.addColorStop(0.53, '#fff')
                    lingrad.addColorStop(0.535, 'rgba(93, 141, 182, 0.6)')
                    lingrad.addColorStop(1, 'rgba(93, 141, 182, 0.6)')

                    canvasCtx.beginPath()
                    canvasCtx.moveTo(x, y1)
                    canvasCtx.quadraticCurveTo(x - diff, center, x, y2)
                    canvasCtx.moveTo(x, y1)
                    canvasCtx.quadraticCurveTo(x + diff, center, x, y2)
                    canvasCtx.closePath()
                    canvasCtx.fillStyle = lingrad
                    canvasCtx.fill()

                    shape.x = x + 8
                }
            }

            requestAnimationFrame(render)
        }

        requestAnimationFrame(render)
        audio.play()
    })
}

【问题讨论】:

  • 是否需要 MP3 或者您可以使用 Ogg Opus 或 WebM Opus 代替 MP3?
  • 不幸的是,@AnthumChris MP3 是必需的
  • 您可以在bugs.webkit.org/enter_bug.cgi 填写错误报告问题甚至在您尝试分析它之前:createMediaElementSource 不起作用。
  • 您找到解决方案了吗?

标签: javascript safari html5-audio web-audio-api


【解决方案1】:

您可能需要考虑使用Media Source Extensions,它允许您在文件流式传输时读取和解码文件的块。 This MSE MP3 tutorial 也可能有用。该教程引用了 XHR,但您也可以将 fetch() 与流 API 一起使用来播放音频

【讨论】:

  • 很遗憾,这不起作用 (jsfiddle.net/fuz0ed4j)。错误是当 MediaElement 指向流时,它们不支持将音频传输到网络音频上下文图,因此从中生成新流将无济于事。
猜你喜欢
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
相关资源
最近更新 更多