应一个朋友需求,研究了下 cocos2d-x 引擎在 android 平台上播放视频的方法,因为之前研究 Libgdx 播视频的时候有了经验,于是依葫芦画瓢

首先你不要想到去用系统的 VideoView 控件,他不适合我们

我们来用强大 SurfaceView 和 MediaPlayer 来组装一下,android 框架设计的很好啊

其原理就是:

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() {@Overridepublic 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                 @Override
38                 public void run() {
39                     instance.a(name);
40                 }
41             });
42         }
43     }
44
45     static {
46          System.loadLibrary("game");
47     }
48
49     @Override
50     public void onVideoFinish() {
51         group.removeView(videoView);
52         videoView = null;
53     }
54 }

OK,核心方法介绍完毕,具体实现细节可以看我提供的 Demo 源码

http://pan.baidu.com/share/link?shareid=505934&uk=4061068395

转载于:https://www.cnblogs.com/yichouangle/archive/2013/04/25/3042121.html

cocos2d-x 播放视频 on Android相关推荐

  1. android webview 播放视频总结,Android WebView 播放视频总结~

    此次遇到一个问题就是webView无法播放视频,查了下谷歌发现可以设置 setting.setPluginsEnabled(true); (从API 11 支持,可以不加) 这个从而播放视频,但是最新 ...

  2. android studio播放视频权限,Android Studio实现本地视频播放

    Android Studio的MediaPlayer播放本地视频 关于MediaPlayer错误[open failed: EACCES (Permission denied)] 可能会有下面几个方面 ...

  3. android 播放视频文件格式,Android视频文件格式解析相关分析

    目录结构 OpenCore的代码在如下目录中:external/opencore/.这个目录是OpenCore的根目录,其中包含的子目录以下所示: * android:这里面是一个上层的库,它基于PV ...

  4. android 调用系统播放器播放视频,适配android 7.0以上

    1.新一个类并继承 FileProvider 类,不做其他事情 public class AppFileProvider extends FileProvider {} 2.AndroidManife ...

  5. cocos android 播放视频,Cocos2d-x IOS 和Android播放视频

    本篇文章会给大家介绍在对IOS 和Android开发时,是如何实现播放视频这个功能的,下面就分别给大家介绍下. 一. iOS播放本地视频 对于ios平台的视频播放,这里直接使用MediaPlayer. ...

  6. Android三种播放视频的方式

     分类: Android多媒体(12)  Android应用层(93)  版权声明:本文为博主原创文章,未经博主允许不得转载. 在Android中,我们有三种方式来实现视频的播放: 1.使用其自带的播 ...

  7. 播放视频android学习笔记---44_在线视频播放器,网络视频解析器,SurfaceView 控件使用方法...

    最近用使开辟的过程中涌现了一个小题问,顺便录记一下因原和法方--播放视频 44_在线视频播放器 ------------------------- 1.注意这里,在模拟器中,android2.2和an ...

  8. android打开视频噔_android: 播放视频

    播放视频文件其实并不比播放音频文件复杂,主要是使用 VideoView 类来实现的.这个 类将视频的显示和控制集于一身,使得我们仅仅借助它就可以完成一个简易的视频播放器. VideoView 的用法和 ...

  9. android点击视频使用固定应用打开,Android 使用intent打开手机自带应用播放视频,音频,文档,还有打开应用市场...

    1 打开手机上的视频播放器播放视频String url = "http://192.168.0.1/1.mp4" Intent intent = new Intent(); int ...

  10. android播放mp3方法,Android之MediaPlayer播放音频与视频

    本节带来的是Android多媒体中的--MediaPlayer,我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码 和播放 ...

最新文章

  1. 双边滤波JAVA代码实现
  2. leetcode算法题--三数之和
  3. 设置tomcat服务为80端口,tomcat虚拟主机,tomcat日志
  4. 【运营】如何有效率的进行“用户访谈”
  5. dev c++运行没有结果_「C/C++」一行注释也能影响运行结果?
  6. 肖仰华 | 领域知识图谱落地实践中的问题与对策
  7. RabbitMQ如何解决各种情况下丢数据的问题
  8. button按钮onclick触发不了_用一篇深度好文,详解按钮的设计
  9. Unlocker使用
  10. 【软考 系统架构设计师】软件架构设计④ 基于架构的软件开发方法
  11. Python shapefile转GeoJson的两种方式
  12. 每台计算机需要配置网关吗,怎么设置一台电脑作为网关
  13. java-第十三章-类的无参方法(一)-模拟一个简单的购房商贷月供计算器
  14. HarmonyOS(鸿蒙系统)体系
  15. 计算机系统ARM64拆除炸弹
  16. python time.time()单位是秒不是毫秒
  17. arcgis python字段计算器_计算字段示例—帮助 | ArcGIS for Desktop
  18. 2022年全球市场360度手机摄像头总体规模、主要生产商、主要地区、产品和应用细分研究报告
  19. 阿里云服务器ECS配置选择(新手教程)
  20. 二.Linux下安装wkhtmltopdf 解决N个安装中的问题

热门文章

  1. Docker教程小白实操入门(9)--基于export导出容器与基于import导入一个镜像
  2. 浅析JDK,JRE,JVM的区别
  3. python小星_Python学习【第3篇】:列表魔法
  4. C++ printf输出
  5. nginx 禁止访问配置,指定URL地址指定IP允许访问
  6. Spring DeferredResult 实现长轮询
  7. 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第3节 综合案例_文件上传_3_综合案例_文件上传案例的服务器端...
  8. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_07 缓冲流_2_BufferedOutputStream_字节缓冲...
  9. c++ primer 6.3.3节练习答案
  10. 输入1-53周,输出1-53周的开始时间和结束时间