From ca410b5cdd66e5c73885fb41c22af87123c65c9d Mon Sep 17 00:00:00 2001 From: Pavel Maslov Date: Wed, 12 Jan 2022 12:19:47 +0200 Subject: [PATCH] prewarm audio context on iOS --- docs/main.js | 67 ++++++++++++++++++++++++++++++++++++----------- package.json | 2 +- public/index.html | 32 ++++++++++++++++++++++ src/helpers.js | 26 +++++++++--------- 4 files changed, 97 insertions(+), 30 deletions(-) diff --git a/docs/main.js b/docs/main.js index 249dbc4..67c81e9 100644 --- a/docs/main.js +++ b/docs/main.js @@ -1,3 +1,38 @@ +//////////////////////// +// Fix iOS AudioContext +//////////////////////// +(function() { + window.AudioContext = window.AudioContext || window.webkitAudioContext; + if (window.AudioContext) { + window.audioContext = new window.AudioContext(); + } + const fixAudioContext = function (e) { + if (window.audioContext) { + // Create empty buffer + const buffer = window.audioContext.createBuffer(1, 1, 22050); + const source = window.audioContext.createBufferSource(); + source.buffer = buffer; + // Connect to output (speakers) + source.connect(window.audioContext.destination); + // Play sound + if (source.start) { + source.start(0); + } else if (source.play) { + source.play(0); + } else if (source.noteOn) { + source.noteOn(0); + } + } + // Remove events + document.removeEventListener('touchstart', fixAudioContext); + document.removeEventListener('touchend', fixAudioContext); + }; + // iOS 6-8 + document.addEventListener('touchstart', fixAudioContext); + // iOS 9 + document.addEventListener('touchend', fixAudioContext); +})(); + //////////////// // Worker //////////////// @@ -115,23 +150,23 @@ function stopVideo() { init(); } -function beep(freq = 750, duration = 150, vol = 5) { - const AudioContext = window.AudioContext || window.webkitAudioContext || false; - if (!AudioContext) { - console.warn("Sorry, but the Web Audio API is not supported by your browser"); - return; +const beep = (freq = 750, duration = 150, vol = 5) => { + try { + const context = window.audioContext; + const oscillator = context.createOscillator(); + const gain = context.createGain(); + oscillator.connect(gain); + oscillator.frequency.value = freq; + oscillator.type = "square"; + gain.connect(context.destination); + gain.gain.value = vol * 0.01; + oscillator.start(context.currentTime); + oscillator.stop(context.currentTime + duration * 0.001); + } catch (e) { + console.warn("Sorry, Web Audio API is not supported by your browser"); + console.warn(e.toString()); } - const context = new AudioContext(); - const oscillator = context.createOscillator(); - const gain = context.createGain(); - oscillator.connect(gain); - oscillator.frequency.value = freq; - oscillator.type = "square"; - gain.connect(context.destination); - gain.gain.value = vol * 0.01; - oscillator.start(context.currentTime); - oscillator.stop(context.currentTime + duration * 0.001); -} +}; //////////////// // DOM diff --git a/package.json b/package.json index 9a52b12..bf9eb13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "koder-react", - "version": "1.2.7", + "version": "1.3.0", "homepage": "./", "private": true, "devDependencies": { diff --git a/public/index.html b/public/index.html index 0aac426..149e8a3 100644 --- a/public/index.html +++ b/public/index.html @@ -25,6 +25,38 @@ trackLinks:true, accurateTrackBounce:true }); + + (function() { + window.AudioContext = window.AudioContext || window.webkitAudioContext; + if (window.AudioContext) { + window.audioContext = new window.AudioContext(); + } + const fixAudioContext = function (e) { + if (window.audioContext) { + // Create empty buffer + const buffer = window.audioContext.createBuffer(1, 1, 22050); + const source = window.audioContext.createBufferSource(); + source.buffer = buffer; + // Connect to output (speakers) + source.connect(window.audioContext.destination); + // Play sound + if (source.start) { + source.start(0); + } else if (source.play) { + source.play(0); + } else if (source.noteOn) { + source.noteOn(0); + } + } + // Remove events + document.removeEventListener('touchstart', fixAudioContext); + document.removeEventListener('touchend', fixAudioContext); + }; + // iOS 6-8 + document.addEventListener('touchstart', fixAudioContext); + // iOS 9 + document.addEventListener('touchend', fixAudioContext); + })(); diff --git a/src/helpers.js b/src/helpers.js index b87d43a..2f99196 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,19 +1,19 @@ const beep = (freq = 750, duration = 150, vol = 5) => { - const AudioContext = window.AudioContext || window.webkitAudioContext || false; - if (!AudioContext) { + try { + const context = window.audioContext; + const oscillator = context.createOscillator(); + const gain = context.createGain(); + oscillator.connect(gain); + oscillator.frequency.value = freq; + oscillator.type = "square"; + gain.connect(context.destination); + gain.gain.value = vol * 0.01; + oscillator.start(context.currentTime); + oscillator.stop(context.currentTime + duration * 0.001); + } catch (e) { console.warn("Sorry, Web Audio API is not supported by your browser"); - return; + console.warn(e.toString()); } - const context = new AudioContext(); - const oscillator = context.createOscillator(); - const gain = context.createGain(); - oscillator.connect(gain); - oscillator.frequency.value = freq; - oscillator.type = "square"; - gain.connect(context.destination); - gain.gain.value = vol * 0.01; - oscillator.start(context.currentTime); - oscillator.stop(context.currentTime + duration * 0.001); }; const WORKER_TYPE = {