cocos2dx 3.3 视频播放的实现-VideoPlayer的使用

最近因为项目需求需要使用到视频播放功能。

在3.x版本之前如果需要用到视频播放功能就要使用原生的视频播放实现技术,好在3.x之后官方已经集成了视频播放功能,这是值得欣慰的。但是欣慰过后的悲剧在于,官方的文档一直跟不上版本的更新速度。虽然集成了这个功能,但是郁闷的是你要花费很大的力气去尝试使用技巧(仅限于类似我这种菜鸟)。

以下为我整了好久才摸到的使用方法,其实使用不难,难的是一定要注意这个集成的播放器(VideoPlayer)是有平台限制的。一些代码只有在android平台和IOS平台有效。废话不多说了,直接上实例代码:

HelloWorldScene.h文件

[cpp]  view plain copy print ?
  1. #ifndef __HELLOWORLD_SCENE_H__  
  2. #define __HELLOWORLD_SCENE_H__  
  3.   
  4. #include "cocos2d.h"  
  5. //务必引入以下2个.h文件  
  6. #include "ui/UIVideoPlayer.h"  
  7. #include "ui/CocosGUI.h"  
  8. USING_NS_CC;  
  9. class HelloWorld : public Layer  
  10. {  
  11. public:  
  12.     static Scene* createScene();  
  13.   
  14.     virtual bool init();  
  15.   
  16.     void onEnter();  
  17.       
  18.     void videoPlayOverCallback();  
  19.   
  20.     void showVideo();  
  21.     /** 
  22.      * 视频播放状态,只有在android和ios平台有效 
  23.      */  
  24. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)  
  25.     void videoEventCallback(Ref* sender, cocos2d::experimental::ui::VideoPlayer::EventType eventType);  
  26. #endif  
  27.   
  28.     CREATE_FUNC(HelloWorld);  
  29. };  
  30. #endif   

HelloWorldScene.cpp文件

[cpp]  view plain copy print ?
  1. #include "HelloWorldScene.h"  
  2.   
  3. USING_NS_CC;  
  4.   
  5. Scene* HelloWorld::createScene()  
  6. {  
  7.     auto scene = Scene::create();  
  8.     auto layer = HelloWorld::create();  
  9.     scene->addChild(layer);  
  10.     return scene;  
  11. }  
  12. bool HelloWorld::init()  
  13. {  
  14.     if ( !Layer::init() )  
  15.     {  
  16.         return false;  
  17.     }  
  18.     return true;  
  19. }  
  20.   
  21. void HelloWorld::onEnter(){  
  22.     Layer::onEnter();  
  23.     showVideo();  
  24. }  
  25.   
  26. void HelloWorld::showVideo(){  
  27.     Size size = Director::getInstance()->getVisibleSize();  
  28. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)  
  29.     auto videoPlayer = cocos2d::experimental::ui::VideoPlayer::create();  
  30.     videoPlayer->setPosition(Point(size.width / 2, size.height / 2));  
  31.     videoPlayer->setAnchorPoint(Vec2::ANCHOR_MIDDLE);  
  32.     videoPlayer->setContentSize(Size(size.width , size.height));  
  33.     this->addChild(videoPlayer);  
  34.     if (videoPlayer)  
  35.     {  
  36.         videoPlayer->setFileName("1111.mp4");  
  37.         videoPlayer->play();  
  38.     }  
  39.     videoPlayer->addEventListener(CC_CALLBACK_2(HelloWorld::videoEventCallback, this));  
  40. #endif  
  41. }  
  42.   
  43. /** 
  44.  * 视频播放完成的回调函数 
  45.  */  
  46. void HelloWorld::videoPlayOverCallback()  
  47. {  
  48.       
  49. }  
  50. /** 
  51.  *  视频播放的状态 
  52.  *  注意这里的代码,此处代码只有在android平台和Ios平台有效 
  53.  */  
  54. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)  
  55. void HelloWorld::videoEventCallback(Ref* sender, cocos2d::experimental::ui::VideoPlayer::EventType eventType){  
  56.     switch (eventType) {  
  57.     case cocos2d::experimental::ui::VideoPlayer::EventType::PLAYING:  
  58.         break;  
  59.     case cocos2d::experimental::ui::VideoPlayer::EventType::PAUSED:  
  60.         break;  
  61.     case cocos2d::experimental::ui::VideoPlayer::EventType::STOPPED:  
  62.         break;  
  63.     case cocos2d::experimental::ui::VideoPlayer::EventType::COMPLETED:  
  64.         videoPlayOverCallback();  
  65.         break;  
  66.     default:  
  67.         break;  
  68.     }  
  69. }  
  70. #endif  

