网站首页 > 编程文章 正文
1. FFmpeg 的介绍
若要讲解音视频的开发,首先不得不提开源框架 FFmpeg。该开源框架为音视频开发者们提供了非常大的帮助,其也是全世界的音视频开发工程师都应该掌握的工具。
FFmpeg 是一套可以用来记录、处理数字音频、视频,并将其转换为流的开源框架,提供了录制、转换以及流化音视频的完整解决方案。
它的可移植性或者说跨平台特性非常强大,可以用在 Linux 服务器、PC (包括 Windows、Mac OS X 等)、移动端设备 (Android、iOS 等移动设备) 等平台。
名称中的 mpeg 来自视频编码标准 MPEG,而前缀 FF 是 Fast Forward 的首字母缩写。本章会从编译开始讲解,然后介绍命令行工具的使用,接着会介绍 FFmpeg 在代码层面提供给开发者的 API,最后会从源码的角度分析一下整个 FFmpeg 框架。
2. FFmpeg Android 编译库
FFmpeg github 上已经有现成编译好的 android 库:https://github.com/xufuji456/FFmpegAndroid,简介如下:
android 端基于 FFmpeg 库的使用,添加编译 ffmpeg、shine、mp3lame、x264 源码的参考脚本,目前音视频相关处理:
音频剪切、拼接
音频混音
音频转码
音视频合成
音频抽取
音频解码播放
音频编码
视频抽取
视频剪切
视频转码
视频截图
视频降噪
视频抽帧
视频转 GIF 动图
视频添加水印
视频画面拼接
视频反序倒播
视频画中画
图片合成视频
视频解码播放
本地直播推流
实时直播推流
音视频解码播放
FFmpeg 的 AVFilter 滤镜
使用 mp3lame 库进行 mp3 转码
视频拖动实时预览
moov 往前移动
ffprobe 检测多媒体格式
IjkPlayer 的 RTSP 超低延时直播
相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】
音视频免费学习地址:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~
3. FFmpeg 的结构
默认的编译会生成 4 个可执行文件和 8 个静态库。可执行文件包括用于转码、推流、Dump 媒体文件的 ffmpeg、用于播放媒体文件的ffplay、用于获取媒体文件信息的 ffprobe,以及作为简单流媒体服务器的 ffserver。8 个静态库其实就是 FFmpeg 的 8 个模块,具体包括如下内容:
AVUtil:核心工具库,该模块是最基础的模块之一,下面的许多其他模块都会依赖该库做一些基本的音视频处理操作。
AVFormat:文件格式和协议库,该模块是最重要的模块之一,封装了 Protocol 层和 Demuxer、Muxer 层,使得协议和格式对于开发者来说是透明的。
AVCodec:编解码库,该模块也是最重要的模块之一,封装了 Codec 层,但是有一些 Codec 是具备自己的 License 的,FFmpeg 是不会默认添加像 libx264、FDK-AAC、lame 等库的,但是 FFmpeg 就像一个平台一样,可以将其他的第三方的 Codec 以插件的方式添加进来,然后为开发者提供统一的接口。
AVFilter:音视频滤镜库,该模块提供了包括音频特效和视频特效的处理,在使用 FFmpeg 的 API 进行编解码的过程中,直接使用该模块为音视频数据做特效处理是非常方便同时也非常高效的一种方式。
AVDevice:输入输出设备库,比如,需要编译出播放声音或者视频的工具 ffplay,就需要确保该模块是打开的,同时也需要 libSDL的预先编译,因为该设备模块播放声音与播放视频使用的都是 libSDL 库。
SwrRessample:该模块可用于音频重采样,可以对数字音频进行声道数、数据格式、采样率等多种基本信息的转换。
SWScale:该模块是将图像进行格式转换的模块,比如,可以将 YUV 的数据转换为 RGB 的数据。
PostProc:该模块可用于进行后期处理,当我们使用 AVFilter 的时候需要打开该模块的开关,因为 Filter中 会使用到该模块的一些基础函数。
如何为 FFmpeg 平台引入第三方编解码库呢?下面就以最常用的 LAME、X264、FDK-AAC 进行举例。前面的章节中已经介绍了这三个库在 Android 和 iOS 平台上的交叉编译,现在就假设已经交叉编译出了 LAME、X264、FDK-AAC 的静态库与头文件,并且在 FFmpeg 的源码目录下建立了 external-libs 目录,还在其中建立了 LAME、X264、FDK-AAC 三个目录,每个目录中的结构都包含了 include 和 lib两个目录,并且将编译出来的头文件和静态库文件分别都放到了这两个目录下面。
现在修改编译脚本如下:
新增 X264 编码器需要新增以下脚本:
--enable-muxer=h264 \
--enable-encoder=libx264 \
--enable-libx264 \
--extra-cflags=”-Iexternal-libs/x264/include” \
--extra-ldflags=”-Lexternal-libs/x264/lib” \
新增 LAME 编码器需要新增以下脚本:
--enable-muxer=mp3 \
--enable-encoder=libmp3lame \
--enable-libmp3lame \
--extra-cflags=”-Iexternal-libs/lame/include” \
--extra-ldflags=”-Lexternal-libs/lame/lib” \
新增FDK-AAC编码器需要新增以下脚本:
--enable-encoder=libfdk_aac \
--enable-libfdk_aac \
--extra-cflags=”-Iexternal-libs/fdk-aac/include” \
--extra-ldflags=”-Lexternal-libs/fdk-aac/lib” \
可以按照自己的应用场景,把需要编译进来的第三方库以修改脚本文件的方式进行编译,然后以命令行模式或者以API调用的方式进行使用。
4. FFmpeg 命令行工具的使用
FFmpeg 中有 ffmpeg、ffprobe、ffplay以及 ffserver 等命令行工具,这边将重点介绍 ffmpeg、ffprobe 与 ffplay 这三个命令行工具,而ffserver 则是作为简单的流媒体服务器存在的,与客户端开发关系不大。
ffmpeg 是进行媒体文件转码的命令行工具;
ffprobe 是用于查看媒体文件头信息的工具;
ffplay 则是用于播放媒体文件的工具。
4.1 ffprobe
先来测试一个音频文件:
ffprobe /Users/kuangzhongwen/Desktop/my\ documents/kuang\ Music/繁星-阿文.mp3
输出:
# 时长 03:51.80,开始播放时间为 0,比特率是 128 kb/s
Duration: 00:03:51.80, start: 0.000000, bitrate: 128 kb/s
# 第一个流是音频流,编码格式是 mp3,采样率为 44100,声道是立体声,采样表示格式是 fltp,路流比特了是 128 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
再来测试一个视频文件:
ffprobe /Users/kuangzhongwen/Desktop/my\ documents/视频/女生节.mpg
输出:
# 时长,开始播放时间,比特率
Duration: 00:04:47.48, start: 0.220000, bitrate: 8381 kb/s
Stream #0:0[0x1bf]: Data: dvd_nav_packet
# stream,视频流,格式为 mpeg2video,每一帧的数据表示为 yuv420P,分辨率为 720x576,fps 为 25
Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
# stream 音频流,格式为 pcm_dvd,采样率为 48000 Hz,2 个声道,音频流比特率为 1536 kb/s
Stream #0:2[0xa0]: Audio: pcm_dvd, 48000 Hz, 2 channels, s16, 1536 kb/s
格式化输出:
ffprobe -show_format /Users/kuangzhongwen/Desktop/my\ documents/视频/女生节.mpg
输出:
[FORMAT]
filename=/Users/kuangzhongwen/Desktop/my documents/视频/女生节.mpg
nb_streams=3
nb_programs=0
format_name=mpeg
format_long_name=MPEG-PS (MPEG-2 Program Stream)
start_time=0.220000
duration=287.480000
size=301199360
bit_rate=8381782
probe_score=26
[/FORMAT]
JSON 格式输出:
ffprobe -print_format json -show_streams /Users/kuangzhongwen/Desktop/my\ documents/视频/女生节.mpg
输出:
{
Input #0, mpeg, from '/Users/kuangzhongwen/Desktop/my documents/视频/女生节.mpg':
Duration: 00:04:47.48, start: 0.220000, bitrate: 8381 kb/s
Stream #0:0[0x1bf]: Data: dvd_nav_packet
Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
Stream #0:2[0xa0]: Audio: pcm_dvd, 48000 Hz, 2 channels, s16, 1536 kb/s
Unsupported codec with id 100357 for input stream 0
"streams": [
{
"index": 0,
"codec_name": "dvd_nav_packet",
"codec_long_name": "DVD Nav packet",
"codec_type": "data",
"codec_tag_string": "[0][0][0][0]",
"codec_tag": "0x0000",
"id": "0x1bf",
"r_frame_rate": "0/0",
"avg_frame_rate": "0/0",
"time_base": "1/90000",
"start_pts": 19800,
"start_time": "0.220000",
"disposition": {
"default": 0,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0
}
},
{
"index": 1,
"codec_name": "mpeg2video",
"codec_long_name": "MPEG-2 video",
"profile": "Main",
"codec_type": "video",
"codec_time_base": "1/25",
"codec_tag_string": "[0][0][0][0]",
"codec_tag": "0x0000",
"width": 720,
"height": 576,
"coded_width": 0,
"coded_height": 0,
"has_b_frames": 1,
"sample_aspect_ratio": "64:45",
"display_aspect_ratio": "16:9",
"pix_fmt": "yuv420p",
"level": 8,
"color_range": "tv",
"chroma_location": "left",
"field_order": "tt",
"refs": 1,
"id": "0x1e0",
"r_frame_rate": "25/1",
"avg_frame_rate": "25/1",
"time_base": "1/90000",
"start_pts": 19800,
"start_time": "0.220000",
"duration_ts": 25873200,
"duration": "287.480000",
"disposition": {
"default": 0,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0
}
},
{
"index": 2,
"codec_name": "pcm_dvd",
"codec_long_name": "PCM signed 20|24-bit big-endian",
"codec_type": "audio",
"codec_time_base": "1/48000",
"codec_tag_string": "[0][0][0][0]",
"codec_tag": "0x0000",
"sample_fmt": "s16",
"sample_rate": "48000",
"channels": 2,
"bits_per_sample": 0,
"id": "0xa0",
"r_frame_rate": "0/0",
"avg_frame_rate": "0/0",
"time_base": "1/90000",
"start_pts": 19800,
"start_time": "0.220000",
"duration_ts": 25873091,
"duration": "287.478789",
"bit_rate": "1536000",
"bits_per_raw_sample": "16",
"disposition": {
"default": 0,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0
}
}
]
}
显示帧信息的命令如下:
ffprobe -show_frames sample.mp4
查看包信息的命令如下:
ffprobe -show_packets sample.mp4
4.2 ffplay
ffplay 是以 FFmpeg 框架为基础,外加渲染音视频的库 libSDL 来构建的媒体文件播放器。它所依赖的 libSDL 是1.2版本的,所以在安装ffplay 之前也要安装对应版本的 libSDL 作为其依赖的组件。之后使用 ffplay 就非常简单了,比如我们要播放一个音频文件。
ffplay /Users/kuangzhongwen/Desktop/my\ documents/kuang\ Music/繁星-阿文.mp3
或者视频文件:
ffplay /Users/kuangzhongwen/Desktop/my\ documents/视频/女生节.mpg
会打开 ffmpeg 自带的播放器播放。
业界内开源的 ijkPlayer 其实就是基于 ffplay 进行改造的播放器,当然其做了硬件解码以及很多兼容性的工作。ijkPlayer 是一款非常优秀的播放器,作为开发者的我们需要很多优秀的开源项目。
4.3 ffmpeg
ffmpeg 其实是这三个命令行工具里最强大的一个工具,如果说 ffprobe 是用于探测媒体文件的格式以及详细信息,ffplay 是一个播放媒体文件的工具,那么 ffmpeg 就是强大的媒体文件转换工具。它可以转换任何格式的媒体文件,并且还可以用自己的 AudioFilter 以及VideoFilter 进行处理和编辑,总之一句话,有了它,进行离线处理视频时可以做任何你想做的事情了。
原文链接:音视频篇 - FFmpeg 的介绍和使用
猜你喜欢
- 2024-09-08 技术分享| 如何使用FFmpeg命令处理音视频
- 2024-09-08 ubuntu ffmpeg开发环境搭建(ffmpeg linux开发)
- 2024-09-08 嘉宾博文:OpenCV如何在区块链操作系统中进行交叉编译
- 2024-09-08 想做人工智能的你,OpenCV安装好了吗?AI大神手把手教会你
- 2024-09-08 Kotlin编写一个AudioMerger 在线音视频解析七
- 2024-09-08 FFmpeg中与视频解码相关知识简介(ffmpeg hevc解码)
- 2024-09-08 ffmpeg教程-手把手教你如何简单快捷处理音视屏
- 2024-09-08 C++与音视频处理: 处理音频和视频数据的编码和解码
- 2024-09-08 ffmpeg安装大放送,包括编译需要的支持库
- 2024-09-08 ffmpeg推流桌面直播(ffmpeg推流rtsp命令)
你 发表评论:
欢迎- 05-09Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 05-09《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- 05-09MapStruct架构设计(mapstruct @mapping)
- 05-09分布式微服务架构组件(分布式微服务架构设计)
- 05-09Java Swing组件下的JButton实例(java swing 组件)
- 05-09java基础都在这了,小主们拿去吧(java基础是指什么)
- 05-09AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 05-09【Spring Boot】WebSocket 的 6 种集成方式
- 最近发表
-
- Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- MapStruct架构设计(mapstruct @mapping)
- 分布式微服务架构组件(分布式微服务架构设计)
- Java Swing组件下的JButton实例(java swing 组件)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 【Spring Boot】WebSocket 的 6 种集成方式
- Java 中五种最常见加密算法:原理、应用与代码实现
- 用注解进行参数校验,spring validation介绍、使用、实现原理分析
- 标签列表
-
- spire.doc (59)
- system.data.oracleclient (61)
- 按键小精灵源码提取 (66)
- pyqt5designer教程 (65)
- 联想刷bios工具 (66)
- c#源码 (64)
- graphics.h头文件 (62)
- mysqldump下载 (66)
- sqljdbc4.jar下载 (56)
- libmp3lame (60)
- maven3.3.9 (63)
- 二调符号库 (57)
- 苹果ios字体下载 (56)
- git.exe下载 (68)
- diskgenius_winpe (72)
- pythoncrc16 (57)
- solidworks宏文件下载 (59)
- qt帮助文档中文版 (73)
- satacontroller (66)
- hgcad (64)
- bootimg.exe (69)
- android-gif-drawable (62)
- axure9元件库免费下载 (57)
- libmysqlclient.so.18 (58)
- springbootdemo (64)
本文暂时没有评论,来添加一个吧(●'◡'●)