ffmpeg 是一个强大的开源库,当下火热的直播也用了 ffmpeg ,我们熟悉的很多播放器比如某豆,某酷在客户端中都能找到 ffmpeg 的身影,它们提供的转码服务比如 mp4 转 rmvb ,其实都是调用 ffmpeg 的 API 实现的。
实验楼介绍的这个项目教程就是教你使用 ffmpeg 来编写一个播放器。
一、项目简介:
该项目学习编译 ffmpeg (它提供了一套丰富的视音频解码库,和方便使用的工具),使用它的库来转换视频文件,并结合 sdl 编写播放器,从中学习到编解码的知识。
二、ffmpeg 简介:
ffmpeg 是一个很好的开源的多媒体库,它包括了编解码,格式转化,复用器,解复用器,数据流处理,过滤和播放大多数多媒体格式,既包括较老的格式也支持很新的格式,它具有高度的可移植性。ffmpeg 可以在各种环境下构建,运行。从 Linux , 到 Mac OS , windows ,Android 都可以适用。
三、效果图:
四、项目涉及知识点:
- ffmpeg 库介绍
- 相关结构介绍
- 动画屏幕捕捉
- 格式转换
- sdl介绍
- 图像格式:yuv ,rgb 介绍
- 播放画面
其中由于项目内容较多,本文主要介绍:ffmpeg 工具和库的介绍、图像格式:yuv ,rgb 介绍这两块内容,关于具体的如何进行动画屏幕捕捉以及格式转换和播放画面,点击【ffmpeg 结合 SDL 编写播放器】即可查看了,有详细的开发文档和步骤,更有在线开发环境可以跟着动手操作。
五、ffmpeg 工具介绍
ffmpeg 命令行工具
ffmpeg 工具是一个高效快速的命令行工具,进行视音频不同格式之间的转换,ffmpeg可以读取任意数量的输入“文件”(可以是常规文件,管道,网络流,抓取设备等)读取,由 -i 选项指定,并写入任意数量的输出“文件” (由纯输出文件名指定,在命令行中发现的不能被解释为选项的任何东西被认为是输出文件名。)
每个输入或输出文件原则上可以包含任意数量的不同类型的流(视频/音频/字幕/附件/数据)。 流的数量或类型可以由容器格式规定。 选择哪些输入并输出到哪个要么自动完成,要么使用-map选项。
将输出文件的视频比特率设置为64 kbit/s
ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi
强制输出文件的帧速率24帧:
ffmpeg -i input.avi -r 24 output.avi
强制输入文件的帧速率(仅对raw格式有效)为1帧和输出文件的帧速率为24帧的:
ffmpeg -r 1 -i input.m2v -r 24 output.avi
ffmpeg 的转码流程可以由下图表示:
( ffmpeg 调用 libavformat 库(包含 demuxers )来读取输入文件,并从中获取包含编码数据的数据包。 当有多个输入文件时,ffmpeg 尝试通过输入流上的时间戳来保持它们的同步。
编码分组后传递到解码器。 解码器可以通过滤波进一步处理的未压缩帧(原始视频/ PCM音频/ ...)。 在过滤之后,帧被传递到编码器,编码它们并输出编码分组。 最后,它们被传递到复用器,复用器将编码的数据包写入输出文件。)
ffserver
ffserver 是用于音频和视频的流服务器。 它支持多种推送方式,从文件流传输或者实时流推送。 如果有足够大的推送存储空间,还可以查找每个实时流的位置。
ffserver 从一些实例接收预录制文件或 FFM 流作为输入,然后通过 RTP / RTSP / HTTP 将其流式传输。
对于每个推送,可以有不同格式的不同输出流,每个格式由配置文件中的 部分指定。
推送发布的网址如:
http://ffserver_ip_address:http_port/feed_name
其中 ffserver_ip_address 是安装 ffserver 的计算机的 IP 地址,http_port 是 HTTP 服务器的端口号(通过 HTTPPort 选项配置),feed_name 是配置文件中定义的相应订阅源的名称。
多个流可以连接到同一个推送上。例如,可以使用以下图形描述的情况:
我们可以使用下面的命令来开启一个简单的范例:
ffserver -f doc/ffserver.conf &ffmpeg -i INPUTFILE http://localhost:8090/feed1.ffm
然后可以在其他的电脑上输入 url 查看:
http://:8090/test.asf
ffplay
ffplay 是一个使用 ffmpeg 库和 sdl 库的非常简单和便携的媒体播放器。 它主要用作各种 ffmpeg api 的测试平台。
每个流使用一些选项,例如比特率或编解码器。 流指定符用于精确地指定选项所属的流。流指定符是一个字符串,通常添加选项名称,并用冒号分隔。 例如。 -codec:a:1 ac3 包含a:1 流标识符,它匹配第二个音频流。 因此,它将为第二个音频流选择 ac3 编解码器。流指定符可以匹配多个流,以便将选项应用于所有流。 例如。 -b:128k 中的流说明符匹配所有音频流。空流说明符匹配所有流。 例如,-codec copy 或 -codec:copy 将复制所有流,而不重新编码。流标识符的可能形式是:
- stream_index : 使用此索引匹配流。 例如。 -threads:1 4 将第二个流的线程计数设置为4。
- stream_type[:stream_index]: stream_type 是以下之一:视频的'v'或'V',音频的'a',字幕的's',数据的'd'和 附件的't'。 'v'匹配所有视频流,'V'仅匹配未附加图片。如果给出 stream_index,则它匹配此类型的流 stream_index。 否则,它匹配此类型的所有流。
- p:program_id[:stream_index]:如果给出 stream_index,则它将流与程序中具有 id program_id 的数字 stream_index 匹配。 否则,它匹配程序中的所有流。
- stream_id or i:stream_id : 通过流 id 匹配流(例如 MPEG-TS 容器中的 PID )。
- m:key[:value] : 匹配具有指定值的元数据标记键的流。 如果未指定值,则将包含给定标记的流与任何值 进行匹配。匹配具有可用配置的流,必须定义编解码器,并且存在诸如视频尺寸或音频采 样率的基本信息。请注意,在ffmpeg中,通过元数据进行的匹配仅适用于输入文件。
ffprobe
ffprobe从多媒体流收集信息,并以人和机器可读的方式打印。
例如,它可以用于检查由多媒体流使用的容器的格式以及包含在其中的每个媒体流的格式和类型。
如果在输入中指定了文件名,ffprobe 将尝试打开并探测文件内容。如果文件无法打开或识别为多媒体文件,则返回正的退出代码。
ffprobe 可以用作独立应用或与文本过滤器组合,其可以执行更复杂的处理,例如,统计处理或绘图。
选项用于列出 ffprobe 支持的某些格式,或用于指定要显示的信息,以及用于设置 ffprobe 将如何显示它。
ffprobe 输出设计为可以通过文本过滤器轻松解析,并且由选定 writer(由 print_format 选项指定)定义的一个或多个部分组成。
存储在容器或流中的元数据标签被识别并打印在相应的 “FORMAT” ,“STREAM” 或 “PROGRAM_STREAM” 部分中。
六、ffmpeg 为开发者准备的库
libavutil
libavutil 库是一个实用程序库,以辅助多媒体编程。 它包含安全可移植字符串函数,随机数生成器,数据结构,附加数学函数,加密和多媒体相关功能。 它不是 libavcodec 和 libavformat 所需的代码的库。
这个库的目标是:
模块化 它应该具有很少的相互依赖性和在 ./configure 期间禁用单个部件的可能性。小 源和对象都应该小。高效 它应该具有低CPU和内存使用。有用 它应该添加人们很需要的功能。
libavcodec
libavcodec 库提供通用编码/解码框架,并包含用于音频,视频和字幕流的多个解码器和编码器,以及多个比特流滤波器。
共享架构提供从比特流 i/o 到 dsp 优化的各种服务,并且使得它适合于实现健壮和快速的编解码器。
libavformat
libavformat 库为音频、视频和字幕流的复用和解复用(多路复用和解复用)提供了一个通用框架。 它包括多媒体容器格式的多个多路复用器和多路分解器。
它还支持几种输入和输出协议来访问媒体资源。
libavdevice
libavdevice 库提供了一个通用框架,用于从许多常见的多媒体输入/输出设备抓取和渲染,并支持多个输入和输出设备,包括 Video4Linux2,VfW,DShow和ALSA。
libavfilter
libavfilter 库提供了一个通用的音频/视频过滤框架,包含几个过滤器,源和接收器模块。
libswscale
libswscale 库执行高度优化的图像缩放和颜色空间和像素格式转换操作。
具体来说,此库执行以下转换:
重新调整:是更改视频大小的过程。 有几个重新调整选项和算法可用。 这通常是有损耗的过程。像素格式转换:是转换图像的图像格式和颜色空间的过程,例如从平面 YUV420P 到 RGB24 转换。 它还可以处理 packed 转换,即从 packed 布局(属于在同一缓冲器中交织的不同平面的所有像素)转换为平面布局(属于存储在专用缓冲器或“平面”中的相同平面的所有样本)的转换。如果源和目标颜色空间不同,这通常是有损过程。
libswresample
libswresample 库执行高度优化的音频重采样,重新矩阵化和样本格式转换操作。
具体来说,此库执行以下转换:
重新采样:是改变音频速率的过程,例如从 44100Hz 的高采样率到 8000Hz 。从高到低采样率的音频转换是有损耗的过程。有几个重采样选项和算法可用。格式转换:是将采样类型(例如从16位有符号采样转换为无符号8位或浮点采样)的过程。当从 packed 布局(所有属于在相同缓冲器中交错的不同通道的样本)到平面布局(属于存储在专用缓冲器或“平面”中的相同通道的所有样本)时,它还处理 packed 转换。重新矩阵化:是改变通道布局的过程,例如从立体声到单声道。当输入通道不能映射到输出流时,该过程是有损的,因为它涉及不同的增益因子和混合。通过专用选项启用各种其他音频转换(例如拉伸和填充)。
七、图像格式介绍
yuv 介绍
YUV,是一种颜色编码方法。
YUV 是编译 true-color 颜色空间(color space)的种类,Y'UV, YUV, YCbCr,YPbPr 等专有名词都可以称为YUV,彼此有重叠。“Y”表示明亮度(Luminance、Luma),“U”和“V”则是色度、浓度(Chrominance、Chroma),Y'UV, YUV, YCbCr, YPbPr 常常有些混用的情况,其中YUV 和 Y'UV 通常用来描述模拟信号,而相反的 YCbCr 与 YPbPr 则是用来描述数位的影像信号,例如在一些压缩格式内 MPEG、JPEG中,但在现今,YUV 通常已经在电脑系统上广泛使用。YUV Formats 分成两个格式:
- 紧缩格式(packed formats):将 Y、U、V 值储存成 Macro Pixels 阵列,和 RGB 的存放方式类似。
- 平面格式(planar formats):将 Y、U、V 的三个分量分别存放在不同的矩阵中。
- 紧缩格式(packed format)中的 YUV 是混合在一起的,对于 YUV4:4:4 格式而言,用紧缩格式很合适的,因此就有了UYVY、YUYV 等。平面格式(planar formats)是指每 Y 分量,U 分量和 V 分量都是以独立的平面组织的,也就是说所有的 U 分量必须在 Y 分量后面,而 V 分量在所有的 U 分量后面,此一格式适用于采样(subsample)。平面格式(planar format)有 I420(4:2:0)、YV12、IYUV 等。
常用的YUV格式:
为节省带宽起见,大多数 YUV 格式平均使用的每像素位数都少于24位元。主要的抽样(subsample)格式有 YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。YUV 的表示法称为 A:B:C 表示法:
- 4:4:4表示完全取样。
- 4:2:2表示2:1的水平取样,垂直完全采样。
- 4:2:0表示2:1的水平取样,垂直2:1采样。
- 4:1:1表示4:1的水平取样,垂直完全采样。
rgb 介绍
光的三原色是红色、绿色和蓝色,三种光相加会成为白色光。这是由于人类有三种视锥细胞分别对红、绿和蓝光最敏感。 三原色光和绘画中的“三原色”不同。绘画时用三种颜色洋红色、黄色和青色以不同的比例配合,会产生许多种颜色。如果三种色料相加,理论上会成为黑色,但实际上是深灰色,因此需要独立的黑色颜料。三色颜料加上黑色 (K) 便是“ CMYK 色彩空间”。
24比特模式 每像素24位(比特s per pixel,bpp)编码的RGB值:使用三个8位无符号整数(0到255)表示红色、绿色和蓝色的强度。这是当前主流的标准表示方法,用于真彩色和JPEG或者TIFF等图像文件格式里的通用颜色交换。它可以产生一千六百万种颜色组合,对人类的眼睛来说,其中有许多颜色已经是无法确切的分辨。
16比特模式 16比特模式分配给每种原色各为5比特,其中绿色为6比特,因为人眼对绿色分辨的色调更精确。但某些情况下每种原色各占5比特,余下的1比特不使用。
32比特模式 实际就是24比特模式,余下的8比特不分配到象素中,这种模式是为了提高数据输送的速度(32比特为一个DWORD,DWORD全称为Double Word,一般而言一个Word为16比特或2个字节,处理器可直接对其运算而不需额外的转换)。同样在一些特殊情况下,如DirectX、OpenGL等环境,余下的8比特用来表示象素的透明度(Alpha)。
最后
以上主要介绍了:ffmpeg 工具和库、图像格式:yuv ,rgb 介绍这两块内容,关于如何进行动画屏幕捕捉以及格式转换和播放画面,点击【ffmpeg 结合 SDL 编写播放器】即可查看了,有详细的开发文档和步骤,更有在线开发环境可以跟着动手操作。