最近因为项目需求需要使用到视频播放功能。
在3.x版本之前如果需要用到视频播放功能就要使用原生的视频播放实现技术,好在3.x之后官方已经集成了视频播放功能,这是值得欣慰的。但是欣慰过后的悲剧在于,官方的文档一直跟不上版本的更新速度。虽然集成了这个功能,但是郁闷的是你要花费很大的力气去尝试使用技巧(仅限于类似我这种菜鸟)。
以下为我整了好久才摸到的使用方法,其实使用不难,难的是一定要注意这个集成的播放器(VideoPlayer)是有平台限制的。一些代码只有在android平台和IOS平台有效。废话不多说了,直接上实例代码:
HelloWorldScene.h文件
- #ifndef __HELLOWORLD_SCENE_H__
- #define __HELLOWORLD_SCENE_H__
-
- #include "cocos2d.h"
-
- #include "ui/UIVideoPlayer.h"
- #include "ui/CocosGUI.h"
- USING_NS_CC;
- class HelloWorld : public Layer
- {
- public:
- static Scene* createScene();
-
- virtual bool init();
-
- void onEnter();
-
- void videoPlayOverCallback();
-
- void showVideo();
-
-
-
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- void videoEventCallback(Ref* sender, cocos2d::experimental::ui::VideoPlayer::EventType eventType);
- #endif
-
- CREATE_FUNC(HelloWorld);
- };
- #endif
HelloWorldScene.cpp文件
- #include "HelloWorldScene.h"
-
- USING_NS_CC;
-
- Scene* HelloWorld::createScene()
- {
- auto scene = Scene::create();
- auto layer = HelloWorld::create();
- scene->addChild(layer);
- return scene;
- }
- bool HelloWorld::init()
- {
- if ( !Layer::init() )
- {
- return false;
- }
- return true;
- }
-
- void HelloWorld::onEnter(){
- Layer::onEnter();
- showVideo();
- }
-
- void HelloWorld::showVideo(){
- Size size = Director::getInstance()->getVisibleSize();
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- auto videoPlayer = cocos2d::experimental::ui::VideoPlayer::create();
- videoPlayer->setPosition(Point(size.width / 2, size.height / 2));
- videoPlayer->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
- videoPlayer->setContentSize(Size(size.width , size.height));
- this->addChild(videoPlayer);
- if (videoPlayer)
- {
- videoPlayer->setFileName("1111.mp4");
- videoPlayer->play();
- }
- videoPlayer->addEventListener(CC_CALLBACK_2(HelloWorld::videoEventCallback, this));
- #endif
- }
-
-
-
-
- void HelloWorld::videoPlayOverCallback()
- {
-
- }
-
-
-
-
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- void HelloWorld::videoEventCallback(Ref* sender, cocos2d::experimental::ui::VideoPlayer::EventType eventType){
- switch (eventType) {
- case cocos2d::experimental::ui::VideoPlayer::EventType::PLAYING:
- break;
- case cocos2d::experimental::ui::VideoPlayer::EventType::PAUSED:
- break;
- case cocos2d::experimental::ui::VideoPlayer::EventType::STOPPED:
- break;
- case cocos2d::experimental::ui::VideoPlayer::EventType::COMPLETED:
- videoPlayOverCallback();
- break;
- default:
- break;
- }
- }
- #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
- #ifndef __Platform_H_H__
- #define __Platform_H_H__
- #include "cocos2d.h"
- using namespace cocos2d;
- class VideoPlatform
- {
- public:
-
- 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
- #include "../../cocos2dx/platform/android/jni/JniHelper.h"
- #include
- #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)
-
- 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)
-
- 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)
- {
-
- 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;
-
- 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);
-
-
- 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 = [[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{
-
-
-
- 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>
3) 在res /layout添加一个 videoview.xml
- 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>
4)在res 下添加一个raw文件夹,里面放你要播放的视频,例如:theme.mp4,这里我的视频文件名为theme
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);
-
- glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
-
- return glSurfaceView;
- }
- static {
- System.loadLibrary("cocos2dcpp");
- }
- }
至此 Android播放本地视频就OK了!
四.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);
- }