基于 ffmpeg时时彩源码 php 的跨平台播放器实现

随着时时彩源码 php【大神源码论坛】dsluntan.com  【布丁源码论坛】budingbbs.com 企娥3393756370 游戏娱乐等直播业务的增长,在移动端观看直播的需求也日益迫切。但是移动端原生的播放器对各种直播流的支持却不是很好。Android 原生的 MediaPlayer 不支持 flv、hls 直播流,iOS 只支持标准的 HLS 流。本文介绍一种基于 ffplay 框架下的跨平台播放器的实现,且兼顾硬解码的实现。

播放器原理:

直观的讲,我们播放一个媒体文件一般需要5个基本模块,按层级顺序:文件读取模块(Source)、解复用模块(Demuxer)、视频频解码模块(Decoder)、色彩空间转换模块(Color Space Converter)、音视频渲染模块(Render)。数据的流向如下图所示,其中 ffmpeg 框架包含了文件读取、音视频解复用的模块。

  1. 文件读取模块(Source)的作用是为下级解复用模块(Demuxer)以包的形式源源不断的提供数据流,对于下一级的Demuxer来说,本地文件和网络数据是一样的。在ffmpeg框架中,文件读取模块可分为3层:

    • 协议层: pipe,tcp,udp,http等这些具体的本地文件或网络协议
    • 抽象层:URLContext结构来统一表示底层具体的本地文件或网络协议
    • 接口层用:AVIOContext结构来扩展URLProtocol结构成内部有缓冲机制的广泛意义上的文件,并且仅仅由最上层用AVIOContext对模块外提供服务,实现读媒体文件功能。
  2. 解复用模块(Demuxer):的作用是识别文件类型,媒体类型,分离出音频、视频、字幕原始数据流,打上时戳信息后传给下级的视频频解码模块(Decoder)。可以简单的分为两层,底层是 AVIContext,TCPContext,UDPContext 等等这些具体媒体的解复用结构和相关的基础程序,上层是 AVInputFormat 结构和相关的程序。上下层之间由 AVInputFormat 相对应的 AVFormatContext 结构的 priv_data 字段关联 AVIContext 或 TCPContext 或 UDPContext 等等具体的文件格式。AVInputFormat 和具体的音视频编码算法格式由 AVFormatContext 结构的 streams 字段关联媒体格式,streams 相当于 Demuxer 的 output pin,解复用模块分离音视频裸数据通过 streams 传递给下级音视频解码器。
  3. 视频频解码模块(Decoder)的作用就是解码数据包,并且把同步时钟信息传递下去。
  4. 色彩空间转换模块(Color Space Converter)颜色空间转换过滤器的作用是把视频解码器解码出来的数据转换成当前显示系统支持的颜色格式
  5. 音视频渲染模块(Render)的作用就是在适当的时间渲染相应的媒体,对视频媒体就是直接显示图像,对音频就是播放声音

跨平台实现

在播放器得5个模块中文件读取模块(Source)、解复用模块(Demuxer)和色彩空间转换模块(Color Space Converter)这三个模块都可以用 ffmpeg 的框架进行实现,而f fmpeg 本身就是跨平台的。因此,实现跨平台的播放器的就需要抽象一层平台无关的音视频解码、渲染接口。Android、iOS、Window 等平台只需要实现各自平台的渲染、硬件解码(如果支持的话)就可以构建一个标准的基于 ffmpeg 的播放器了。

下图是基于ffplay的基本播放流程图:

图中红色部分是需要抽象的接口的,结构如下:

其中 FF_Pipenode.run_sync 视频解码线程,默认有 libavcodec 的软解码实现,其他平台可以增加自己的硬解码实现。SDL_VideoOut 为视频渲染抽象层,这里 overlay 可以是 Android的 NativeWindow,或者是 OpenGL 的 Texture。SDL_AudioOut 是音频播放抽象层,可以直接操作声卡驱动,SDL2.0 里就支持 ALSA、OSS 接口,当然也可以用 Android、iOS SDK 中的音频 API 实现。

