Cocos2d-x v2.2.1版本
下面简单实现Cocos2d-x一个视频播放的模块,需要播放视频时,不用到处乱改了,一句代码搞定!
一. IOS播放本地视频
对于IOS平台的视频播放,这里直接使用MediaPlayer.framework来播放视频
注意:MediaPlayer.framework播放视频格式有限,可能需要转换为指定的视频格式才能播放!
1.添加MediaPalyer框架到项目中
2.简单写三个类
VideoPlatform ,IOSPlayVideo,IOSVideoController
1)VideoPlatform 这个类用来判断播放视频的平台,从而调用各自平台的视频播放接口
VideoPlatform.h
- #ifndef __Platform_H_H__
- #define __Platform_H_H__
- #include "cocos2d.h"
- using namespace cocos2d;
- class VideoPlatform
- {
- public:
- //在当前的layer上播放视频,视频完毕或者点击跳过视频会跳转到指定的layer上(默认为空,也就是停留在当前layer上)
- static void playVideo(const char * filename,CCLayer *layer =NULL);
- };
- #endif // __Platform_H_H__
VideoPlatform.cpp
- #include "VideoPlatform.h"
- #include "../../cocos2dx/platform/CCPlatformConfig.h"
- #if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
- #include <jni.h>
- #include "../../cocos2dx/platform/android/jni/JniHelper.h"
- #include <android/log.h>
- #elif(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
- #include "IOSPlayVideo.h"
- #endif
- void VideoPlatform::playVideo(const char * filename,CCLayer *layer)
- {
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
- //Android视频播放代码
- JniMethodInfo minfo;
- bool isHave = JniHelper::getMethodInfo(minfo,"org/cocos2dx/video/video","playVideo", "()V");
- if (isHave) {
- minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
- }
- #elif(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
- //iOS视频播放代码
- IOSPlayVideo::playVideoForIOS(filename,layer);
- #endif
- }
2) IOSPlayVideo是IOS平台播放视频的接口
IOSPlayVideo.h
- #ifndef __IOSPlayVideo_H_H__
- #define __IOSPlayVideo_H_H__
- #include "cocos2d.h"
- using namespace cocos2d;
- class IOSPlayVideo
- {
- public:
- static void playVideoForIOS(const char * filename,CCLayer *layer);
- };
- #endif // __IOSPlayVideo_H_H__
IOSPlayVideo.mm
- #include "IOSPlayVideo.h"
- #include "IOSVideoController.h"
- void IOSPlayVideo::playVideoForIOS(const char * filename,CCLayer *layer)
- {
- // char * 转化为 NSString
- NSString *audioname=[NSString stringWithUTF8String:filename];
- IOSVideoController *app = [[IOSVideoController alloc] init];
- [app playVideo:audioname :layer];
- }
3)最后IOSVideoController这个类就是ios播放视频的具体实现了
IOSVideoController.h
- #import "MediaPlayer/MediaPlayer.h"
- #import "cocos2d.h"
- #include "SimpleAudioEngine.h"
- using namespace cocos2d;
- using namespace CocosDenshion;
- @interface IOSVideoController :MPMoviePlayerViewController
- {
- MPMoviePlayerController *movePlayer;
- UIWindow *window;
- CCLayer *TargetLayer;
- }
- //播放网络视频
- -(void)playUrlVideo;
- //在当前场景上播放视频,播完或者点击跳过视频 到指定的场景
- -(void)playVideo:(NSString *)filename :(CCLayer *)targetLayer;
- @end
IOSVideoController.mm
- #import "IOSVideoController.h"
- #import "AppController.h"
- @implementation IOSVideoController
- //播放网络视频
- -(void)playUrlVideo
- {
- }
- -(void)playVideo:(NSString *)filename :(CCLayer *)targetLayer
- {
- TargetLayer =targetLayer;
- //跳转Layer非空
- if (targetLayer) {
- TargetLayer->retain();
- }
- SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
- SimpleAudioEngine::sharedEngine()->pauseAllEffects();
- NSString *myFilePath = [[NSBundle mainBundle] pathForResource:filename ofType:nil inDirectory:nil];
- NSURL *url = [NSURL fileURLWithPath:myFilePath];
- movePlayer=[[MPMoviePlayerController alloc] initWithContentURL:url];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:movePlayer];
- if([movePlayer respondsToSelector:@selector(setFullscreen:animated:)])
- {
- movePlayer.shouldAutoplay=YES;
- CCSize winSize=CCDirector::sharedDirector()->getWinSize();
- CCLog("winSize.width====%f winSize.height====%f",winSize.width,winSize.height);
- // 这里iPad2和ipad3 视频位置调整是正确的,Iphone 可能需要细微调整
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
- {
- movePlayer.view.frame=CGRectMake(-80,80, 480, 320);
- }
- else if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
- {
- movePlayer.view.frame=CGRectMake(-128, 128, winSize.width, winSize.height);
- }
- else
- {
- movePlayer.view.frame=CGRectMake(-80,80, 480, 320);
- }
- // 强制横屏
- CGAffineTransform landscapeTransform;
- UIDevice *device = [UIDevice currentDevice] ;
- if (device.orientation==UIDeviceOrientationLandscapeLeft)
- {
- landscapeTransform = CGAffineTransformMakeRotation(M_PI / 2);
- }
- else
- {
- landscapeTransform = CGAffineTransformMakeRotation(-M_PI / 2);
- }
- movePlayer.view.transform = landscapeTransform;
- // 新建一个window,添加视频这个UIView
- window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
- [window addSubview:movePlayer.view];
- [window makeKeyAndVisible];
- // 在视频上方添加“跳过”按钮
- CGRect frame = CGRectMake(768-100, 100, 100, 50);
- UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- button.frame = frame;
- [button setTitle:@"跳过" forState: UIControlStateNormal];
- button.transform =landscapeTransform;
- button.backgroundColor = [UIColor clearColor];
- button.tag = 2000;
- [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
- [window addSubview:button];
- // 设置是否带控制条
- movePlayer.controlStyle = MPMovieControlStyleNone;
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitFullScreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
- }
- else
- {
- movePlayer.controlStyle=MPMovieControlModeHidden;
- }
- [self playMovie];
- }
- //跳过视频
- -(IBAction) buttonClicked:(id)sender {
- [movePlayer stop];
- [movePlayer.view removeFromSuperview];
- [movePlayer release];
- [window release];
- SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
- SimpleAudioEngine::sharedEngine()->resumeAllEffects();
- if (!TargetLayer) {
- return;
- }
- TargetLayer->removeAllChildrenWithCleanup(true);
- TargetLayer->removeFromParent();
- CCScene * scene =CCScene::create();
- scene->addChild(TargetLayer,10);
- CCDirector::sharedDirector()->replaceScene(scene);
- }
- //播放开始
- -(void) playMovie
- {
- MPMoviePlaybackState state=movePlayer.playbackState;
- if(state==MPMoviePlaybackStatePlaying)
- {
- NSLog(@"Movie is already playing.");
- return;
- }
- [movePlayer play];
- }
- //退出全屏
- -(void)exitFullScreen:(NSNotification *)notification{
- CCLOG("exitFullScreen");
- movePlayer.controlStyle=MPMovieControlStyleDefault;
- [movePlayer.view removeFromSuperview];
- }
- //视频播放结束
- - (void) movieFinished:(NSNotificationCenter *)notification{
- // CCLOG("moviePlaybackFinished");
- //视频播放完毕
- movePlayer.controlStyle=MPMovieControlStyleDefault;
- MPMoviePlaybackState state=movePlayer.playbackState;
- if(state==MPMoviePlaybackStateStopped){
- NSLog(@"Movie is already stopped.");
- return;
- }
- [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:movePlayer];
- if([movePlayer respondsToSelector:@selector(setFullscreen:animated:)])
- {
- [movePlayer.view removeFromSuperview];
- [window release];
- SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
- SimpleAudioEngine::sharedEngine()->resumeAllEffects();
- if (!TargetLayer) {
- return;
- }
- TargetLayer->removeAllChildrenWithCleanup(true);
- TargetLayer->removeFromParent();
- CCScene * scene =CCScene::create();
- scene->addChild(TargetLayer,10);
- CCDirector::sharedDirector()->replaceScene(scene);
- }
- }
- - (void)dealloc {
- [super dealloc];
- if (TargetLayer) {
- TargetLayer->release();
- }
- }
- @end
IOS项目里只需在需要的地方调用接口
//只在当前layer上播放视频,播完不跳转就调这个
VideoPlatform::playVideo("test.mp4");
//当前layer上播放视频,播完跳转到指定layer就调这个
VideoPlatform::playVideo("test.mp4",TestLayer::create());
就可以播放视频了!有没有发觉世界瞬间变得美好了一点呢?
二.IOS播放网络视频
只需将
- NSURL *url = [NSURL fileURLWithPath:myFilePath];
- NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/test.mp4"];
(后面填写视频地址就OK!)
三.Android 播放本地视频
至于Android就稍微麻烦一点,需要用到Jni 技术, C++调用java
1) 添加一个VideoActivity
- package org.cocos2dx.video;
- import android.app.Activity;
- import android.content.pm.ActivityInfo;
- import android.media.MediaPlayer;
- import android.net.Uri;
- import android.os.Bundle;
- import android.view.Window;
- import android.view.WindowManager;
- import android.widget.MediaController;
- import android.widget.VideoView;
- public class VideoActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//强制为横屏
- setContentView(R.layout.videoview);
- final VideoView videoView = (VideoView)findViewById(R.id.VideoView01);
- videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" +R.raw.theme));
- videoView.start();
- // 视频播控制条设置
- MediaController controller = new MediaController(VideoActivity.this);
- videoView.setMediaController(controller);
- // 播放完成监听
- videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
- {
- @Override
- public void onCompletion(MediaPlayer mp)
- {
- //播放结束后的动作,返回点击播放视频的那个页面
- finish();
- }
- });
- }
- }
2) 修改AndroidManifest.xml,添加一个Activity
- <activity android:name="VideoActivity"
- android:label="@string/app_name"
- android:screenOrientation="landscape"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:configChanges="orientation">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- tools:context=".VideoActivity" >
- <VideoView
- android:id="@+id/VideoView01"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:orientation="horizontal"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
- </RelativeLayout>
5)修改video.java (我的Android 项目包名为 org.cocos2dx.video)
- package org.cocos2dx.video;
- import org.cocos2dx.lib.Cocos2dxActivity;
- import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
- import android.content.Intent;
- import android.os.Bundle;
- public class video extends Cocos2dxActivity{
- public static video instance;
- public static Intent intent;
- protected void onCreate(Bundle savedInstanceState){
- super.onCreate(savedInstanceState);
- instance =this;
- intent = new Intent(video.this, VideoActivity.class);
- }
- void playVideo()
- {
- instance.startActivity(intent);
- }
- public Cocos2dxGLSurfaceView onCreateView() {
- Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
- // video should create stencil buffer
- glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
- return glSurfaceView;
- }
- static {
- System.loadLibrary("cocos2dcpp");
- }
- }
四.Android 播放网络视频
新添加一个如下方法即可(同样也可以使用JNI C++调Java)
- void playURLVideo()
- {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- String type = "video/* ";
- Uri uri = Uri.parse("http://forum.ea3w.com/coll_ea3w/attach/2008_10/12237832415.3gp");
- intent.setDataAndType(uri, type);
- instance.startActivity(intent);
- }