基于FFMPEG的跨平台播放器实现
基于FFMPEG的跨平台播放器实现
一、背景介绍
FFmpeg是一款超级强大的开源多媒体编解码框架,提供了录制、转换以及流化音视频的完整解决方案,包含了libavcodec、libavformat等多个多媒体库。FFmpeg是基于linux平台下开发的,同样可以运行于android(其实也是linux,你懂得!)、windows、Mac等平台。
FFmpeg有多重要?列举一下我们常用的多媒体处理软件:暴风影音、QQ影音、KMP(这个牛掰啊)、格式工厂……都使用了FFmpeg,可是他们都被FFmpeg刻上了耻辱柱:理由是把开源的东西改造成不开源的去赚钱!
说到播放器,千万不要把FFmpeg和播放器等同,这也是我这篇博文重点介绍的:FFmpeg处理的数据我们看不到,要想看到数据处理的结果,还需要借助另一套多媒体处理框架的帮助,这里就用surface代替吧。

图一
那么在不同平台下应该如何搭配FFmpeg与surface呢?我采用如下方案实现:
linux平台:FFmpeg + SDL。
Android平台:FFmpeg + surface(jni注入)。
Windows:FFmpeg + D3D。
以上三种平台的搭配本人全部实现(代码陆续上传到github中,欢迎大家批评指正)。实现难度么,个人感觉Android最难,linux其次,windows较为简单。本人是从事linux平台开发的,按道理说linux衍生出的Android不应该有太大困难的,这里强烈喷一下GFW,你把谷歌禁了也就罢了,Android相关资源也禁?Android源码、ADT这些资源找了十天半月,浪费了博主我大把青春岁月。
闲话少说,下面切入正题。
二、FFmpeg + surface(jni注入)
平台资源:adt-bundle-windows-x86-20140702、android-ndk-r4b、libffmpeg、cygwin。
具备知识:JNI、FFmpeg、Android surface。
1、 adt-bundle-windows-x86-20140702:windows上的Android开发环境,由eclipse、Android SDk、Android模拟器组成。
2、 android-ndk-r4b:交叉编译器,用来在Android开发环境下编译C系语言的交叉编译器。
3、 libffmpeg 经过修改的可以由android-ndk-r4b编译的ffmpeg源码。
4、 JNI :JAVA调用C、C++的技术。
5、 Android surface:android显示技术。
6、 Cygwin:因为交叉编译器是在linux上才能运行的,所以需要cygwin在windows上模拟一个linux环境。
参考网址:
http://www.cnblogs.com/bjzhanghao/archive/2012/11/14/2769409.html
(开发资源下载,解决了android官网被墙的不便)
http://blog.csdn.net/buleriver/article/details/26139109
(java调用C、C++的实现方法)
http://www.cnblogs.com/android100/p/android-surfaceView.html
(android surface 实现方法)
https://github.com/havlenapetr/FFMpeg
(超级大牛,ffmpeg在android上实现的鼻祖)
http://blog.csdn.net/conowen/article/details/7526398
(针对鼻祖的讲解)
https://github.com/dongguadan/surfaceDraw
(博主的DEMO)
开发步骤
1、搭建环境。
初学者不建议使用原生态的eclipse加上各种复杂的配置来进行环境搭建,那只会让你失去学习的乐趣,直接使用配套产品adt-bundle-windows-x86比较简洁。解压准备好adt-bundle-windows-x86、ndroid-ndk-r4b,装好cygwin,进行工程配置,主要是配置交叉编译器(eclipse是不能直接编译C系的,需要外部编译器),如图2、3。

图2

图3
2、编译工程
可以先使用android-ndk-r4b自带的hello-jni,也可以使用博主根据havlenapetr裁剪的surfaceDraw(一个简单的播放器,实现对SD卡中的视频文件进行播放)。相比于havlenapetr,surfaceDraw功能简洁,没有涉及C++、java中一些复杂的技术,可以清晰的看出android调用C++封装的ffmpeg接口的过程。
3、创建、运行模拟器
首先创建模拟器(必须基于API2.2的,后面会说明这样做的原因),然后运行,导入视频文件到SD卡,运行APP,如图4、图5、图6。

图4

图5