这里顺便提下,随着 Android、iOS 平台的普及,ffmpeg 版本的也逐步支持了 Android、iOS 的硬件解码器,如f fmpeg 在很早之前就支持了 libstagefright,最新的 ffmpeg2.8 也已经支持了 iOS 的硬件解码库 VideoToolBox。从下面重点介绍下视频硬解码以及音视频渲染模块在移动平台上的实现。

Android

1.硬解码模块:

Android 的硬解码模块目前有 2 种实现方案:

libstagefright_h264:

libstagefright 是 Android2.3 之后版本的多媒体库,ffmpeg 早在 0.9 版本时就已经将libstagefright_h264 收录到自己的解码库中了,从 libstagefright.cpp 包括的头文件路径来看,是基于 Android2.3 版本的源码。因此编译 libstagefright 需要 Android2.3 的相关源码以及动态链接库。

ffmpeg 中的 libstagefright 目前只实现了 h264 格式的解码,由于 Android 机型、版本的碎片化相当严重,这种基于某个 Android 版本编译出来的 libstagefright 也存在很严重的兼容性问题,我在 Android4.4 的机型上就遇到无法解码的问题。

MediaCodec:

MediaCodec 是 Google 在 Android4.1(API16)以后新提供的硬件编解码 API,其工作原理如图所示:

以解码为例,先从 Codec 获取 inputBuffer,将待解码数据填充到 inputbuffer,再将 inputbuffer 交给Codec,接下来就可以从 Codec 的 outputBuffer 中拿到新鲜出炉的图像和声音信息了。下面的这段实例代码也许更能说明问题:

MediaCodec codec = MediaCodec.createByCodecName(name);
 codec.configure(format, …);
 MediaFormat outputFormat = codec.getOutputFormat(); // option B
 codec.start();
 for (;;) {
   int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
   if (inputBufferId >= 0) {
     ByteBuffer inputBuffer = codec.getInputBuffer(…);
     // fill inputBuffer with valid data
     …
     codec.queueInputBuffer(inputBufferId, …);
   }
   int outputBufferId = codec.dequeueOutputBuffer(…);
   if (outputBufferId >= 0) {
     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
     // bufferFormat is identical to outputFormat
     // outputBuffer is ready to be processed or rendered.
     …
     codec.releaseOutputBuffer(outputBufferId, …);
   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
     // Subsequent data will conform to new format.
     // Can ignore if using getOutputFormat(outputBufferId)
     outputFormat = codec.getOutputFormat(); // option B
   }
 }
 codec.stop();
 codec.release();

令人沮丧的是,MediaCodec 只提供了 java 层的 API,而我们的播放器是基于 ffplay 架构的,核心的解码模块是不可能移到 java 层的。既然我们移不上去,就只能把 MediaCodec 拉到 Native 层了,通过 (*JNIEnv)->CallxxxMethod 的方式将 MediaCodec 相关的 API 在 Native 层做了一套接口。嗯,现在我们可以来实现视频的硬件解码了:

queue_picture 的实现如下图所示:

2.视频渲染模块:

在渲染之前,我们必须先指定一个渲染的画布,在android上这个画布可以是ImageView,SurfaceView,TextureView或者是GLSurfaceView。

关于在Native层渲染图片的方法,我曾看过一篇文章,文中介绍了四种渲染方法:

  • Java Surface JNI
  • OpenGL ES 2 Texture
  • NDK ANativeWindow API
  • Private C++ API

如果是用 ffmpeg 的 libavcodec 进行软解码,那么使用 NDK ANativeWindow API 将是最高效简单的方案,主要实现代码:

ANativeWindow* window = ANativeWindow_fromSurface(env, javaSurface);