如此即可实现视频播放了,对视频的控制请参考官方demo

================================下面是另一篇博客的记录========

Cocos2d-x v2.2.1版本

下面简单实现Cocos2d-x一个视频播放的模块,需要播放视频时,不用到处乱改了,一句代码搞定!

一. IOS播放本地视频

     对于IOS平台的视频播放,这里直接使用MediaPlayer.framework来播放视频

   注意:MediaPlayer.framework播放视频格式有限,可能需要转换为指定的视频格式才能播放!

    1.添加MediaPalyer框架到项目中

    2.简单写三个类

    VideoPlatform ,IOSPlayVideo,IOSVideoController

   1)VideoPlatform 这个类用来判断播放视频的平台,从而调用各自平台的视频播放接口

  VideoPlatform.h  

[cpp]  view plain copy
  1. #ifndef __Platform_H_H__  
  2. #define __Platform_H_H__  
  3. #include "cocos2d.h"  
  4. using namespace cocos2d;  
  5. class VideoPlatform   
  6. {  
  7.  public:  
  8.     //在当前的layer上播放视频,视频完毕或者点击跳过视频会跳转到指定的layer上(默认为空,也就是停留在当前layer上)  
  9.     static void playVideo(const char * filename,CCLayer *layer =NULL);  
  10. };  
  11.   
  12. #endif // __Platform_H_H__  

 VideoPlatform.cpp

[cpp]  view plain copy
  1. #include "VideoPlatform.h"  
  2. #include "../../cocos2dx/platform/CCPlatformConfig.h"  
  3. #if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)  
  4. #include   
  5. #include "../../cocos2dx/platform/android/jni/JniHelper.h"  
  6. #include   
  7. #elif(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)  
  8. #include "IOSPlayVideo.h"  
  9. #endif  
  10.   
  11. void VideoPlatform::playVideo(const char * filename,CCLayer *layer)  
  12. {  
  13.   
  14. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)  
  15.     //Android视频播放代码  
  16.     JniMethodInfo minfo;  
  17.     bool isHave = JniHelper::getMethodInfo(minfo,"org/cocos2dx/video/video","playVideo""()V");  
  18.     if (isHave) {  
  19.         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);  
  20.     }  
  21. #elif(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)  
  22.     //iOS视频播放代码  
  23.     IOSPlayVideo::playVideoForIOS(filename,layer);  
  24.       
  25. #endif  
  26.   
  27. }  

2) IOSPlayVideo是IOS平台播放视频的接口

IOSPlayVideo.h

[cpp]  view plain copy
  1. #ifndef __IOSPlayVideo_H_H__  
  2. #define __IOSPlayVideo_H_H__  
  3.   
  4. #include "cocos2d.h"  
  5. using namespace cocos2d;  
  6. class IOSPlayVideo   
  7. {   
  8. public:  
  9.     static void playVideoForIOS(const char * filename,CCLayer *layer);  
  10.       
  11. };  
  12.   
  13. #endif // __IOSPlayVideo_H_H__  

IOSPlayVideo.mm

[cpp]  view plain copy
  1. #include "IOSPlayVideo.h"  
  2. #include "IOSVideoController.h"  
  3.   
  4.  void IOSPlayVideo::playVideoForIOS(const char * filename,CCLayer *layer)  
  5. {  
  6. //   char * 转化为 NSString  
  7.     NSString *audioname=[NSString stringWithUTF8String:filename];  
  8.     IOSVideoController *app = [[IOSVideoController alloc] init];  
  9.     [app playVideo:audioname :layer];  
  10.       
  11. }  

3)最后IOSVideoController这个类就是ios播放视频的具体实现了

IOSVideoController.h

