javascript - 在将视频元素添加到 DOM 之前,如何在用户启动的事件上播放带声音的视频?iOS Safari/Chrome/Webkit
问题描述
我有一个 Ember.js 应用程序,在 DOM 中有两个元素:1)查看器窗口(显示大图像或视频)2)缩略图网格(代表视频或图像)。
当用户单击视频的相应缩略图时,视频应加载到查看器窗口中并开始在 mobile/ios/android 上播放声音。我正在专门在 iOS Safari 上进行测试。
我知道关于用户发起的事件的webkit 策略,要求视频静音,除非用户明确点击事物(这是我在这里所做的操作),但在理解具体的实现细节时遇到了麻烦。
关于用户手势要求的注释:当我们说一个动作必须“作为用户手势的结果”发生时,我们的意思是导致调用 video.play() 的 JavaScript,例如,必须直接由 touchend、click、doubleclick 或 keydown 事件的处理程序产生。因此, button.addEventListener('click', () => { video.play(); }) 将满足用户手势要求。video.addEventListener('canplaythrough', () => { video.play(); }) 不会。
我相信对我来说问题是直到下一个渲染循环才将视频元素添加到dom中。即使用户通过单击缩略图来播放视频来启动事件,webkit 也不会将其识别为用户启动的事件并阻止播放视频,因为它有声音。
用户点击:
updateCurrentItem(item) {
set(this, "currentItem", item);
this.videoManager.playWhenLoaded.perform(item);
}
videoManager.playWhenLoaded
是一个 ember 并发任务。当视频加载到 dom 时,它会向 videoManager 服务注册自己。
playWhenLoaded: task(function*(item) {
let id = item.id;
while (this.videos.findBy("modelId", id) === undefined) {
yield timeout(200);
}
let video = this.videos.findBy("modelId", id);
video.player.muted = false;
video.player.play();
})
你能解释一下为什么这不起作用吗?以及我可以尝试哪些策略使其适用于我的用例?我确实有一个用户发起的事件触发了播放,那么如何让它工作呢?
头脑风暴,我可能需要这样的东西:
updateCurrentItem(item) {
set(this, "currentItem", item);
let player = this.videoManager.getVideoPlayer.perform(item);
//wait for the result somehow?
player.muted = false;
player.play();
}
其中 play() 是点击事件的直接结果。但是我可以阻止函数的执行以等待获取播放器吗?据我所知,它只会阻止运行循环,并且视频永远不会插入到 dom 中。
解决方案
推荐阅读
- scikit-image - 如何实现 PIL 着色功能?
- spring - Spring Boot:配置继承
- python - 我如何告诉熊猫在多年中对相同的月份进行分组?
- r - R中具有大稀疏张量的算术/逻辑运算
- c++ - 如何从一个在循环内使用迭代器的函数内部使用 getter 的类中检索特定成员?
- react-native - 如何从 Expo / React Native 将图像分享到 Instagram 故事
- r - 满足条件后退出 Plumber API
- python-3.x - 我们可以一次在单个 lambda 函数中使用 for 循环和 if else 吗?因此它可以在循环内工作时检查值
- python - 并行比较两个拆分的数据列表
- bash - 运行命令以通过 bash 创建目录