Safari on iOS puts a scrubber on its lock screen for simple HTMLAudioElements. For example:
const a = new Audio();
a.src = '.m4a'
a.play();
JSFiddle: /
The lock screen will allow me to choose a position in the currently playing audio file.
How can I disable the ability for the user to scrub the file on the lock screen? The metadata showing is fine, and being able to pause/play is also acceptable, but I'm also fine with disabling it all if I need to.
Safari on iOS puts a scrubber on its lock screen for simple HTMLAudioElements. For example:
const a = new Audio();
a.src = 'https://example./audio.m4a'
a.play();
JSFiddle: https://jsfiddle/0seckLfd/
The lock screen will allow me to choose a position in the currently playing audio file.
How can I disable the ability for the user to scrub the file on the lock screen? The metadata showing is fine, and being able to pause/play is also acceptable, but I'm also fine with disabling it all if I need to.
Share Improve this question edited Jun 29, 2019 at 14:20 Brad asked Jun 27, 2019 at 3:13 BradBrad 163k55 gold badges377 silver badges552 bronze badges 11- I guess the functionality is decided in program code. I would just have a reference to if the user is allowed or not to scrub the file on the lock screen. However, the design guidelines will not allow this since it requires that a user action to have some effect. – Gillsoft AB Commented Jun 29, 2019 at 18:08
- @GillsoftAB Unfortunately, there are some situations, such as content license agreements, where allowing the user to scrub is not permitted. I'm working on a way to just go back to the last time offset when the user tries to seek the file, but it's hacky and not a great user experience. – Brad Commented Jun 29, 2019 at 18:11
- omit user changes unless some condition. e.g. if (make_ui_change && user_paid) { ... } this is how I've done it. Then any dragged item will realign itself properly (but can still be dragged with no effect). – Gillsoft AB Commented Jun 29, 2019 at 18:14
-
@GillsoftAB Yeah, that's the approach I'm taking. Unfortunately, there is no event I get directly from these controls. The media element is controlled directly by this OS widget, so I can only respond after-the-fact. I've tried
e.preventDefault()
ande.stopPropagation()
and what not on theseeked
andseeking
events, but they don't do anything. Therefore, I think the best I can do is keep track of the time, and then seek back to it. – Brad Commented Jun 29, 2019 at 18:16 - Ahh, you use React Native or similar? or du you use Apple Music API? – Gillsoft AB Commented Jun 29, 2019 at 18:16
4 Answers
Reset to default 7DISABLE Player on lock screen pletely
if you want to pletely remove the lock screen player you could do something like
const a = new Audio();
document.querySelector('button').addEventListener('click', (e) => {
a.src = 'http://sprott.physics.wisc.edu/wop/sounds/Bicycle%20Race-Full.m4a'
a.play();
});
document.addEventListener('visibilitychange', () => {
if (document.hidden) a.src = undefined
})
https://jsfiddle/5s8c9eL0/3/
that is stoping the player when changing tab or locking screen (code to be cleaned improved depending on your needs)
From my understanding you can't block/hide the scrubbing mands unless you can tag the audio as a live stream. That being said, you can use js to refuse scrubbing server-side. Reference the answer here. Although that answer speaks of video, it also works with audio.
The lock screen / control center scrubber can also be avoided by using Web Audio API.
This is an example of preloading a sound and playing it, with mentary and error handling:
try {
// <audio> element is simpler for sound effects,
// but in iOS/iPad it shows up in the Control Center, as if it's music you'd want to play/pause/etc.
// Also, on subsequent plays, it only plays part of the sound.
// And Web Audio API is better for playing sound effects anyway because it can play a sound overlapping with itself, without maintaining a pool of <audio> elements.
window.audioContext = window.audioContext || new AudioContext(); // Interoperate with other things using Web Audio API, assuming they use the same global & pattern.
const audio_buffer_promise =
fetch("audio/sound.wav")
.then(response => response.arrayBuffer())
.then(array_buffer => audioContext.decodeAudioData(array_buffer))
var play_sound = async function () {
audioContext.resume(); // in case it was not allowed to start until a user interaction
// Note that this should be before waiting for the audio buffer,
// so that it works the first time (it would no longer be "within a user gesture")
// This only works if play_sound is called during a user gesture (at least once), otherwise audioContext.resume(); needs to be called externally.
const audio_buffer = await audio_buffer_promise; // Promises can be awaited any number of times. This waits for the fetch the first time, and is instant the next time.
// Note that if the fetch failed, it will not retry. One could instead rely on HTTP caching and just fetch() each time, but that would be a little less efficient as it would need to decode the audio file each time, so the best option might be custom caching with request error handling.
const source = audioContext.createBufferSource();
source.buffer = audio_buffer;
source.connect(audioContext.destination);
source.start();
};
} catch (error) {
console.log("AudioContext not supported", error);
play_sound = function() {
// no-op
// console.log("SFX disabled because AudioContext setup failed.");
};
}
I did a search, in search of a way to help you, but I did not find an effective way to disable the mands, however, I found a way to customize them, it may help you, follow the apple tutorial link
I think what's left to do now is wait, see if ios 13 will bring some option that will do what you want.