[cpp]  view plain copy
  1. #import "MediaPlayer/MediaPlayer.h"  
  2. #import "cocos2d.h"  
  3. #include "SimpleAudioEngine.h"  
  4. using namespace cocos2d;  
  5. using namespace CocosDenshion;  
  6.   
  7. @interface IOSVideoController :MPMoviePlayerViewController  
  8. {  
  9.  MPMoviePlayerController *movePlayer;  
  10.     UIWindow *window;  
  11.     CCLayer *TargetLayer;  
  12. }  
  13.   
  14. //播放网络视频  
  15. -(void)playUrlVideo;  
  16.   
  17. //在当前场景上播放视频,播完或者点击跳过视频 到指定的场景  
  18. -(void)playVideo:(NSString *)filename :(CCLayer *)targetLayer;  
  19. @end  

IOSVideoController.mm

[cpp]  view plain copy
  1. #import "IOSVideoController.h"  
  2. #import "AppController.h"  
  3. @implementation IOSVideoController  
  4.   
  5. //播放网络视频  
  6. -(void)playUrlVideo  
  7. {  
  8.   
  9.   
  10.   
  11. }  
  12. -(void)playVideo:(NSString *)filename :(CCLayer *)targetLayer  
  13. {  
  14.     TargetLayer =targetLayer;  
  15.     //跳转Layer非空  
  16.     if (targetLayer) {  
  17.         TargetLayer->retain();  
  18.     }  
  19.   
  20.     SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();  
  21.     SimpleAudioEngine::sharedEngine()->pauseAllEffects();  
  22.   
  23.     NSString *myFilePath = [[NSBundle mainBundle] pathForResource:filename ofType:nil inDirectory:nil];  
  24.     NSURL *url = [NSURL fileURLWithPath:myFilePath];  
  25.       
  26.     movePlayer=[[MPMoviePlayerController alloc] initWithContentURL:url];  
  27.     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:movePlayer];  
  28.       
  29.     if([movePlayer respondsToSelector:@selector(setFullscreen:animated:)])  
  30.     {  
  31.         movePlayer.shouldAutoplay=YES;  
  32.           
  33.         CCSize winSize=CCDirector::sharedDirector()->getWinSize();  
  34.         CCLog("winSize.width====%f    winSize.height====%f",winSize.width,winSize.height);  
  35.         //         这里iPad2和ipad3 视频位置调整是正确的,Iphone 可能需要细微调整  
  36.           
  37.         if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)  
  38.         {  
  39.             movePlayer.view.frame=CGRectMake(-80,80, 480, 320);  
  40.         }  
  41.         else if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)  
  42.         {  
  43.             movePlayer.view.frame=CGRectMake(-128, 128, winSize.width, winSize.height);  
  44.         }  
  45.         else  
  46.         {  
  47.             movePlayer.view.frame=CGRectMake(-80,80, 480, 320);  
  48.               
  49.         }  
  50.           
  51.         //        强制横屏  
  52.         CGAffineTransform landscapeTransform;  
  53.         UIDevice *device = [UIDevice currentDevice] ;  
  54.         if (device.orientation==UIDeviceOrientationLandscapeLeft)  
  55.         {  
  56.             landscapeTransform = CGAffineTransformMakeRotation(M_PI / 2);  
  57.         }  
  58.         else  
  59.         {  
  60.             landscapeTransform = CGAffineTransformMakeRotation(-M_PI / 2);  
  61.         }  
  62.         movePlayer.view.transform = landscapeTransform;  
  63.           
  64.         // 新建一个window,添加视频这个UIView  
  65.         window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];  
  66.           
  67.         [window addSubview:movePlayer.view];  
  68.         [window makeKeyAndVisible];  
  69. //  在视频上方添加“跳过”按钮        
  70.         CGRect frame = CGRectMake(768-100, 100, 100, 50);  
  71.         UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];  
  72.         button.frame = frame;  
  73.         [button setTitle:@"跳过" forState: UIControlStateNormal];  
  74.           
  75.         button.transform =landscapeTransform;  
  76.         button.backgroundColor = [UIColor clearColor];  
  77.         button.tag = 2000;  
  78.         [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];  
  79.         [window addSubview:button];  
  80.           
  81.   
  82.         //  设置是否带控制条  
  83.         movePlayer.controlStyle = MPMovieControlStyleNone;  
  84.         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitFullScreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];  
  85.           
  86.     }  
  87.     else  
  88.     {  
  89.         movePlayer.controlStyle=MPMovieControlModeHidden;  
  90.     }  
  91.       
  92.     [self playMovie];  
  93.   
  94.   
  95. }  
  96. //跳过视频  
  97. -(IBAction) buttonClicked:(id)sender {  
  98.     [movePlayer stop];  
  99.   
  100.     [movePlayer.view removeFromSuperview];  
  101.     [movePlayer release];  
  102.     [window release];  
  103.     SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();  
  104.     SimpleAudioEngine::sharedEngine()->resumeAllEffects();  
  105.       
  106.     if (!TargetLayer) {  
  107.         return;  
  108.     }  
  109.     TargetLayer->removeAllChildrenWithCleanup(true);  
  110.     TargetLayer->removeFromParent();  
  111.   
  112.     CCScene * scene =CCScene::create();  
  113.     scene->addChild(TargetLayer,10);  
  114.     CCDirector::sharedDirector()->replaceScene(scene);  
  115.       
  116.       
  117. }  
  118. //播放开始  
  119. -(void) playMovie  
  120. {  
  121.     MPMoviePlaybackState state=movePlayer.playbackState;  
  122.     if(state==MPMoviePlaybackStatePlaying)  
  123.     {  
  124.         NSLog(@"Movie is already playing.");  
  125.         return;  
  126.     }  
  127.     [movePlayer play];  
  128. }  
  129. //退出全屏  
  130. -(void)exitFullScreen:(NSNotification *)notification{  
  131.     CCLOG("exitFullScreen");  
  132.     movePlayer.controlStyle=MPMovieControlStyleDefault;  
  133.     [movePlayer.view removeFromSuperview];  
  134. }  
  135. //视频播放结束  
  136. - (void) movieFinished:(NSNotificationCenter *)notification{  
  137. //    CCLOG("moviePlaybackFinished");  
  138.     //视频播放完毕  
  139.     
  140.     movePlayer.controlStyle=MPMovieControlStyleDefault;  
  141.     MPMoviePlaybackState state=movePlayer.playbackState;  
  142.     if(state==MPMoviePlaybackStateStopped){  
  143.         NSLog(@"Movie is already stopped.");  
  144.         return;  
  145.     }  
  146.     [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:movePlayer];  
  147.     if([movePlayer respondsToSelector:@selector(setFullscreen:animated:)])  
  148.     {  
  149.   
  150.         [movePlayer.view removeFromSuperview];  
  151.         [window release];  
  152.           
  153.         SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();  
  154.         SimpleAudioEngine::sharedEngine()->resumeAllEffects();  
  155.           
  156.         if (!TargetLayer) {  
  157.             return;  
  158.         }  
  159.         TargetLayer->removeAllChildrenWithCleanup(true);  
  160.         TargetLayer->removeFromParent();  
  161.         CCScene * scene =CCScene::create();  
  162.         scene->addChild(TargetLayer,10);  
  163.         CCDirector::sharedDirector()->replaceScene(scene);  
  164.   
  165.     }  
  166.       
  167. }  
  168.   
  169. - (void)dealloc {  
  170.     [super dealloc];  
  171.     if (TargetLayer) {  
  172.             TargetLayer->release();  
  173.     }  
  174.   
  175. }  
  176. @end  


 
  

