Bru*_*ton 6 javascript ios progressive-web-apps web-audio-api
我希望 Stack Overflow 社区中的某个人能够为此提供解决方法。很长一段时间以来,它一直是我的眼中钉。
我的要求非常简单:淡入页面上音频播放的音量。
使用 JavaScript 有几种方法可以做到这一点:
HTMLAudioElement. 这对于 iOS 设备根本不起作用,因为该属性对于操作系统来说是只读的。AudioContext.createMediaElementSource()与GainNode. 目前此功能有效,但声音输出通常会失真 - 裂纹和爆裂声会破坏任何流媒体音频的体验。这不是由于 AudioContext 使用不同的采样率引起的。AudioBuffer下载的文件结合使用。XMLHttpRequestarraybuffer这似乎导致根本没有音量。它适用于模拟器,但不适用于物理设备。这三种方法几乎适用于任何设备上的任何浏览器(现代 iOS 设备除外)。13 之前的 iOS 版本对于方法 2 或 3 来说工作得很好。我并不是想搞阴谋论,但苹果是否会故意破坏 PWA 支持,以便为他们的应用商店带来更多收入?
我有这个片段,你可以尝试一下并告诉我这是否适合你:
// input
const FADE_IN_DURATION = 10
const url = '/path/to/audio.mp3'
// setup
const context = /** @type {AudioContext} */(new (window.AudioContext || window.webkitAudioContext)())
const gainNode = context.createGain()
gainNode.connect(context.destination)
gainNode.gain.value = 0
// fetch
const response = await fetch(url)
const audioData = await response.arrayBuffer()
const buffer = await new Promise((resolve, reject) => {
context.decodeAudioData(audioData, resolve, reject)
})
// connect
const source = context.createBufferSource()
source.buffer = buffer
source.connect(gainNode)
// play
const startTime = context.currentTime
gainNode.gain.linearRampToValueAtTime(1, startTime + FADE_IN_DURATION)
source.start(startTime)
Run Code Online (Sandbox Code Playgroud)
GainNode的 使context.createGain()您可以访问“增益” AudioParam。并且AudioParam有一个名为的方法linearRampToValueAtTime可以完全满足您的需求1会产生一些“失真”,因为“音量峰值”开始超过最大可能值。因此,如果您只想平滑淡入,请保持在0和之间1。AudioBufferSourceNode --> GainNode --> AudioContext上面的代码片段并不能真正开箱即用,因为您需要
// input
const FADE_IN_DURATION = 10
const url = 'https://upload.wikimedia.org/wikipedia/commons/d/de/Lorem_ipsum.ogg'
// setup
const context = /** @type {AudioContext} */ (new(window.AudioContext || window.webkitAudioContext)())
const gainNode = context.createGain()
gainNode.connect(context.destination)
gainNode.gain.value = 0
// fetch
;(async function() {
const response = await fetch(url)
const audioData = await response.arrayBuffer()
const buffer = await new Promise((resolve, reject) => {
context.decodeAudioData(audioData, resolve, reject)
})
// user input necessary
document.getElementById('text').textContent = "Ready. Click anywhere to start audio."
document.addEventListener('click', () => {
document.getElementById('text').textContent = "Now playing..."
// connect
const source = context.createBufferSource()
source.buffer = buffer
source.connect(gainNode)
// play
const startTime = context.currentTime
gainNode.gain.linearRampToValueAtTime(1, startTime + FADE_IN_DURATION)
source.start(startTime)
}, {
once: true
})
})()Run Code Online (Sandbox Code Playgroud)
<div id="text">Loading file...</div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
936 次 |
| 最近记录: |