为媒体禁用 iOS Safari 锁定屏幕擦除器

Posted

技术标签:

【中文标题】为媒体禁用 iOS Safari 锁定屏幕擦除器【英文标题】:Disable iOS Safari lock screen scrubber for media 【发布时间】:2019-11-09 00:35:22 【问题描述】:

ios 上的 Safari 在其锁定屏幕上为简单的 htmlAudioElements 放置了一个洗涤器。例如:

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

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

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

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

【问题讨论】:

我猜功能是由程序代码决定的。我只想参考是否允许用户在锁定屏幕上擦洗文件。但是,设计指南不允许这样做,因为它需要用户操作才能产生某些效果。 @GillsoftAB 不幸的是,在某些情况下,例如内容许可协议,不允许用户擦洗。我正在研究一种方法,可以在用户尝试查找文件时返回到上次偏移量,但这很麻烦,而且用户体验不好。 忽略用户更改,除非某些条件。例如if (make_ui_change && user_paid) ... 这就是我所做的。然后任何拖动的项目都会正确地重新对齐(但仍然可以拖动而没有效果)。 @GillsoftAB 是的,这就是我正在采取的方法。不幸的是,我没有直接从这些控件中获得任何事件。媒体元素由这个操作系统小部件直接控制,所以我只能在事后做出回应。我已经尝试过e.preventDefault()e.stopPropagation() 以及seekedseeking 事件中没有的东西,但它们什么也没做。因此,我认为我能做的最好的事情就是跟踪时间,然后再寻找它。 啊,你用的是 React Native 还是类似的?还是你使用 Apple Music API? 【参考方案1】:

在锁定屏幕上完全禁用播放器

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

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/

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

【讨论】:

谢谢,停止音频对我来说不是一个选项,但我赞成这个答案,因为它可能对其他人有帮助。【参考方案2】:

据我了解,除非您可以将音频标记为实时流,否则您无法阻止/隐藏清理命令。话虽如此,您可以使用 js 拒绝清理服务器端。参考答案here。尽管该答案涉及视频,但它也适用于音频。

【讨论】:

谢谢,是的,我正在阻止寻求客户端。不理想,但可能是目前唯一的解决方法。谢谢。【参考方案3】:

使用 Web Audio 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.");
    ;

【讨论】:

我无法让它工作。对于我在 Safari、Chrome 或 Firefox 中尝试过的任何文件,它抱怨它无法“解码音频数据”或“传递给 decodeAudioData 的缓冲区包含未知的内容类型”......即使播放完全相同的路径我们目前的&lt;audio&gt; 方法很好。我猜 Web Audio API 的工作方式与音频元素有点不同?【参考方案4】:

我做了一个搜索,想找到一种方法来帮助你,但是我没有找到一个有效的方法来禁用这些命令,但是我找到了一种自定义它们的方法,它可能对你有帮助,关注apple tutorial link

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

【讨论】:

很遗憾,该链接与 Safari 中的网页无关。

以上是关于为媒体禁用 iOS Safari 锁定屏幕擦除器的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS Safari 中播放音频时如何设置缩略图?

当 VoiceOver 运行时,如何实现像 Podcast 应用程序这样的可拖动擦除器?

防止 iOS 移动 Safari 闲置/自动锁定/休眠?

如何在 Safari 和 iOS 11 上播放 WebRTC 媒体流

iOS AVPlayer:屏幕锁定时暂停视频

在 safari ios 上禁用下拉以退出全屏模式