Cocos2d-3.2 VideoPlayer 视频播放梳理01

时间:2021-10-10 09:27:50

         目前网上能查找到关于VideoPlayer的相关信息,要么就是版本2.x的情况下集成视频播放功能,要么就是不同于自己的需求解决了其他问题的实现整理,这里梳理一下自己在开发中遇到的问题及解决方法。方便自己的查阅和大家的交流学习,能力有限,记录过程中如有什么错误,欢迎斧正,希望大家多包涵……

        本人使用引擎版本及开发环境:cocos3.2-lua, VS2013,SublimeText等。

        需求:

             1,在游戏启动时需播放一个视频动画。

             2,点击视频动画界面跳过动画播放。

        两个细节问题:

        首先, Cocos2d自带的视频播放功能是在Cocos2d V3.0的版本中才集成添加进来的,所以说在3.0之前的版本是没有集成视频播放的,相应的之前的2.x版本要实现视频播放功能可能得自己手动添加相关的播放逻辑。(这个实现对应的平台环境下视频接口就行

Android:MediaPlayer;

iOS:mediaPlayer.framework下的MPMediaPlayerController、AVFounditon.framework下的AVPlayer和AVKit下的AVPlayerViewcontroller)

        其次,Cocos2d 3.x版本针对视频播放所提供的VideoPlayer节点的使用也只能在android和iOS系统平台下进行真机的编译和调试,不过最新的Cocos2d版本也支持Tizen系统了(这个自己没有试,感兴趣的可以试试)。也就是说所有的功能逻辑在编写完以后,如何验证是否正常,这时就需要你自己编译,打包在真机上进行调试验证了,这一点也还是比较蛋疼,但是因为所有功能都集成在VideoPlayer的这个节点上加上官方的依然提供了相应的示例,所以也不成问题(范伟说~)

       这里记录下lua环境下的简单实用方法,c++或者js的应该都一样,只是实现语言不同。

       lua环境下对应的导出可使用的方法如下:

        "getFileName":获取播放的视频文件名称。
"getURL":获取可播放视频的URL地址。
"play":播放视频。
"pause":暂停视频播放。
"setKeepAspectRatioEnabled":保持长宽比。
"resume":恢复视频播放。
"stop":停止视频播放。
"setFullScreenEnabled":设置全屏播放。
"setFileName":设置本地视频播放的文件名称。
"setURL":设置网络视频播放的URL地址。
"isKeepAspectRatioEnabled":判断是否有保持长宽比。
"onPlayEvent":视频播放事件的监听。
"isFullScreenEnabled":判断是否是全屏播放。
"isPlaying":判断是否正在播放。
"seekTo":跳转到指定位置播放。
"create":VideoPlayer节点的创建。

       一,实现视频的播放

       核心代码,也是相当的简单,这里只截取一部分:

    --视频播放节点的父节点容器
local layer = cc.Layer:create()
--视频播放对应的事件监听
local function onVideoEventCallback(sener, eventType)
if eventType == ccexp.VideoPlayerEvent.PLAYING then
--正在播放
elseif eventType == ccexp.VideoPlayerEvent.PAUSED then
--暂停播放
elseif eventType == ccexp.VideoPlayerEvent.STOPPED then
--停止播放
elseif eventType == ccexp.VideoPlayerEvent.COMPLETED then
--播放完成
end
end
local widgetSize = widget:getContentSize()
local videoPlayer = ccexp.VideoPlayer:create()
videoPlayer:setPosition(centerPos)
videoPlayer:setAnchorPoint(cc.p(0.5, 0.5))
videoPlayer:setContentSize(cc.size(widgetSize.width * 0.4,widgetSize.height * 0.4))
videoPlayer:addEventListener(onVideoEventCallback)
layer:addChild(videoPlayer)
在需要视频播放的地方调用:

videoPlayer:setFileName("res/cocosvideo.mp4")
videoPlayer:play()
即可。当然这里可以使用对应tolua导出的相关接口函数处理相应的功能需求,这里有个重要的函数是:setFullScreenEnabled,设置视频全屏播放。

(细节:

      1,在节点的构造方法里不要调用视频播放,这时可能会不成功,最好在节点的onEnter方法中进行视频的播放处理。

      2,视频的在播放时必须setFileName或者setURL方法连着play()一起才能开始视频的正常播放。

  )

   ,视频真机播放过程中的细节问题

     因为视频播放是在Android和iOS不同平台下对应的原生代码实现的,如果你按照上面的方法在真机设备上编译可以正常运行了,其实这时会有一些细节问题需要留意(自己环境及设备上发现的):

    1,Android环境下点击屏幕视频会暂停,再次点击视频又接着播放。

    2,iOS环境下点击屏幕会出现一般播放器上的进度条以及暂停缩放按钮界面。

    3,iOS环境下即使通过setFullScreenEnabled设置了全屏播放,在XCode模拟器下也会裁减掉1/4的视频界面。

    4,Android环境下点击返回键,视频会缩小。

    5,Android环境下点击home或者锁屏键以后,再次打开游戏界面时屏幕黑屏或者不能接着上次的位置继续播放。

