基于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的跨平台播放器实现的更多相关文章

  1. 基于FFMPEG的跨平台播放器实现(二)

    基于FFMPEG的跨平台播放器实现(二) 上一节讲到了在Android平台下采用FFmpeg+surface组合打造播放器的方法,这一节讲一下Windows平台FFmpeg + D3D.Linux平台 ...

  2. 基于ffmpeg的C++播放器1

    基于ffmpeg的C++播放器 (1) 2011年12月份的时候发了这篇博客 http://blog.csdn.net/qq316293804/article/details/7107049 ,博文最 ...

  3. 仿迅雷播放器教程 -- 基于ffmpeg的C++播放器 (1)

    2011年12月份的时候发了这篇博客 http://blog.csdn.net/qq316293804/article/details/7107049 ,博文最后说会开源一个播放器,没想到快两年了,才 ...

  4. 视频播放器控制原理:ffmpeg之ffplay播放器源代码分析

    版权声明:本文由张坤原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/535574001486630869 来源:腾云阁 ht ...

  5. 基于Live555,ffmpeg的RTSP播放器直播与点播

    基于Live555,ffmpeg的RTSP播放器直播与点播 多路RTSP高清视频播放器下载地址:http://download.csdn.net/detail/u011352914/6604437多路 ...

  6. 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  7. 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  8. 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  9. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】

    转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] ...

随机推荐

  1. ajax中后台string转json

    首先导入alibaba的fastJson包 后台: String thirdPage1=prop.getProperty("thirdPage1"); String thirdPa ...

  2. 201521123024《Java程序设计》第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 注意conve ...

  3. 201521123098 《Java程序设计》第7周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 该方法调用了ind ...

  4. 201521123015 《Java程序设计》第2周学习总结

    1.本章学习总结 (1)学习了枚举,数组等方法 (2)通过实验内容的讲解,解决了一些问题 (3)进一步运用和了解码云 书面作业 1.使用Eclipse关联jdk源代码,并查看String对象的源代码( ...

  5. Java中 == 和 equals()详解

    java中的数据类型分为两种: 一 .基本数据类型: byte.short.int.long.float.double.char.boolean 比较它们需要用  ==  ,比较的是它们的值是否相等 ...

  6. 201521123005《Java程序设计》第十三周学习总结

    1. 本周学习总结 1.网络基本概念 2.网络常用命令 ipconfig 查看网络配置信息,如ip地址 ping 测试网络是否连通 telnet 远程登录 ftp 登陆ftp Fport (xp下)查 ...

  7. Python学习笔记011_模块_标准库_第三方库的安装

    容器 -> 数据的封装 函数 -> 语句的封装 类 -> 方法和属性的封装 模块 -> 模块就是程序 , 保存每个.py文件 # 创建了一个hello.py的文件,它的内容如下 ...

  8. ExtJS4为form表单必填项添加红色*标识

    通常情况下,ExtJS4的form表单必填项在输入状态下会有特殊提示,非输入状态下,显示却和其他项没有任何区别.为使必填项更加容易区分,我们需要根据allowBlank的属性值,为form表单中的必填 ...

  9. String... args 和 String[] args 的区别

    public static void main(String[] args) { callMe1(new String[] { "a", "b", " ...

  10. 绘制QQ圆形图像

    思路:这里用到的是图像求交.现在画布上画上圆形,即所需要的圆形头像,然后设置paint的属性设置为求交集,再将bitmap划到canvas上面就好了. 代码如下: private static Bit ...