# ffplay_study **Repository Path**: suhuamo/ffplay_study ## Basic Information - **Project Name**: ffplay_study - **Description**: ffplay的学习 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-06 - **Last Updated**: 2026-05-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Based on the code map provided, I have clear information about this project. This is an FFmpeg-based video player study project using SDL for rendering. Let me create a comprehensive README for it. --- # 学习来源 1. ffplay 源码 2. 开源项目:https://github.com/itisyang/playerdemo # FFplay 学习项目 一个基于 FFmpeg 和 SDL2 构建的简单视频播放器,用于学习音视频播放原理。 ## 项目简介 本项目是一个轻量级的视频播放器实现,旨在通过源码学习 FFmpeg 和 SDL2 的基本使用方法。播放器实现了基本的视频播放功能,包括: - 🎬 视频文件解码播放(支持多种格式) - 🖼️ SDL2 窗口渲染与显示 - 🔊 音频解码与播放 - ⏱️ 音视频同步控制 - ⏯️ 播放进度控制(暂停/恢复/逐帧) - ⏩ 快进快退功能 - 🔉 音量调节(基于分贝的对数刻度) - 🔄 多音轨/多视频流切换 - 📺 全屏/窗口模式切换 - ⚡ 变速播放(0.25x ~ 3.0x,使用 Sonic 库实现音频变速) ## 技术栈 ### 核心库 - **FFmpeg 4.2.1**: 多媒体编解码库 - `libavformat`: 封装格式处理、解复用 - `libavcodec`: 音视频编解码 - `libavutil`: 工具函数(时间戳、数学运算等) - `libswscale`: 图像缩放与格式转换 - `libswresample`: 音频重采样 - **SDL2 2.0+**: Simple DirectMedia Layer - 视频渲染与纹理管理 - 音频设备输出 - 事件处理(键盘、窗口) - 线程同步(互斥锁、条件变量) - **C++11**: 项目开发语言,使用 std::thread 进行多线程管理 ### 核心技术特性 - **多线程架构**: 读取线程、解码线程、刷新线程分离 - **队列管理**: 数据包队列、帧队列的环形缓冲设计 - **时钟同步**: 基于音频主时钟的音视频同步策略 - **丢帧机制**: 自动检测并丢弃延迟帧以保持同步 - **分贝音量控制**: 基于对数刻度的音量调节,符合人耳感知 - **变速播放**: 支持 0.25x ~ 3.0x 倍速播放,通过 Sonic 库实现音频变速,同时保持音视频同步 ## 构建要求 - CMake 3.15+ - FFmpeg 4.0+ (libavformat, libavcodec, libavutil, libswscale, libswresample) - SDL2 2.0+ - C++11 兼容的编译器 ## 构建步骤 ```bash # 1. 进入项目目录 cd ffplay_study # 2. 创建构建目录 mkdir build && cd build # 3. 配置项目 cmake .. # 4. 编译 make ``` ## 使用方法 ### 基本运行 ```bash ./ffplay_study ``` 程序默认播放配置的视频文件(在 main.cpp 中设置)。 ### 键盘快捷键 | 按键 | 功能 | 说明 | |-----------|------|------| | **空格键** | 暂停/恢复 | 切换播放和暂停状态 | | **S 键** | 逐帧播放 | 每次按下播放一帧,适合细节查看 | | **← 左箭头** | 快退 5 秒 | 向后跳转 SEEK_INCR 秒(默认 5s) | | **→ 右箭头** | 快进 5 秒 | 向前跳转 SEEK_INCR 秒(默认 5s) | | **↑ 上箭头** | 音量增加 | 按 0.75 dB 步长增加音量 | | **↓ 下箭头** | 音量减少 | 按 0.75 dB 步长降低音量 | | **A 键** | 切换音频流 | 在多音轨视频中循环切换(如国语/粤语/英语) | | **V 键** | 切换视频流 | 在多视频流视频中循环切换 | | **C 键** | 同步切换音视频流 | 同时切换视频流和音频流,保持音画同步 | | **F 键** | 全屏切换 | 在窗口模式和全屏模式间切换 | | **] 键** | 加速播放 | 按 0.25x 步长增加播放速度(最大 3.0x) | | **[ 键** | 减速播放 | 按 0.25x 步长降低播放速度(最小 0.25x) | | **R 键** | 重置速度 | 恢复到正常播放速度(1.0x) | ### 变速播放说明 播放器支持 **0.25x ~ 3.0x** 的变速播放功能: #### 技术实现 - **音频变速**: 使用 [Sonic 库](https://github.com/waywardgeek/sonic) 实现音频时间伸缩算法 - `sonicSetSpeed()`: 设置播放速度 - `sonicSetPitch()`: 保持音调不变(设为 1.0) - `sonicSetRate()`: 保持采样率不变(设为 1.0) - **视频变速**: 通过调整帧显示时长实现 - 帧显示时长 = 原始时长 / 播放速度 - 例如:正常 40ms 的帧,2倍速时变为 20ms - **时钟同步**: 音视频时钟均除以播放速度,确保同步 - 视频时钟: `pts / playback_rate` - 音频时钟: `audio_clock / playback_rate` #### 变速原理 - **2倍速播放**: 原本 1 秒的媒体内容在 0.5 秒内播放完成 - **0.5倍速播放**: 原本 1 秒的媒体内容在 2 秒内播放完成 - **时钟计算**: PTS(呈现时间戳)需要除以播放速度,使时钟按照变速后的节奏走 #### 注意事项 - 变速时会自动重建 Sonic 音频流对象以应用新配置 - 音频数据经过 Sonic 处理后,样本数量会相应变化 - 音视频同步机制会根据变速后的时钟自动调整 ### 音量调节说明 音量控制采用**分贝(dB)刻度**而非线性刻度: - **优势**: 人耳对声音的感知是对数关系,分贝调节让每次增减的听觉感受一致 - **步长**: 默认 0.75 dB(定义在 `datactl.h` 中的 `SDL_VOLUME_STEP`) - **范围**: 0(静音)~ SDL_MIX_MAXVOLUME(最大音量) - **计算**: 使用公式 `dB = 20 × log₁₀(当前音量/最大音量)` 进行转换 ### 快进快退说明 - **步进值**: 默认 5 秒(定义在 `videoctl.cpp` 中的 `SEEK_INCR`) - **实现**: 通过 `stream_seek_incr()` 函数实现精确跳转 - **同步**: 跳转后会自动重新同步音视频时钟