IOS项目里只需在需要的地方调用接口

//只在当前layer上播放视频,播完不跳转就调这个

  VideoPlatform::playVideo("test.mp4");

//当前layer上播放视频,播完跳转到指定layer就调这个

  VideoPlatform::playVideo("test.mp4",TestLayer::create());

就可以播放视频了!有没有发觉世界瞬间变得美好了一点呢?

二.IOS播放网络视频

只需将

[cpp]  view plain copy
  1. NSURL *url = [NSURL fileURLWithPath:myFilePath];  
类似改为:

[cpp]  view plain copy
  1. NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/test.mp4"];  

(后面填写视频地址就OK!)


三.Android 播放本地视频

至于Android就稍微麻烦一点,需要用到Jni 技术, C++调用java

1) 添加一个VideoActivity

[java]  view plain copy
  1. package org.cocos2dx.video;    
  2.      
  3. import android.app.Activity;  
  4. import android.content.pm.ActivityInfo;  
  5. import android.media.MediaPlayer;  
  6. import android.net.Uri;  
  7. import android.os.Bundle;  
  8. import android.view.Window;  
  9. import android.view.WindowManager;  
  10. import android.widget.MediaController;  
  11. import android.widget.VideoView;  
  12.     
  13.     
  14. public class VideoActivity extends Activity {    
  15.     @Override    
  16.     protected void onCreate(Bundle savedInstanceState) {     
  17.         super.onCreate(savedInstanceState);    
  18.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  19.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   
  20.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);   
  21.         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);  
  22.         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//强制为横屏  
  23.         setContentView(R.layout.videoview);  
  24.        
  25.        final VideoView videoView = (VideoView)findViewById(R.id.VideoView01);   
  26.         videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" +R.raw.theme));   
  27.         videoView.start();   
  28. //        视频播控制条设置  
  29.           MediaController controller = new MediaController(VideoActivity.this);  
  30.           videoView.setMediaController(controller);  
  31. //        播放完成监听  
  32.           videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener()  
  33.            {  
  34.              @Override  
  35.              public void onCompletion(MediaPlayer mp)  
  36.              {  
  37.                //播放结束后的动作,返回点击播放视频的那个页面  
  38.                 finish();  
  39.              }  
  40.             });  
  41.           
  42.     }    
  43.     
  44.   
  45. }   