图6
其实Android平台是内置多媒体处理的API的,例如MediaPlayer,只需短短的几行代码就可以实现上面整个工程的功能。但是读者可以仔细想想,如果是这样简单的话,那么岂不是谁都可以开发一个简洁的手机版暴风影音?另一方面,如果开发者想用播放器播放一段流媒体,这段流媒体的接收参数是一段网址(就想优酷在线观看一样),而不是本地视频路径,MediaPlayer可以么?当然不可以。所以我们需要开发一套可以满足自己需求的API。
这就涉及到了Android framework层的知识了。Android简单说是运行在linux上的虚拟机,用过虚拟机的人都知道,那是相当的消耗资源,在虚拟机上在跑一个复杂的多媒体处理软件,效率可想而知。那么如何才能提高效率呢?在linux上运行C语言的程序效率当然是最高的,业内公认。所以需要有一种方法使Android 应用绕过虚拟层直接调用linux层的接口进行处理,这就是JNI技术的精髓,也是havlenapetr、surfaceDraw的实现原理。MediaPlayer其实也是用的这种技术,但是基于MediaPlayer的多媒体处理能力、灵活性当然是无法满足我们的需求的。

图7
唯一可惜的是目前为止的surfaceDraw只能在Android 2.X上运行,因为工程最重要的两个库libjniaudio.so、libjnivideo.so是基于Android2.X的源码编译的。基于Android4.X源码的编译博主尚位编译通过,主要原因是Android4.X对编译的环境要求比较高。后面有时间博主会提供给相关版本的libjniaudio.so、libjnivideo.so。
Android平台上的FFMpeg移植介绍到这里,下一篇会介绍linux平台上的FFMpeg与SDL的组合应用。
基于FFMPEG的跨平台播放器实现的更多相关文章
- 基于FFMPEG的跨平台播放器实现(二)
基于FFMPEG的跨平台播放器实现(二) 上一节讲到了在Android平台下采用FFmpeg+surface组合打造播放器的方法,这一节讲一下Windows平台FFmpeg + D3D.Linux平台 ...
- 基于ffmpeg的C++播放器1
基于ffmpeg的C++播放器 (1) 2011年12月份的时候发了这篇博客 http://blog.csdn.net/qq316293804/article/details/7107049 ,博文最 ...
- 仿迅雷播放器教程 -- 基于ffmpeg的C++播放器 (1)
2011年12月份的时候发了这篇博客 http://blog.csdn.net/qq316293804/article/details/7107049 ,博文最后说会开源一个播放器,没想到快两年了,才 ...
- 视频播放器控制原理:ffmpeg之ffplay播放器源代码分析
版权声明:本文由张坤原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/535574001486630869 来源:腾云阁 ht ...
- 基于Live555,ffmpeg的RTSP播放器直播与点播
基于Live555,ffmpeg的RTSP播放器直播与点播 多路RTSP高清视频播放器下载地址:http://download.csdn.net/detail/u011352914/6604437多路 ...
- 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
- 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】
转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ...
随机推荐
- C语言数据在内存分配
一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放 ...
- 201521123119《Java程序设计》第6周学习总结
1. 本周学习总结 2. 书面作业 Q1.clone方法 Q1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 只能在本类内部或者和 ...
- list,set,map总结
学习了集合,脑子里list,set,map之间的关系有混乱,在这里整理一下.有兴趣的朋友可以看下. 先看下 list,set,map各自的特点
- Java课程设计——GUI密码生成器团队博客
1.团队名称.团队成员介绍(需要有照片) 1.1团队名称 小黄人 1.2团队成员介绍 吴玲:组长,现任院就业会策划部副部长 郭琪容:组员,现任院硬件协会会长 2. 项目git地址 吴 玲 郭琪容 3. ...
- Java课程设计——学生信息系统(团队)
团队名称.团队成员介绍 1.1 团队名称 1.2 团队成员 高可心 网络1514 201521123097 组长 黄滢滢 网络1514 201521123095 组员 2.项目git地址 http:/ ...
- 201521123068 《java程序设计》 第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1.网络基础 1.1 比较ping www.baidu.com与ping cec.jmu. ...
- logback:logback和slf4j中的:appender、logger、encoder、layout
(1)appender 1.appender标签是logback配置文件中重要的组件之一.在logback配置文件中使用appender标签进行定义.可 以包含0个或多个appender标签. 2.a ...
- python数据分析panda库
panda内有两种数据结构,Series()和DataFrame() >>> a=pd.Series([1,2],index=['a','b']) >>> a a ...
- 【机器学习实战】Machine Learning in Action 代码 视频 项目案例
MachineLearning 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远 Machine Learning in Action (机器学习实战) | ApacheCN(apa ...
- 传统编程和IoC的对比
ref:http://www.importnew.com/13619.html 传统编程:决定使用哪个具体的实现类的控制权在调用类本身,在编译阶段就确定了. IoC模式:调用类只依赖接口,而不依赖具体 ...