为媒体禁用 iOS Safari 锁屏刷屏

Disable iOS Safari lock screen scrubber for media

iOS 上的 Safari 在其锁定屏幕上放置了一个用于简单 HTMLAudioElements 的进度条。例如:

const a = new Audio();
a.src = 'https://example.com/audio.m4a'
a.play();

JSFiddle:https://jsfiddle.net/0seckLfd/

锁定屏幕将允许我在当前播放的音频文件中选择一个位置。

如何禁用用户在锁定屏幕上擦除文件的功能?显示 的元数据 很好,能够 pause/play 也是可以接受的,但如果需要,我也可以禁用它。

完全禁用锁屏播放器

如果你想完全删除锁屏播放器,你可以这样做

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.net/5s8c9eL0/3/

切换标签页或锁定屏幕时停止播放器 (要清理的代码根据您的需要改进)

我进行了搜索,寻找一种方法来帮助你,但我没有找到禁用命令的有效方法,但是,我找到了一种自定义它们的方法,它可能对你有帮助,请按照 apple tutorial link

我想现在剩下要做的就是等待,看看 ios 13 是否会带来一些可以满足您要求的选项。

据我了解,您不能 block/hide 擦除命令,除非您可以将音频标记为实时流。话虽这么说,你可以使用js来拒绝擦洗server-side。参考答案here。虽然这个答案说的是视频,但它也适用于音频。

使用网络音频也可以避免锁屏/控制中心滑动条API。

这是预加载声音并播放它的示例,带有注释和错误处理:


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.");
    };
}