-----------------------------------------------------------------------------------------------------------------------------------

解决办法:

    首先,针对Android和iOS不同平台下的问题解决在相应的:

    Android:cocos\platform\android\java\src\org\cocos2dx\lib目录下的Cocos2dxVideoView.java和Cocos2dxVideoHelper.java文件

    iOS:cocos\ui目录下的UIVideoPlayerIOS.mm文件下。可针对这两个文件解决以上细节问题。


    第1个问题:

    Android,注释掉onTouchEvent方法中if条件判断里的逻辑代码,让在点击屏幕时不响应即可。

@Override
public boolean onTouchEvent(MotionEvent event) {
if((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP)
{
if (isPlaying()) {
pause();
} else if(mCurrentState == STATE_PAUSED){
resume();
}
}


return true;
}


      第2个问题:

     iOS,红色部分改成绿色部分就行了。

-(void) setURL:(int)videoSource :(std::string &)videoUrl
{
self.moviePlayer.allowsAirPlay = false;
self.moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
self.moviePlayer.controlStyle = MPMovieControlStyleNone;
self.moviePlayer.view.userInteractionEnabled = true;
self.moviePlayer.view.userInteractionEnabled = false;
}


    第4个问题:

    Cocos2dxVideoHelper.java文件下,绿色部分注释掉即可。  

         static class VideoHandler extends Handler{
WeakReference<Cocos2dxVideoHelper> mReference;

VideoHandler(Cocos2dxVideoHelper helper){
mReference = new WeakReference<Cocos2dxVideoHelper>(helper);
}

@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case VideoTaskCreate: {
Cocos2dxVideoHelper helper = mReference.get();
helper._createVideoView(msg.arg1);
break;
}
case VideoTaskRemove: {
Cocos2dxVideoHelper helper = mReference.get();
helper._removeVideoView(msg.arg1);
break;
}
case VideoTaskSetSource: {
Cocos2dxVideoHelper helper = mReference.get();
helper._setVideoURL(msg.arg1, msg.arg2, (String)msg.obj);
break;
}
case VideoTaskStart: {
Cocos2dxVideoHelper helper = mReference.get();
helper._startVideo(msg.arg1);
break;
}
case VideoTaskSetRect: {
Cocos2dxVideoHelper helper = mReference.get();
Rect rect = (Rect)msg.obj;
helper._setVideoRect(msg.arg1, rect.left, rect.top, rect.right, rect.bottom);
break;
}
case VideoTaskFullScreen:{
Cocos2dxVideoHelper helper = mReference.get();
Rect rect = (Rect)msg.obj;
if (msg.arg2 == 1) {
helper._setFullScreenEnabled(msg.arg1, true, rect.right, rect.bottom);
} else {
helper._setFullScreenEnabled(msg.arg1, false, rect.right, rect.bottom);
}
break;
}
case VideoTaskPause: {
Cocos2dxVideoHelper helper = mReference.get();
helper._pauseVideo(msg.arg1);
break;
}
case VideoTaskResume: {
Cocos2dxVideoHelper helper = mReference.get();
helper._resumeVideo(msg.arg1);
break;
}
case VideoTaskStop: {
Cocos2dxVideoHelper helper = mReference.get();
helper._stopVideo(msg.arg1);
break;
}
case VideoTaskSeek: {
Cocos2dxVideoHelper helper = mReference.get();
helper._seekVideoTo(msg.arg1, msg.arg2);
break;
}
case VideoTaskSetVisible: {
Cocos2dxVideoHelper helper = mReference.get();
if (msg.arg2 == 1) {
helper._setVideoVisible(msg.arg1, true);
} else {
helper._setVideoVisible(msg.arg1, false);
}
break;
}
case VideoTaskRestart: {
Cocos2dxVideoHelper helper = mReference.get();
helper._restartVideo(msg.arg1);
break;
}
case VideoTaskKeepRatio: {
Cocos2dxVideoHelper helper = mReference.get();
if (msg.arg2 == 1) {
helper._setVideoKeepRatio(msg.arg1, true);
} else {
helper._setVideoKeepRatio(msg.arg1, false);
}
break;
}
case KeyEventBack: {
/*Cocos2dxVideoHelper helper = mReference.get();
helper.onBackKeyEvent();*/

break;
}
default:
break;
}

super.handleMessage(msg);
}
}