返回文章归档

cpp音视频开发

本页目录4 个章节

想找的工作方向

主要的方向是希望找cpp这一块的开发,因为比较喜欢c家族的代码风格吧。本科阶段写了挺多的javaweb项目,虽然没到达什么很深的阶段,但是还是觉得不是很喜欢这一块的开发。

调查了一下cpp的工作方向主要有嵌入式,云原生,游戏开发,qt桌面客户端,数据库存储,linux服务器方向。

我对linux的只是,简单的使用都是比较熟悉的,但是对更底层的接口就没怎么接触过。

虽然比较喜欢玩游戏,但是感觉游戏开发这个工作还是比较难找。

对于云原生,大数据存储了解的就更少了。

而音视频在现实生活中接触的比较多吧,而且感觉未来使用的场景也会随着传播媒介、应用场景的变化应该也不太会死掉。比较人的感官嗅觉和触觉还是比较难实现数字化的,视觉和听觉我觉得还是会一直用到。(赛博飞升,人脑接口,这大概也是离不开音视频数据传输的吧

计划一下

打算是做一个比较综合一点的项目,音视频+linux后台(操作系统中的只是)+qt前端,即使没找到音视频的工作也能有个qt相关的保底项目吧。

按照gpt老师的建议,要是分成几个学习阶段,同时也不能落下每天的算法代码部分。

阶段主要任务输出成果
第一阶段音视频基础知识 + FFmpeg 命令行操作写笔记 + 用命令完成转码、截图、裁剪等任务
第二阶段FFmpeg 解码流程 + 播放器框架入门实现 YUV 视频文件播放
第三阶段音视频同步 + SDL 渲染音视频同步播放 demo
第四阶段实现推流功能(摄像头 / 桌面)RTMP 推流 demo(配合 OBS / NGINX 测试)
第五阶段Qt + FFmpeg 简易播放器界面Qt 播放器 GUI 初版

ffmpeg

stage 1

音视频基础知识

帧通常指没有压缩后的数据,包是压缩后的 常见封装格式对比

封装格式全称/别名主要用途支持音视频轨典型特点应用场景
MP4MPEG-4 Part 14通用型播放与存储✅结构复杂,索引强,兼容好本地播放、在线视频、存储
FLVFlash Video网络流媒体传输✅封装简单、延迟低,适合直播Flash 播放器、RTMP 直播
MKVMatroska高质量/多轨封装✅可封多轨字幕、音频,灵活开放本地高清视频、多音轨资源
TSTransport Stream广播/传输流媒体传输✅片段化强,适合流媒体逐段播放直播、HLS(.m3u8 + .ts)

音视频网络协议封装格式对比表

协议封装格式传输方式延迟支持双向?典型用途特点总结
RTMPFLV基于 TCP低否直播推流(如 OBS)实时性强、部署简单、兼容广
RTSPRTPTCP / UDP低是摄像头、监控系统支持控制命令(PAUSE/PLAY),低延迟
HLSTS基于 HTTP高否网页直播 / 点播分片传输、兼容性强、CDN 支持好
MMSASFTCP / UDP中否Windows Media 流媒体已过时,被 RTSP 和 HLS 取代
WebRTCSRTPUDP + ICE/STUN/DTLS极低是实时音视频通信、连麦互动原生双向通信、极低延迟、浏览器支持、实现复杂
概念定义
编码把原始音视频数据(如 YUV、PCM)压缩成可传输的格式(如 H.264、AAC)
解码把压缩数据(如 H.264、AAC)还原成原始数据,供播放或编辑使用

YUV 是一种广泛使用的颜色编码格式,主要用于视频处理和压缩领域,用来表示图像的颜色信息。

视频编码格式大全

格式名全称 / 简称压缩效率延迟应用场景特点说明
H.264AVC高中视频播放、录制、直播主流格式,兼容性好,支持 B 帧
H.265HEVC更高中4K/8K 视频、高清视频传输压缩率比 H.264 高约 30%,需更强硬件解码
AV1AOMedia Video 1极高高未来网页视频、开源播放器开源免费,压缩率比 H.265 更高,但编码速度慢
VP8Google VP8中等低WebRTC、YouTube开源、适合实时,替代 H.264
VP9Google VP9高中YouTube、网页高清视频支持 4K,开源,压缩比优于 H.264
MPEG-2—低低DVD、广播电视老旧格式,兼容性强但压缩率低
MJPEGMotion JPEG低低摄像头、老式录像设备每帧为一张 JPEG,简单快速,但体积大
ProResApple ProRes无损/轻压缩高后期剪辑、专业摄像高质量中间格式,不适合播放或传输

压缩效率指的是在相同画质下,所需的数据量(码率)有多小。 延迟是指从采集或读取一帧数据,到它被成功编码传输并最终播放出来之间的时间间隔。

概念表示的意义越高表示…
压缩效率同样画质下文件有多小✅ 更节省体积和带宽
延迟从编码到播放的等待时间❌ 越高越不适合实时传输

音频编码格式大全

格式名全称压缩方式延迟应用场景特点说明
AACAdvanced Audio Coding有损低主流播放器、视频音轨比 MP3 更高效,H.264 搭配常用
MP3MPEG Layer 3有损中音乐播放、老设备历史最广泛格式,兼容强
Opus—有损极低WebRTC、语音通话支持宽频/语音切换,低延迟,实时性强
PCMPulse Code Modulation无压缩低音频处理、硬件采集原始格式,体积大但保真
FLACFree Lossless Audio Codec无损压缩中音乐收藏、高清音频保留完整音质,压缩率较高
ALACApple Lossless无损压缩中Apple 设备高质量音频与 FLAC 类似,但用于苹果生态
AMR-NB/WBAdaptive Multi-Rate有损极低手机语音通信GSM/VoLTE 通信编码标准

常见的容器格式

容器格式可封装的视频编码可封装的音频编码
MP4H.264, H.265, AV1AAC, MP3, Opus
MKVH.264, VP9, AV1, MPEG-2AAC, MP3, Vorbis, FLAC
AVIMPEG-4, H.264MP3, PCM
FLVH.263, H.264MP3, AAC
TSH.264, H.265AAC, AC3
MOVH.264, ProResAAC, PCM, ALAC

编码压缩数据以便传输或保存,解码还原数据以便播放或处理。没有编码,视频文件无法高效传播;没有解码,就无法播放它。

SDL 是一个 C 语言编写的跨平台开发库,常用于音视频播放、图形渲染和事件处理。

功能说明
视频显示用于渲染 YUV 视频帧(例如 FFmpeg 解码后)
音频播放播放解码后的 PCM 音频数据
窗口管理创建图形窗口,控制分辨率、刷新等
事件处理支持键盘、鼠标、窗口关闭等用户交互
跨平台支持一次编写,运行在 Windows、Linux、macOS、Android

采样

采样是将连续的模拟音频信号(analog),以固定时间间隔测量并记录成**数字信号(digital)**的过程。

参数说明
采样率每秒采样次数,单位为 Hz(赫兹)
位深每个采样点的精度,单位为 bit(如 16bit)

重采样

重采样是将已有的数字音频从一个采样率或通道格式转换为另一种采样率或格式的过程。

  • 把 48000 Hz 转换为 44100 Hz(向下重采样)
  • 把单声道变为双声道(通道重采样)
  • 把 float32 格式变为 int16(格式重采样)

ffmpeg 命令行操作

linux 安装

sudo apt update
sudo apt install -y \
  ffmpeg \
  libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev \
  libsdl2-dev \
  libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libmp3lame-dev libopus-dev \
  libass-dev libfreetype6-dev libvorbis-dev \
  pkg-config build-essential cmake git
库名用途说明
ffmpeg命令行工具,包含 ffprobe、ffplay
libavcodec-dev编解码库(视频/音频解码器)
libavformat-dev封装/解封装库(MP4、FLV、MKV 等)
libavutil-dev工具函数库(时间戳、颜色转换)
libswscale-dev视频缩放、像素格式转换
libswresample-dev音频重采样
libsdl2-dev视频渲染/音频播放(配合 FFmpeg 播放器)
libx264-devH.264 编码器
libx265-devH.265 编码器
libvpx-devVP8/VP9 编码器
libfdk-aac-dev高质量 AAC 编码器(需 --enable-nonfree)
libmp3lame-devMP3 编码器
libopus-devWebRTC 用音频编码器
libass-devASS 字幕渲染
libfreetype6-dev字体渲染(用于水印/字幕)
libvorbis-devOGG/Vorbis 音频编码器
pkg-config自动查找编译依赖
build-essentialGCC、g++ 等基础开发工具链
cmake, git编译构建与源码管理工具
ffmpeg [global_options] -i [input_file] [input_options] [processing_options] [output_options] [output_file]

常用命令

操作类别命令示例说明
查看信息ffprobe input.mp4显示媒体详细信息
转码为 MP4ffmpeg -i input.avi output.mp4转码为 H.264/AAC 编码的 MP4
指定编码器转码ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4手动设置视频/音频编码器
调整码率ffmpeg -i input.mp4 -b:v 1000k -b:a 128k output.mp4设置视频/音频目标码率
调整帧率ffmpeg -i input.mp4 -r 30 output.mp4设置输出帧率为 30 fps
调整分辨率ffmpeg -i input.mp4 -s 1280x720 output.mp4缩放为 720p
提取音频ffmpeg -i input.mp4 -vn -c:a copy output.aac仅保留音频轨 -vn(video none)
提取视频ffmpeg -i input.mp4 -an -c:v copy output.h264仅保留视频轨 -av(audio none)
音频转 WAVffmpeg -i input.aac output.wav转为未压缩音频
静音处理ffmpeg -i input.mp4 -an output.mp4移除音频轨
添加静音音轨ffmpeg -f lavfi -i anullsrc -i input.mp4 -shortest -c:v copy -c:a aac output.mp4为无声视频添加静音 -f lavfi 使用 libavfilter 作为输入 -i anullsrc 虚拟输入
截取片段ffmpeg -ss 00:01:00 -i input.mp4 -t 10 -c copy clip.mp4从 1 分钟处截取 10 秒
视频截图ffmpeg -ss 00:00:01 -i input.mp4 -frames:v 1 shot.png截取指定时间帧
视频转图片序列ffmpeg -i input.mp4 img_%04d.jpg每帧输出为图片 %04d
图片序列转视频ffmpeg -framerate 25 -i img_%04d.jpg -c:v libx264 output.mp425fps 合成视频
裁剪视频区域ffmpeg -i input.mp4 -filter:v "crop=640:360:0:0" output.mp4裁剪左上角 640×360 区域
合并音视频ffmpeg -i video.mp4 -i audio.aac -c:v copy -c:a copy output.mp4封装合并
拼接视频(同编码)ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4快速拼接
推流 RTMPffmpeg -re -i input.mp4 -c:v libx264 -f flv rtmp://...本地文件推送到 RTMP 流媒体服务器
添加字幕ffmpeg -i input.mp4 -vf subtitles=sub.srt output.mp4内嵌软字幕
变速播放ffmpeg -i input.mp4 -vf "setpts=0.5*PTS" output.mp4快放(2 倍速)
视频加水印ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4左上角加水印
转为 HLSffmpeg -i input.mp4 -f hls -hls_time 10 -hls_list_size 0 -hls_segment_filename seg_%03d.ts out.m3u8生成分片和索引用于直播

参数

参数说明默认值(如未指定)
-i指定输入文件(input)必填,无默认值
-ss指定起始时间(用于截取/跳转)seek start0(从开头开始)
-t指定持续时间(配合 -ss 截取片段)到文件末尾
-to指定结束时间(-ss 到 -to)到文件末尾
-c同时设置音频和视频的编码器(codec)自动选择(mp4 → libx264 + aac)
-c:v指定视频编码器,如 libx264依容器类型自动选择(如 libx264)
-c:a指定音频编码器,如 aac依容器类型自动选择(如 aac)
-vn不处理视频(video none)默认处理视频
-an不处理音频(audio none)默认处理音频
-sn不处理字幕(subtitle none)默认处理字幕
-r设置帧率(frame rate)跟随输入帧率
-s设置分辨率,如 1280x720跟随输入尺寸
-b:v设置视频码率(bitrate)自动估算(CRF 编码时不需设定)
-b:a设置音频码率自动估算(通常如 128k、192k)
-f指定格式(format),如 mp4、flv自动识别(根据输入/输出文件扩展名) 强制指定输入或输出的封装格式(format)常用于输入为虚拟格式(如 lavfi, concat),输出不带扩展名或需手动设定格式(如 flv, hls, mp4)
-filter:v设置视频滤镜(如 crop、scale)无过滤器(原始传递)
-filter:a设置音频滤镜(如 volume)无过滤器
-map精确指定输入的哪些流要输出自动选择主流(如第一个音视频)
-threads设置使用线程数量自动检测 CPU 线程
-y自动覆盖已有文件(不提示)默认 false(需确认)
-n若输出文件已存在则不执行(no overwrite)默认 false(允许覆盖)
-hide_banner隐藏启动时版权和配置信息默认显示
-loglevel设置日志级别,如 quiet、info、errorinfo
-re以实际速度读取输入(用于推流)默认关闭
-vf视频滤镜(video filter)的快捷写法(同 -filter:v)同 -filter:v
-af音频滤镜(audio filter)的快捷写法(同 -filter:a)同 -filter:a
-movflags设置 MP4 特性,如 faststart 优化网页加载默认不设置(需显式添加)
-preset编码速度设置(ultrafast → veryslow)medium(x264/x265 默认)
-crf设置恒定质量值(常用于 x264 编码,范围 0–51)23(推荐范围 18–28)
-profile:v设置视频编码的 profile(如 main、high)由编码器自动选择
-level设置编码等级(如 4.0、5.1)由编码器自动选择

ffmpeg 源码

stage1 主控流程
main()
├── init_dynload()
├── av_log_set_flags()
├── parse_loglevel()
├── avdevice_register_all()
├── avformat_network_init()
├── show_banner()
├── sch = sch_alloc()
├── ffmpeg_parse_options()      ← 参数解析 & 打开输入输出
├── 检查输入输出是否为空
├── get_benchmark_time_stamps()
├── transcode()                 ← 关键转换流程
├── get_benchmark_time_stamps()
├── ffmpeg_cleanup()
└── sch_free()

ffmpeg_parse_options() 这个部分会解析命令行的参数,打开输入输出文件,根据参数配置demux,mux,decode,encode,filter等任务,这里就会调用到相关的代码的入口(ifile_open,of_open,dec_create,fg_create),其中encode和mux都在of_open调用,enc是在of_open的create_stream调用ost_add

*transcode()*个部分会启动并且执行任务

阶段执行线程操作内容(操作码)代表函数/结构典型命令示例
DemuxDemux 线程拆包(读取媒体文件或流)avformat_read_frameffmpeg -i input.mp4
DecodeDecoder 线程解码(压缩数据 → 原始帧)avcodec_send_packet, avcodec_receive_frameffmpeg -i input.mp4 -c:v rawvideo -f null -
FilterFilter 线程滤镜处理(剪辑、缩放、裁剪等)av_buffersrc_add_frame, avfilter_graph, av_buffersink_get_frameffmpeg -i input.mp4 -vf "trim=start=10:end=20,scale=640:360"
EncodeEncoder 线程编码(原始帧 → 压缩包)avcodec_send_frame, avcodec_receive_packetffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
MuxMuxer 线程封装为输出文件或推流avformat_write_header, av_write_frame, av_write_trailerffmpeg -i input.mp4 -f flv rtmp://server/live/stream
stage2 封装模块 mux demux
stage3 编码模块 encode decode
stage4 滤镜模块 filter

搜索文章

输入关键词,寻找一段记忆。

Tab 切换结果 · Enter 打开 · Esc 关闭