前言
最近做的全景漫游项目中,要求点击场景中热点实现播放视频功能,具体要求:
- 在全景场景中的大屏上添加播放按钮;
- 点击播放按钮时弹出要播放的视频在屏幕上展示,并且自动开始播放;
- 点击播放器界面视频暂停;
- 点击周边空白区域视频播放界面消失;
其实单纯视频播放视频的功能还挺简单的,可以选择两种方式:
- 使用js实现播放功能,将点击热点事件绑定为js函数调用,通过参数传递形式传递要播放的视频地址;
- 使用Krpano提供的原生播放视频插件功能,本篇使用的该种方式;
具体实现效果如下(PC端的效果):
先附上具体实现步骤吧,最后说下如何解决在移动端播放效果不一致问题
步骤一:
-
我播放的是本地视频,在工程根目录下创建videos文件夹,存放要播放的视频,如果你想播放远程链接视频也是可以的。
-
添加一张播放按钮的图片放到images(在根目录下自定义创建)文件夹下,示例图片如下:
步骤二:
在需要播放视频的场景标签中,添加热点按钮,用来响应用户点击时弹出播放窗口,具体代码如下:
<!-- 添加视频热点 -->
<hotspot name="videospot"
url="./images/media_playback_start.png"
scale="0.6"
zoom="true"
ath="0" atv="5"
onclick="looktohotspot(get(name),90);"
onloaded=""
/>
注意这里,播放热点的点击响应事件的onclick事件,我想在点击按钮时,全景窗口的视角朝向播放按钮,使用Krpano自带的函数,looktohotspot,参数中get(name)获取到的是朝向的热点,90表示朝向的角度。
步骤三:
在plugins文件夹下创建video-player.xml文件,添加代码如下,关于代码解释可看代码注释部分:
<krpano>
//播放视频热点按钮onloaded时调用事件,创建好要用来播放视频的视图
<action name="videoplayer_open">
if(layer[videoplayer_bg],
trace('videoplayer_open - there is already a videoplayer!'-);,
<!-- 添加播放视图的半透明背景插件 -->
addlayer(videoplayer_bg);
set(layer[videoplayer_bg].type, container);
set(layer[videoplayer_bg].zorder, 999999);
set(layer[videoplayer_bg].safearea, false);
set(layer[videoplayer_bg].align, lefttop);
set(layer[videoplayer_bg].width, 100%);
set(layer[videoplayer_bg].height, 100%);
set(layer[videoplayer_bg].bgcolor, 0x000000);
set(layer[videoplayer_bg].bgalpha, 0.8);
set(layer[videoplayer_bg].bgcapture, true);
set(layer[videoplayer_bg].handcursor, false);
set(layer[videoplayer_bg].alpha, 0.0);
set(layer[videoplayer_bg].visible, false);
set(layer[videoplayer_bg].enabled, false);
set(layer[videoplayer_bg].onclick, videoplayer_close() );
tween(layer[videoplayer_bg].alpha, 1.0, 0.5, default,
<!-- 添加播放视图插件 -->
addlayer(videoplayer_plugin);
set(layer[videoplayer_plugin].parent, layer[videoplayer_bg]);
set(layer[videoplayer_plugin].align, center);
set(layer[videoplayer_plugin].loop, true);
set(layer[videoplayer_plugin].onclick, togglepause() );
set(layer[videoplayer_plugin].alpha, 0.0);
set(layer[videoplayer_plugin].scale, 0.0);
set(layer[videoplayer_plugin].visible, false);
set(layer[videoplayer_plugin].enabled, false);
<!-- 这里1%为该action被调用传入的第一个参数,%2第二个,%3第三个 -->
set(layer[videoplayer_plugin].onloaded, videoplayer_plugin_ready(%1) );
if('%2' != null, set(layer[videoplayer_plugin].posterurl,'%2'); );
if('%3' != null, set(layer[videoplayer_plugin].volume,%3); );
set(layer[videoplayer_plugin].url,'%VIEWER%/plugins/videoplayer.js');
);
);
</action>
<!-- 判断是否在钉钉内内 -->
<action name="getIsDingTalkBroswer">
jsget(dingitem,isDingTalkBrowser());
</action>
<action name="videoplayer_plugin_ready">
getIsDingTalkBroswer();
if(layer[videoplayer_plugin],
set(events[videoplayer_events].onresize, videoplayer_plugin_resize() );
set(layer[videoplayer_plugin].pausedonstart, true);
set(layer[videoplayer_plugin].onvideoready,
videoplayer_plugin_resize();
tween(scale,1,0.5,easeOutBack);
tween(alpha,1,0.5,default, ifnot(device.ios, play()));
);
<!-- 判断苹果设备上视频界面提前加载 -->
if(device.ios,
if(layer[videoplayer_plugin].visible == false,
layer[videoplayer_plugin].pause();
);
if(layer[videoplayer_plugin].visible,
set(layer[videoplayer_plugin].onclick, togglepause());
layer[videoplayer_plugin].playvideo(%1);
<!-- iOS内钉钉浏览器的加载位置 -->
if(dingitem=="1",layer[videoplayer_plugin].playvideo(%1););
);
<!-- iOS内非钉钉浏览器的视频加载位置 -->
if(dingitem=="2",layer[videoplayer_plugin].playvideo(%1););
);
if(layer[videoplayer_plugin].visible,
layer[videoplayer_plugin].playvideo(%1);
);
<!-- 播放识别到触摸事件时回调方法 -->
set(layer[videoplayer_plugin].ongottouch,
if(layer[videoplayer_plugin].visible == false,
layer[videoplayer_plugin].pause();
);
if(layer[videoplayer_plugin].visible,
if(layer[videoplayer_plugin].onclick == null,
set(layer[videoplayer_plugin].onclick, togglepause());
);
if(layer[videoplayer_plugin].ispaused AND layer[videoplayer_plugin].visible,
layer[videoplayer_plugin].play();
);
if(layer[videoplayer_plugin].ispaused==false,
layer[videoplayer_plugin].pause();
);
);
);
);
</action>
<!-- 点击播放按钮事件 -->
<action name="videoplayer_begin_play">
set(events[videoplayer_events].onresize, videoplayer_plugin_resize());
set(layer[videoplayer_bg].visible, true);
set(layer[videoplayer_plugin].visible, true);
set(layer[videoplayer_plugin].enabled, true);
set(layer[videoplayer_bg].enabled, true);
layer[videoplayer_plugin].playvideo(%1);
if(layer[videoplayer_plugin], layer[videoplayer_plugin].play());
</action>
<action name="videoplayer_plugin_resize">
<!-- use 90% width or height of available screen size -->
div(aspect, layer[videoplayer_plugin].imagewidth, layer[videoplayer_plugin].imageheight);
mul(new_videowidth, stagewidth, 0.90);
div(new_videoheight, new_videowidth, aspect);
mul(max_videoheight, stageheight, 0.90);
if(new_videoheight GT max_videoheight,
copy(new_videoheight, max_videoheight);
mul(new_videowidth, new_videoheight, aspect);
);
roundval(new_videowidth);
roundval(new_videoheight);
copy(layer[videoplayer_plugin].width, new_videowidth);
copy(layer[videoplayer_plugin].height, new_videoheight);
</action>
<action name="videoplayer_close">
set(layer[videoplayer_bg].visible, false);
set(layer[videoplayer_plugin].visible, false);
set(layer[videoplayer_plugin].enabled, false);
set(layer[videoplayer_bg].enabled, false);
if(layer[videoplayer_plugin], layer[videoplayer_plugin].stop());
</action>
</krpano>
在iOS系统,微信打开网页,使用krpano播放视频,会卡在第一帧,需要用手点击开始或者触屏才能播放。这是因为iOS系统原因,考虑到在移动端不浪费用户流量,但是为了保证用户交互的统一性,我们采用曲线救国的方式,实现在iOS端也能自动播放。另外本次还发现了一个问题:iOS端的微信浏览器和钉钉浏览器的模式不一样,微信浏览器不能自动播放,但是钉钉浏览器可以,所以需要区分一下是在哪个app中打开,完成不同的视频预加载策略,判断是钉钉的方案如下,因为代码已经实现了默认在iOS微信加载的策略,所以只需要判断在钉钉中打开即可:
//判断是否是钉钉或者支付宝内浏览器(krpano中调用)
function isDingTalkBrowser() {
let ua = navigator.userAgent.toLowerCase();
return ua.indexOf("dingtalk") !== -1 || ua.match(/Alipay/i) == "alipay" ? "1" : "2";
}
可将以上代码放到index.html文件中,这段代码的调用在video-player.xml中,具体调用如下:
<!-- 判断是否在钉钉内内,如果是在钉钉中打开,dingitem被赋值1,否则返回2 -->
<action name="getIsDingTalkBroswer">
jsget(dingitem,isDingTalkBrowser());
</action>
解决在iOS端加载视频界面不能自动播放的核心逻辑如下:
<!-- 判断苹果设备上视频界面提前加载 -->
if(device.ios,
if(layer[videoplayer_plugin].visible == false,
layer[videoplayer_plugin].pause();
);
if(layer[videoplayer_plugin].visible,
set(layer[videoplayer_plugin].onclick, togglepause());
layer[videoplayer_plugin].playvideo(%1);
<!-- iOS内钉钉浏览器的加载位置 -->
if(dingitem=="1",layer[videoplayer_plugin].playvideo(%1););
);
<!-- iOS内非钉钉浏览器的视频加载位置 -->
if(dingitem=="2",layer[videoplayer_plugin].playvideo(%1););
);
步骤四:
完善视频播放热点按钮的回调事件,具体代码如下:
<!-- 添加视频热点 -->
<hotspot name="videospot"
url="./images/media_playback_start.png"
scale="0.6"
zoom="true"
ath="0" atv="5"
onclick="looktohotspot(get(name),90);videoplayer_begin_play('%CURRENTXML%/videos/kkchina.mp4')"
onloaded="videoplayer_open('%CURRENTXML%/videos/kkchina.mp4', '%CURRENTXML%/images/videoplay.png', 1);"
/>
以上方案即可实现在Krpano中实现视频播放功能,并且解决在iOS端微信或者Safari浏览器中浏览全景网页播放视频卡在第一帧的问题。 注意:不要忘记在tour.xml中引入video-player.xml插件
<include url="./plugins/video-player.xml" />
其实在Krpano中播放视频,没有那么复杂,本篇文章之所以复杂,是为了解决在iOS端播放视频时在微信或者Safari(官方浏览器内核)不能自动播放(卡在第一帧的问题),在微信中打开播放视图效果如下,点击播放按钮弹出播放视图后可以自动播放: