在 a 帧和 react.js 中播放和暂停视频
Play and pause video in a-frame and react.js
我的任务是通过一些动作在 videosphere 中播放和停止视频。我通过点击 videosphere 中的哪个视频应该改变来获得元素列表。我正在使用 React.js 和框架库。
我花了很多时间来实现所需的行为,所以我想分享一些代码和注释。突然有人会帮忙。
所以一些重要的事情:
- 您应该播放和暂停 a-video 而不是 a-videosphere,
a-videosphere 控制事件不起作用
- 你不能停止视频,你应该使用video.currentTime = 0;然后 video.pause()
- 您应该从视频标签中删除自动播放属性并自己播放,因为如果您保留自动播放属性,视频中的音轨将被复制
- 如果您删除了 autoplay 属性,您将无法在用户点击事件之前播放视频,因此您需要在某些元素上模仿 click 事件 .我创建了 hidden 跨度并在其上模仿点击事件。关于问题的文章https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
我的代码片段:
static getDerivedStateFromProps(nextProps, prevState){
let update = {};
if(nextProps.scene_item){
let isVideoSphere = nextProps.scene_item.type_id === experienceTypes.videosphere;
update.sceneUrl = nextProps.scene_item.asset_url;
update.isVideoSphere = isVideoSphere;
if(isVideoSphere){
playVideo('scene-video',true)
}
}
return Object.keys(update).length ? update : null;
}
componentWillUnmount() {
pauseVideo('scene-video')
}
export function pauseVideo(id) {
//pause aframe 360 video
let video = document.getElementById(id);
video.currentTime = 0;
video.pause()
}
export function playVideo(id,first_playing) {
//play aframe 360 video
let video = document.getElementById(id);
let el = document.getElementById('clikable-el-for-play-video');
if(video){
if(first_playing){
if(el){
el.click()
video.play()
}
}else video.play()
}
}
<a-scene>
<a-assets>
<video id="scene-video" src={sceneUrl} loop/>
</a-assets>
<a-videosphere src={'#scene-video'}/>
<span className="hidden" id="clikable-el-for-play-video"/>
</a-scene>
更新
在 safari 中发出点击事件不起作用,所以我进行了更改:
- 默认静音视频
- 通过单击桌面的 HTML 元素取消视频静音(我不需要额外的按钮,所以我使用 div)
- 在移动设备的同一 HTML 元素上通过 onTouchEnd 事件取消视频静音(如果您将使用按钮,我想您可以跳过它)
handleClickOnScene = (event) => {
let videoId = `scene-video-${this.props.scene_item.id}`;
let video = document.getElementById(videoId);
if(video.muted && !video.paused){
setTimeout(increaseVideoVolume(videoId), 5000)
}
}
export function increaseVideoVolume(id,first_playing) {
let video = document.getElementById(id);
if(video){
if(video.muted){
video.muted = false;
}
}
}
我的任务是通过一些动作在 videosphere 中播放和停止视频。我通过点击 videosphere 中的哪个视频应该改变来获得元素列表。我正在使用 React.js 和框架库。 我花了很多时间来实现所需的行为,所以我想分享一些代码和注释。突然有人会帮忙。
所以一些重要的事情:
- 您应该播放和暂停 a-video 而不是 a-videosphere, a-videosphere 控制事件不起作用
- 你不能停止视频,你应该使用video.currentTime = 0;然后 video.pause()
- 您应该从视频标签中删除自动播放属性并自己播放,因为如果您保留自动播放属性,视频中的音轨将被复制
- 如果您删除了 autoplay 属性,您将无法在用户点击事件之前播放视频,因此您需要在某些元素上模仿 click 事件 .我创建了 hidden 跨度并在其上模仿点击事件。关于问题的文章https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
我的代码片段:
static getDerivedStateFromProps(nextProps, prevState){
let update = {};
if(nextProps.scene_item){
let isVideoSphere = nextProps.scene_item.type_id === experienceTypes.videosphere;
update.sceneUrl = nextProps.scene_item.asset_url;
update.isVideoSphere = isVideoSphere;
if(isVideoSphere){
playVideo('scene-video',true)
}
}
return Object.keys(update).length ? update : null;
}
componentWillUnmount() {
pauseVideo('scene-video')
}
export function pauseVideo(id) {
//pause aframe 360 video
let video = document.getElementById(id);
video.currentTime = 0;
video.pause()
}
export function playVideo(id,first_playing) {
//play aframe 360 video
let video = document.getElementById(id);
let el = document.getElementById('clikable-el-for-play-video');
if(video){
if(first_playing){
if(el){
el.click()
video.play()
}
}else video.play()
}
}
<a-scene>
<a-assets>
<video id="scene-video" src={sceneUrl} loop/>
</a-assets>
<a-videosphere src={'#scene-video'}/>
<span className="hidden" id="clikable-el-for-play-video"/>
</a-scene>
更新
在 safari 中发出点击事件不起作用,所以我进行了更改:
- 默认静音视频
- 通过单击桌面的 HTML 元素取消视频静音(我不需要额外的按钮,所以我使用 div)
- 在移动设备的同一 HTML 元素上通过 onTouchEnd 事件取消视频静音(如果您将使用按钮,我想您可以跳过它)
handleClickOnScene = (event) => {
let videoId = `scene-video-${this.props.scene_item.id}`;
let video = document.getElementById(videoId);
if(video.muted && !video.paused){
setTimeout(increaseVideoVolume(videoId), 5000)
}
}
export function increaseVideoVolume(id,first_playing) {
let video = document.getElementById(id);
if(video){
if(video.muted){
video.muted = false;
}
}
}