ANativeWindow_Buffer buffer;
if (ANativeWindow_lock(window, &buffer, NULL) == 0) {
  memcpy(buffer.bits, pixels,  w * h * 2);
  ANativeWindow_unlockAndPost(window);
}

ANativeWindow_release(window);

示例代码中的 javaSurface 来自 java 层的 SurfaceHolder,pixels 指向 RGB 图像数据。

如果是使用了 MediaCodec 进行解码,时时彩源码 php【大神源码论坛】dsluntan.com  【布丁源码论坛】budingbbs.com 企娥3393756370 那么视频渲染将变得异常简单,只需在 MediaCodec 配置时(MediaCodec.configure)指定图像渲染的 Surface,然后再解码完每一帧图像的时候调用 releaseOutputBuffer (index, true),MediaCodec 内部就会将图像渲染到指定的 Surface 上。

3.音频播放模块

Android 支持 2 套音频接口,分别是 AudioTrack 和 OpenSL ES,这里以 AudioTrack 为例介绍下音频的部分流程:

由于 AudioTrack 只有 java 层的 API,我们也得像 MediaCodec 一样在 Native 层重做一套 AudioTrack 的接口。

这里解码和播放是 2 个独立的线程,audioCallback 负责从 Audio Frame queue 中获取解码后的音频数据,如果解码后的音频采样率不是 AudioTrack 所支持的,就需要用 libswresample 进行重采样。

iOS

1. 硬解码模块

从 iOS8 开始,开放了硬解码和硬编码 API,就是名为 VideoToolbox.framework 的 API,支持 h264 的硬件编解码,不过需要 iOS 8 及以上的版本才能使用。这套硬解码 API 是几个纯 C 函数,在任何 OC 或者 C++ 代码里都可以使用。首先要把 VideoToolbox.framework 添加到工程里,并且包含以下头文件。

#include

解码主要需要以下四个函数:

  • VTDecompositionSessionCreate 创建解码session
  • VTDecompressionSessionDecodeFrame 解码一个frame
  • VTDecompressionOutputCallback 解码完一个frame后的回调
  • VTDecompressionSessionInvalidate 销毁解码session

解码流程如图所示:

2. 视频渲染模块

视频的渲染采用 OpenGL ES2 纹理贴图的形式。

3. 音频播放模块

采用 iOS 的 AudioToolbox.frameworks 进行播放。数据流程和 Android 平台是相同,不同的是,Android 平台把 PCM 数据喂给 AudioTrack,iOS 上把 PCM 数据喂给 AudioQueue。

总结

其实 ffpmeg 自带的播放器实例 ffplay 就是一个跨平台的播放器,得益于其依赖的多媒体库 SDL 实现了多平台的音视频渲染。但是 SDL 库过于庞大,并不适合整体移植到移动端。本文介绍的跨平台实现方案也是借鉴了 SDL2.0 的内部实现,只是重新设计了渲染接口。

原文地址:https://www.cnblogs.com/xasdasf/p/9334986.html

时间: 2024-11-05 21:39:12

基于 ffmpeg时时彩源码 php 的跨平台播放器实现的相关文章

【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)

作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csdn.net/shulianghan VLC 二次开发 视频教程 : http://edu.csdn.net/course/detail/355 博客总结 : -- 本博客目的 : 让 Android 开发者通过看本博客能够掌握独立移植 VLC Media Player 核心框架到自己的 app 中,

基于ffmpeg和libvlc的视频剪辑、播放器

以前研究的时候,写过一个简单的基于VLC的视频播放器.后来因为各种项目,有时为了方便测试,等各种原因,陆续加了一些功能,现在集成了视频播放.视频加减速.视频剪切,视频合并(增加中)等功能在一起.有时候看点网上下载的视频,可以一边看,一边能处理视频前后的广告,感觉也还可以用,就想把它开源出去,一方面希望有需要的朋友可以参考.借鉴,另一方面也希望可以促进它进一步的丰富功能,最终能实现一款简单又够用的视频剪辑软件. 程序框架 先上一张程序截图 基本上讲,它的播放功能是基于VLC,剪辑功能是基于FFmp