2) 修改AndroidManifest.xml,添加一个Activity

[html]  view plain copy
  1. <activity android:name="VideoActivity"  
  2.           android:label="@string/app_name"  
  3.           android:screenOrientation="landscape"  
  4.           android:theme="@android:style/Theme.NoTitleBar.Fullscreen"  
  5.           android:configChanges="orientation">  
  6.     <intent-filter>  
  7.         <action android:name="android.intent.action.MAIN" />  
  8.         <category android:name="android.intent.category.DEFAULT" />  
  9.     intent-filter>  
  10. activity>  


3) 在res /layout添加一个 videoview.xml

[html]  view plain copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:gravity="center"  
  7.     tools:context=".VideoActivity" >  
  8.       
  9.     <VideoView  
  10.         android:id="@+id/VideoView01"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="fill_parent"  
  13.         android:layout_alignParentLeft="true"  
  14.         android:layout_alignParentRight="true"  
  15.         android:layout_alignParentTop="true"  
  16.         android:orientation="horizontal"  
  17.         android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />  
  18.   
  19. RelativeLayout>  


4)在res 下添加一个raw文件夹,里面放你要播放的视频,例如:theme.mp4,这里我的视频文件名为theme


5)修改video.java (我的Android 项目包名为 org.cocos2dx.video)

[java]  view plain copy
  1. package org.cocos2dx.video;  
  2.   
  3. import org.cocos2dx.lib.Cocos2dxActivity;  
  4. import org.cocos2dx.lib.Cocos2dxGLSurfaceView;  
  5.   
  6. import android.content.Intent;  
  7. import android.os.Bundle;  
  8.   
  9. public class video extends Cocos2dxActivity{  
  10.      public static video instance;   
  11.      public static Intent intent;   
  12.     protected void onCreate(Bundle savedInstanceState){  
  13.         super.onCreate(savedInstanceState);   
  14.         instance =this;  
  15.         intent = new Intent(video.this, VideoActivity.class);    
  16.      
  17.     }  
  18.     void playVideo()    
  19.     {    
  20.       instance.startActivity(intent);           
  21.     }      
  22.     public Cocos2dxGLSurfaceView onCreateView() {  
  23.         Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);  
  24.         // video should create stencil buffer  
  25.         glSurfaceView.setEGLConfigChooser(5650168);  
  26.           
  27.         return glSurfaceView;  
  28.     }  
  29.     static {  
  30.         System.loadLibrary("cocos2dcpp");  
  31.     }       
  32. }  


至此 Android播放本地视频就OK了!

四.Android 播放网络视频


新添加一个如下方法即可(同样也可以使用JNI C++调Java)

[java]  view plain copy
  1. void playURLVideo()  
  2. {  
  3.     Intent intent = new Intent(Intent.ACTION_VIEW);  
  4.        String type = "video/* ";  
  5.        Uri uri = Uri.parse("http://forum.ea3w.com/coll_ea3w/attach/2008_10/12237832415.3gp");  
  6.        intent.setDataAndType(uri, type);  
  7.        instance.startActivity(intent);    
  8. }  

你可能感兴趣的:(cocos2dx,3.x)