基于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 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ...
随机推荐
- Sublime Text编辑器如何隐藏顶部的菜单栏
隐藏前: 解决办法: 1.按住Ctrl+Shifp+p,出现一个框,在框里输入“view:”,出现了如下界面 2.选择:“View:Toggle Menu”即可.结果为: 大功告成!!!!
- [06] Java的数据类型
1.基本数据类型 1.1 基本数据类型 byte.chart.short.int.long.float.double.boolean 共8种数据类型为基本数据类型: 数据类型 位数 取 ...
- 如何用一天时间实现自己的RPC框架
前言 最近,闲来无事,自己写了一个简单的RPC框架,我把它叫做SimpleRpc.它有多简单?一共只有1400行代码.这个RPC只是作为自己试验作品,交流技术之用,当然如果你敢用,也可以放到生产环境之 ...
- 自己把jar包添加到maven仓库中
定制库到Maven本地资源库 这里有2个案例,需要手动发出Maven命令包括一个 jar 到 Maven 的本地资源库. 要使用的 jar 不存在于 Maven 的中心储存库中. 您创建了一个自定义的 ...
- angular $compiler
directive是如何被compiled HTML编译发生在三个阶段: 1.$compile遍历DOM节点匹配directives 如果compiler找到元素上的directive,directi ...
- [转载]iOS开发之手势识别
感觉有必要把iOS开发中的手势识别做一个小小的总结.在上一篇iOS开发之自定义表情键盘(组件封装与自动布局)博客中用到了一个轻击手势,就是在轻击TextView时从表情键盘回到系统键盘,在TextVi ...
- Redis常见的应用场景解析
Redis是一个key-value存储系统,现在在各种系统中的使用越来越多,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景. Redis特性 一个产品的使用场 ...
- oracle存储过程中is和as区别
在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别:在视图(VIEW)中只能用AS不能用IS:在游标(CURSOR)中只能用IS不能用AS.
- JSP入门 taglib
自定义标签库(taglib),将原本需要写在jsp中的java代码封装起来,成为可复用的组件. taglib的写法和jsp动作(action)很相似,是由taglib前缀,冒号,标签名三者的组合体.其 ...
- 好用的前端页面性能检测工具—sitespeed.io
引言 最近在做HTTP2技术相关调研,想确认一下HTTP2在什么情境下性能会比HTTP1.x有显著提升,当我把http2的本地环境(nginx+PHP)部署完成后进行相关测试时,我遇到了以下问题: ( ...