(可能是在更新至 2.5.0 稳定版之后)安全媒体音频文件在 Safari 上首次点击无法播放。需要点击播放图标两到三次才能开始播放音频。前几次点击时,Web 服务器未收到任何请求。直到第三次左右点击才发送请求。
这看起来像是浏览器的问题,因为仅在 Safari 上出现,但令人有些怀疑的是,这一问题恰好在更新至 2.5.0 版本后开始出现。
有人有相关经验吗?
不确定这是否与以下内容有关:安全媒体上传文件会过期
(可能是在更新至 2.5.0 稳定版之后)安全媒体音频文件在 Safari 上首次点击无法播放。需要点击播放图标两到三次才能开始播放音频。前几次点击时,Web 服务器未收到任何请求。直到第三次左右点击才发送请求。
这看起来像是浏览器的问题,因为仅在 Safari 上出现,但令人有些怀疑的是,这一问题恰好在更新至 2.5.0 版本后开始出现。
有人有相关经验吗?
不确定这是否与以下内容有关:安全媒体上传文件会过期
@martin 这里有什么想法吗?
我明天会看一下。如果在那里需要点击两到三次,那听起来像是 Safari 的问题——我会在我的 iPhone 上试试。
我可以确认,在 iOS 上无论是 Safari 还是 Firefox,这个问题都存在。音频需要多次点击播放/暂停才能开始播放。两个浏览器中的组件看起来是一样的(我认为 Firefox 移动版只是封装了移动 Safari 的渲染引擎)。我在 iOS 13.5.1 上进行了测试。
这个 w3schools 的音频片段在 iOS Safari 和 Firefox 中都能正常工作:W3Schools Tryit Editor preload="none"?这是我唯一能想到的差异……或者是我们将安全媒体 URL 的 302 重定向到实际音频 URL 引发了某些问题?
以下是一些可能提示问题出在重定向上的线索:
看起来在首次点击时没有向服务器发出任何请求,因此问题一定出现在 302 重定向之前……
@martin 你找到关于这个问题的任何信息了吗?
很遗憾,我目前正忙于其他项目。不过这件事已在我的待办清单上,我希望很快能更详细地查看。我们内部也曾简要讨论过类似的问题。
到目前为止,这真是一场冒险……我成功在 Ubuntu 机器上的 Chrome 与 iPhone 上的 iOS Safari 之间设置了远程调试,但过程可谓波折重重。不过令人恼火的是,Network(网络)标签页是空白的,而这恰恰是调试中最关键的部分。
我发现,将 preload="metadata" 设置后,音频在 iOS Safari 中首次点击即可播放;而如果设置为 preload="none",则必须依次执行“播放 > 暂停 > 再播放”的操作,音频才能真正播放。
我用 video 标签也进行了测试,似乎存在类似的问题。
之前将 preload 改为 none 是出于您在此处提交的错误报告:https://meta.discourse.org/t/secure-media-uploads-expire/140894。现在我们陷入了一个相当尴尬的境地:如果把 preload 改回 metadata,上述问题又会重现。我们最近已将预签名 URL 的过期时间延长至 5 分钟(参见 https://github.com/discourse/discourse/pull/10160),因此原始问题现在会 减轻,但依然存在。
我仍在思考并尝试各种方案……目前还不确定是否能两全其美。对于受保护的多媒体内容来说,需要多次点击才能查看,这并非理想的体验。
编辑:我的调试器中的 Network 标签页现在可以正常工作了。以下是我们内部 Discourse 实例中一个 preload="none" 的 audio 标签的示例:
点击播放:GET /secure-media-uploads/dev/original/4X/6/1/8/618a6b19a07de18205cc9889cb604e414b30372b.mp3,返回状态为 Finished(已完成)。
点击暂停。
再次点击播放:GET presigned_url_here,返回状态为 206 Partial Content(部分内容),音频正常加载。
奇怪的是,当使用 preload="metadata" 时,我们得到的请求序列完全相同,而且只需一次点击播放。就像 Safari 在首次点击播放时获取元数据,然后仍需一次暂停和再次播放才能开始播放音频。
我不确定其他设备(例如 Android)是否也会出现这种情况?我目前没有设备可以在此方面进行测试。
这真是一次令人印象深刻的调试过程!
有一个问题:
这个响应具体长什么样?Finished 应该不是 HTTP 响应码吧?
这促使我搭建 mitmproxy 并再次检查此处发生的情况。看起来第一个“完成”请求并未从 iOS 设备或 Safari 浏览器发出。mitm 代理直到第二次点击 PLAY 时才开始记录任何内容。
那么,是否只在 Safari(包括 iOS 和桌面版,我在桌面版上也能复现此问题)中使用 preload="metadata",而在其他浏览器中使用 preload="none" 呢?
(另外,这在我测试的 Android PWA 上似乎并未发生。)
是的,我想我们不得不走这条路了。感谢你在 Android 和桌面版 Safari 上也进行了测试。目前 preload 属性存在问题,所以我想我们需要一些客户端代码来检测浏览器是否为 Safari,并替换 preload 属性。我今天会就此做一些实验。
为了确保我理解正确,这个 bug 会在 Safari 对音频进行分块下载且时间点超过 5 分钟时再次出现吗?
是的,但通过这个新修复,我_认为_可以通过仅在包含媒体的帖子进入视口时(例如通过滚动)更改 preload 属性来解决这个问题。问题在于,一旦从安全的媒体 URL 获取了元数据,就会生成预签名 URL 并在播放器中使用,该 URL 会在 5 分钟后过期。因此,如果在这 5 分钟内没有点击播放,该 URL 就会过期。
我在想是否可以使用 JavaScript 先播放再暂停媒体,这是否会对后续发送的 206 部分内容请求产生影响,因为这些请求似乎不受预签名 URL 过期的限制。不过我可能错了,还需要进一步测试。
编辑:我自己在 Android 设备的 Chrome 浏览器上确认了,这个问题在那里并不存在。
在 @martinwoodward 的许可下,我今天提交了几次更改,将所有上下文(包括安全媒体)中的音频/视频元素切换为使用 preload="metadata"。这应能解决此处描述的问题。
请注意,如果用户在页面上停留超过 5 分钟,他们可能无法播放音频或视频,因为安全 URL 目前仅在 5 分钟内有效。