cocos2d-x 在android下得视频播放
2013-05-22 12:08
337 查看
最近项目有需要在cocos2d-x android中播放一下视频,网上找了点资料最终成功播放。
在这里我也做下总结,方便以后查阅,留下学习的足迹,同时与大家共享。
下面是相关文章的内容:
我们来用强大的 SurfaceView 和 MediaPlayer 来组装一下
其原理就是:
MediaPlayer.setDisplay (SurfaceHolder sh)
sh 来自于SurfaceView,这样MediaPlayer就可以看到画面了。
不过这里面有几个细节需要注意:
1.何时调用 setDisplay :
一般可能会在构造函数里面就调用,这样系统会报错即使没报错也可能会出现 闻其声而不见其画面 的现象(大多数人遇到过),告诉你 Holder 无效,SurfaceHolder 是有一组回调接口的,通过
addCallback(SurfaceHolder.Callback callback)
设置,Callback 里面有个函数:
surfaceCreated(final SurfaceHolder holder)
其参数是 SurfaceHolder 所以我们可以猜到这个接口用来告诉我们 SurfaceHolder 创建好啦,所以我们在这个回调里面调用 MediaPlayer.setDisplay 就没问题啦!
2.如何播放视频文件:
在 coco2d-x 中,资源文件肯定都在 assets 目录下,所以我们首先想到通过 URI 引用 assets 下文件,Like:
但是这样是不行的,播放不出来,于是我就上 StackOverFlow 上搜搜,还是有前辈解决了,所以我要说一句:StackOverFlow 是一个神奇的网站。
正确的做法是调用这个接口:
assets 下可以通过:AssetFileDescriptor afd = getAssets().openFd(name); 方法得到 AssetFileDescriptor 对象,然后这样调用就OK:
你可能会想到:
这样也是不行的,具体原因没深入研究,此外再介绍用 res/raw 下资源的方法:
这样一个 android 层视频播放器就封装好了,实现细节可以看源代码:
View
Code
下面介绍如何调用这个播放器:
1.native 层:native 调 java 我们肯定要用到 jni 技术,cocos2d-x 封装了一个 jni 帮助类在:cocos2dx/platform/android/jni/JniHelper.h ,我们需要在 Java 层定义一个静态方法,然后通过 jni->CallStaticVoidMethod 调用:
View
Code
2.这样重点还是来到 Java 层:
View
Code
为了方便起见,我们把方法定义为 static 这样我们就需要一个当前 activity 的实例,这里用了一个 instance 静态全局变量,类似于单例设计模式。
完整代码:
View
Code
OK,核心方法介绍完毕,具体实现细节可以看我提供的 Demo 源码
demo下载地址
http://pan.baidu.com/share/link?shareid=474938&uk=1543627784
在这里我也做下总结,方便以后查阅,留下学习的足迹,同时与大家共享。
下面是相关文章的内容:
我们来用强大的 SurfaceView 和 MediaPlayer 来组装一下
其原理就是:
MediaPlayer.setDisplay (SurfaceHolder sh)
sh 来自于SurfaceView,这样MediaPlayer就可以看到画面了。
不过这里面有几个细节需要注意:
1.何时调用 setDisplay :
一般可能会在构造函数里面就调用,这样系统会报错即使没报错也可能会出现 闻其声而不见其画面 的现象(大多数人遇到过),告诉你 Holder 无效,SurfaceHolder 是有一组回调接口的,通过
addCallback(SurfaceHolder.Callback callback)
设置,Callback 里面有个函数:
surfaceCreated(final SurfaceHolder holder)
其参数是 SurfaceHolder 所以我们可以猜到这个接口用来告诉我们 SurfaceHolder 创建好啦,所以我们在这个回调里面调用 MediaPlayer.setDisplay 就没问题啦!
2.如何播放视频文件:
在 coco2d-x 中,资源文件肯定都在 assets 目录下,所以我们首先想到通过 URI 引用 assets 下文件,Like:
Uri uri = Uri.parse("file:///android_asset/" + name); //不可取
但是这样是不行的,播放不出来,于是我就上 StackOverFlow 上搜搜,还是有前辈解决了,所以我要说一句:StackOverFlow 是一个神奇的网站。
正确的做法是调用这个接口:
setDataSource (FileDescriptor fd, long offset, long length)
assets 下可以通过:AssetFileDescriptor afd = getAssets().openFd(name); 方法得到 AssetFileDescriptor 对象,然后这样调用就OK:
mPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
你可能会想到:
//直接调用 fd.getFileDescriptor() 是不行的mPlayer.setDataSource(fd.getFileDescriptor());
这样也是不行的,具体原因没深入研究,此外再介绍用 res/raw 下资源的方法:
Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.video2); //可取
这样一个 android 层视频播放器就封装好了,实现细节可以看源代码:
View
Code
下面介绍如何调用这个播放器:
1.native 层:native 调 java 我们肯定要用到 jni 技术,cocos2d-x 封装了一个 jni 帮助类在:cocos2dx/platform/android/jni/JniHelper.h ,我们需要在 Java 层定义一个静态方法,然后通过 jni->CallStaticVoidMethod 调用:
View
Code
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) JniMethodInfo t; if (JniHelper::getStaticMethodInfo(t, "com/yichou/demo/video/VideoDemo", "playVideo", "(Ljava/lang/String;)V")) { t.env->CallStaticVoidMethod(t.classID, t.methodID, t.env->NewStringUTF("video2.mp4")); }#endif
2.这样重点还是来到 Java 层:
View
Code
VideoView videoView; private void a(String name) { Log.i("", "name=" + name); // Uri uri = Uri.parse("file:///android_asset/" + name); //不可取// Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.video2); //可取 videoView = new VideoView(this); videoView.setOnFinishListener(this);// videoView.setVideo(uri); try { AssetFileDescriptor afd = getAssets().openFd(name); videoView.setVideo(afd); } catch (IOException e) { e.printStackTrace(); } group.addView(videoView); videoView.setZOrderMediaOverlay(true); } public static void playVideo(final String name) { if (instance != null) { instance.runOnUiThread(new Runnable() { @Override public void run() { instance.a(name); } }); } }
为了方便起见,我们把方法定义为 static 这样我们就需要一个当前 activity 的实例,这里用了一个 instance 静态全局变量,类似于单例设计模式。
完整代码:
View
Code
1 public class VideoDemo extends Cocos2dxActivity implements OnFinishListener { 2 ViewGroup group; 3 static VideoDemo instance; 4 5 6 protected void onCreate(Bundle savedInstanceState){ 7 super.onCreate(savedInstanceState); 8 instance = this; 9 10 group = (ViewGroup)getWindow().getDecorView();11 }12 13 14 VideoView videoView;15 16 private void a(String name) {17 Log.i("", "name=" + name);18 19 // Uri uri = Uri.parse("file:///android_asset/" + name); //不可取20 // Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.video2); //可取21 videoView = new VideoView(this);22 videoView.setOnFinishListener(this);23 // videoView.setVideo(uri);24 try {25 AssetFileDescriptor afd = getAssets().openFd(name);26 videoView.setVideo(afd);27 } catch (IOException e) {28 e.printStackTrace();29 }30 group.addView(videoView);31 videoView.setZOrderMediaOverlay(true);32 }33 34 public static void playVideo(final String name) {35 if (instance != null) {36 instance.runOnUiThread(new Runnable() {37 @Override38 public void run() {39 instance.a(name); 40 }41 });42 }43 }44 45 static {46 System.loadLibrary("game");47 }48 49 @Override50 public void onVideoFinish() {51 group.removeView(videoView);52 videoView = null;53 }54 }
OK,核心方法介绍完毕,具体实现细节可以看我提供的 Demo 源码
demo下载地址
http://pan.baidu.com/share/link?shareid=474938&uk=1543627784
相关文章推荐
- cocos2d-x 播放视频 on Android
- cocos2d-x IOS 和Android播放视频(包括网络视频)
- cocos2d-x3.0 android播放视频
- cocos2d-x lua 播放视频,VideoPlayer在Android和IOS下的坑,
- cocos2d-x IOS 和Android播放视频(包括网络视频)
- Cocos2d-3.x_视频播放(Android和iOS平台)
- cocos2d-x IOS 和Android播放视频(包括网络视频)
- cocos2d-x IOS,Android “一键式”播放视频
- Cocos2d-x v2.2.3 IOS,Android “一键式”播放视频
- cocos2d-x 播放视频 on Android
- cocos2d-x之Android播放视频c++代码
- cocos2d-x IOS 和Android播放视频(包括网络视频)
- cocos2d-x IOS 和Android播放视频(包括网络视频)
- cocos2d-x 播放视频(mp4)后 android手机音量按钮失效
- [转]Android WebView播放视频(包括全屏播放),androidwebview
- [cocos2d-x·解Bug]关于cocos2d-x游戏在android锁屏状态下播放Bgm的解决方法
- Android多媒体---VideoView(播放视频)
- Android 视频播放的几种方式
- 简单实现Aandroid视频中播放暂停按钮的效果
- Android版添加phonegap--InAndroid视频播放功能插件教程