ffmpeg/ffplay源码剖析笔记<转>

转载:http://www.cnblogs.com/azraelly/ http://www.cnblogs.com/azraelly/archive/2013/01/18/2865858.html 内容摘自<ffmpeg/ffplay源码剖析> 1.播放器一般原理 可以直观的看到播放这个媒体文件的基本模块(filter),七个模块按广度顺序:读文件模块(source filter),解复用模块(Demux filter),视/音频解码模块(Decode filter),颜色空间转换模块(Co

基于 ffmpeg 的跨平台播放器实现

https://www.qcloud.com/community/article/309889001486708756 背景: 随着游戏娱乐等直播业务的增长,在移动端观看直播的需求也日益迫切.但是移动端原生的播放器对各种直播流的支持却不是很好.Android 原生的 MediaPlayer 不支持 flv.hls 直播流,iOS 只支持标准的 HLS 流.本文介绍一种基于 ffplay 框架下的跨平台播放器的实现,且兼顾硬解码的实现. 播放器原理: 直观的讲,我们播放一个媒体文件一般需要5个基本

基于FFMPEG的跨平台播放器实现

一.背景介绍 FFmpeg是一款超级强大的开源多媒体编解码框架,提供了录制.转换以及流化音视频的完整解决方案,包含了libavcodec.libavformat等多个多媒体库.FFmpeg是基于linux平台下开发的,同样可以运行于android(其实也是linux,你懂得!).windows.Mac等平台. FFmpeg有多重要?列举一下我们常用的多媒体处理软件:暴风影音.QQ影音.KMP(这个牛掰啊).格式工厂……都使用了FFmpeg,可是他们都被FFmpeg刻上了耻辱柱:理由是把开源的东西

WmS详解(二)之如何理解Window和窗口的关系?基于Android7.0源码

上篇博客(WmS详解(一)之token到底是什么?基于Android7.0源码)中我们简要介绍了token的作用,这里涉及到的概念非常多,其中出现频率最高的要数Window和窗口这一对搭档了,那么我们今天就来看看到底我们该如何理解Android系统中的Window和窗口. 窗口这个概念,从不同的角度来看它的含义不一样,如果我们从WmS(WindowManagerService)的角度来看窗口,那么这个窗口并不是一个Window类,而是一个View.用户发来的消息被WmS接收之后并不能直接发给各个

亿发游时时彩-源码开发API

1)  函数指针的初始化. 函数如下: 1 int CompareString(const string& str1, const string& str2)2 {3     return str1.compare(str2); 4 } 函数的初始化有两种方式: 第一种,也是最普遍的方式: 1 int (*CompareFunction)(const string&, const string&) = CompareString; 第二种,是使用typedef定义函数类型,

最简单的基于FFMPEG的转码程序

本文介绍一个简单的基于FFmpeg的转码器.转码器在视音频编解码处理的程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码.一个视频播放器,一般只包含解码功能:一个视频编码工具,一般只包含编码功能:而一个视频转码器,则需要先对视频进行解码,然后再对视频进行编码,因而相当于解码器和编码器的结合.下图例举了一个视频的转码流程.输入视频的封装格式是FLV,视频编码标准是H.264,音频编码标准是AAC:输出视频的封装格式是AVI,视频编码标准是MPEG2,音频编码标准是MP3.从流程中可以看出

银航时时彩-天恒PHP版本-时时彩源码程序完整下载

源码介绍 源码名称:    英利银航国际娱乐时时彩源码天恒PHP版本 源码类型:天恒PHP源码 源码架设环境:win2003或win2008等可操作系统,具体环境安装请根据我们独家录制的时时彩架设教程进行安装. 源码截图 源码积分很低相当于免费下载,不提供任何售后服务请自行研究,别联系我. 源码下载:http://www.yxkfw.com/thread-412-1-1.html