## ffmpeg工具手册 // 常见功能应该可以快速链接到底下的详细功能模块 ### 常见功能及简介 #### 视频 [视频输入 - 采集](#video-cap) 视频输入 - 文件: 视频输入 - 流式: 视频处理 - 提取: 视频处理 - 转码: 视频处理 - 拼接: 视频处理 - 截取: 视频处理 - 裁剪: 视频处理 - 融合: 视频处理 - 变速: 视频处理 - 水印: 视频处理 - 抽帧: [视频输出 - 播放](#video-play) 视频输出 - 文件: 视频输出 - 流式: #### 音频 [音频输入 - 采集](#audio-cap) 音频输入 - 文件: 音频输入 - 流式: 音频处理 - 提取: 音频处理 - 转码: 音频处理 - 拼接: 音频处理 - 截取: 音频处理 - 融合: 音频处理 - 变速: [音频输出 - 播放](#audio-play) 音频输出 - 文件: 音频输出 - 流式: ### 功能详细介绍 #### 采集 **mac: avfoundation** ##### 常用参数 1. `-list_devices ` 用于查看设备支持的采集设备列表 > 示例及输出: > `ffmpeg_thin -f avfoundation -list_devices true -i ''` > [AVFoundation indev @ 0x7fe5ae905a80] AVFoundation video devices: > [AVFoundation indev @ 0x7fe5ae905a80] [0] FaceTime高清摄像头(内建) > [AVFoundation indev @ 0x7fe5ae905a80] [1] Capture screen 0 > [AVFoundation indev @ 0x7fe5ae905a80] AVFoundation audio devices: > [AVFoundation indev @ 0x7fe5ae905a80] [0] MacBook Pro麦克风 2. `-capture_raw_data` 是否捕获原始设备数据。默认值为 0 > -c copy 3. `-drop_late_frames` 是否丢弃比期望晚的视频帧,默认值为 true 4. `-capture_cursor` 是否捕获鼠标指针,默认值为 0,即不捕获 5. `-capture_mouse_clicks` 是否捕获屏幕鼠标点击。默认值为 0 #### [视频输入 - 采集](#video-cap-title) ##### 常用参数、参数含义及常用取值 1. `-video_device_index` 指定视频采集设备 2. `-pixel_format` 指定视频采集的像素格式,默认是 yuv420p,如果采集时没有指定,且采集设备不支持默认,会默认选择支持列表的第一条作为默认值 > [avfoundation @ 0x7fe78f204300] Supported pixel formats: > [avfoundation @ 0x7fe78f204300] uyvy422 > [avfoundation @ 0x7fe78f204300] yuyv422 > [avfoundation @ 0x7fe78f204300] nv12 > [avfoundation @ 0x7fe78f204300] 0rgb > [avfoundation @ 0x7fe78f204300] bgr0 3. `-vframes` 视频帧数 4. `-framerate` / `-r` 指定视频帧率, 默认是 ntsc, 60ifps 输入设备选择选择摄像头时,如果设备不支持,不会自动默认,必须手动指定 > [avfoundation @ 0x131e06650] Selected framerate (29.970030) is not supported by the device. > [avfoundation @ 0x131e06650] Supported modes: > [avfoundation @ 0x131e06650] 1920x1080@[1.000000 30.000000]fps > [avfoundation @ 0x131e06650] 1280x720@[1.000000 30.000000]fps > [avfoundation @ 0x131e06650] 1080x1920@[1.000000 30.000000]fps > [avfoundation @ 0x131e06650] 1760x1328@[1.000000 30.000000]fps > [avfoundation @ 0x131e06650] 640x480@[1.000000 30.000000]fps > [avfoundation @ 0x131e06650] 1328x1760@[1.000000 30.000000]fps > [avfoundation @ 0x131e06650] 1552x1552@[1.000000 30.000000]fps > > i 代表隔行扫描,p 代表逐行扫描 > ![img_5.png](img_5.png) 5. `-video_size` / `-s` 指定视频帧宽高 > ![img_4.png](img_4.png) 6. `-vcodec` / `-codec:v` / `-c:v` 指定视频的编码格式,默认是 libx264 7. `-b:v` 视频码率 8. `-aspect` 设置宽高比例 (4:3, 16:9 or 1.3333, 1.7777) 9. `-vf` 视频过滤器 (scale, crop, split) 10. `-vn` 不处理视频 ##### 不常用参数/不常用参数取值,如何通过help获取 1. `-rc_override override` 运行时覆盖编码器和解码器的参数 2. `-pass n -passlogfile prefix` 指定两次编码过程中日志文件路径,便于第二次编码参考第一次编码日志进行优化 3. `-vstats` 将视频编码统计数据转储到vstats_HHMMSS.log 4. `-vstats_file file` 将视频编码统计信息转储到文件 5. `-vstats_version` 指定要使用哪个版本的 vstats 格式 6. `-intra_matrix matrix` 指定自定义的帧内预测矩阵 7. `-chroma_intra_matrix` 指定自定义的色度帧内预测矩阵 8. `-vtag fourcc/tag` 指定视频编码器标签(Video Tag)的选项, 示例: `-vtag h264` 9. `-fps_mode` 设置视频同步方法/帧率模式 > passthrough (0) 每个帧及其时间戳从解复用器传递到复用器 > cfr (1) 帧将被复制和丢弃,以准确实现所请求的恒定帧速率 > vfr (2) 帧会连同其时间戳一起通过或丢弃,以防止 2 个帧具有相同的时间戳 > drop 作为直通,但会破坏所有时间戳,使复用器根据帧速率生成新的时间戳 > auto (-1) 根据复用器功能在 CFR 和 VFR 之间进行选择。这是默认方法 10. `-force_fps` 用于强制设置输出视频的帧率,无论输入视频的原始帧率是多少 11. `-streamid streamIndex:value` 将新的stream-id值分配给输出流 > 例如,要将输出 mpegts 文件的流 0 PID 设置为 33,将流 1 PID 设置为 36 `ffmpeg -i inurl -streamid 0:33 -streamid 1:36 out.ts` 12. `-force_key_frames timestamps` 强制在指定的时间点或帧数处生成关键帧(I帧) > 使用示例: `-force_key_frames 0:05:00,chapters-0.1` 在 5 分钟处,加入每章节开始前 0.1 秒的 I 帧 > 高级使用示例:`-force_key_frames expr:expr` expr中的表达式可以包含以下常量: >> n 当前处理的帧数,从0开始 n_forced 强制帧数 prev_forced_n 前一个强制帧的编号,即NAN尚未强制关键帧时 prev_forced_t 上一个强制帧的时间,即NAN尚未强制关键帧时 t 当前处理帧的时间 > `-force_key_frames expr:gte(t,n_forced*5)` `-force_key_frames expr:if(isnan(prev_forced_t),gte(t,13),gte(t,prev_forced_t+5))` 13. `-hwaccels` 列出可用加速设备 14. `-hwaccel hwaccel name` 使用硬件加速来解码匹配的流,如果所选的 hwaccel 不可用或所选解码器不支持,则此选项无效。 > none 不使用任何硬件加速(默认) auto 自动选择硬件加速方式。 vdpau 使用 VDPAU(适用于 Unix 的视频解码和演示 API)硬件加速。 dxva2 使用DXVA2(DirectX视频加速)硬件加速。 d3d11va 使用D3D11VA(DirectX视频加速)硬件加速。 vaapi 使用VAAPI(视频加速API)硬件加速。 qsv 使用 Intel QuickSync 视频加速进行视频转码。 >> 与大多数其他值不同,此选项不启用加速解码(每当选择 qsv 解码器时自动使用),而是加速转码,而不将帧复制到系统内存中。 为了使其正常工作,解码器和编码器都必须支持 QSV 加速,并且不得使用任何滤波器。 15. `-hwaccel_device devicename` 选择用于硬件加速的设备 16. `-hwaccel_output_format format` 指定硬件加速解码后的输出像素格式(pixel format) 17. `-fix_sub_duration_heartbeat` 将特定的输出视频流设置为心跳流,在收到随机访问数据包时根据该心跳流分割并推送当前正在进行的字幕 18. `-vpre preset` 指定输出视频的质量 参数主要调节编码速度和质量的平衡,有: > ultrafast(转码速度最快,视频往往也最模糊) superfast veryfast faster fast medium slow slower veryslow placebo 共10个选项,从快到慢 19. `-tune` 主要配合 preset 视频类型和视觉优化的参数,tune的值有: > film: 电影、真人类型 animation: 动画 grain: 需要保留大量的grain时用 stillimage: 静态图像编码时使用 psnr: 为提高psnr做了优化的参数 ssim: 为提高ssim做了优化的参数 fastdecode: 可以快速解码的参数 zerolatency:零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码 ##### 常见实例:相较简单的场景 ```Shell ##### 将视频设备 0 中的视频和音频设备 0 中的音频录制到 out.avi 中 ffmpeg -f avfoundation -i "0:0" out.avi ##### 将视频设备 2 中的视频和音频设备 1 中的音频录制到 out.avi 中 ffmpeg -f avfoundation -video_device_index 2 -i ":1" out.avi ##### 使用像素格式 bgr0 从系统默认视频设备录制视频,并且不将任何音频录制到 out.avi 中 ffmpeg -f avfoundation -pixel_format bgr0 -i "default:none" out.avi ``` ##### 使用中常见的error,原因及解决方法 ![img_13.png](img_13.png) #### [音频输入 - 采集](#audio-cap-title) ##### 常用参数、参数含义及常用取值 1. `-audio_device_index` 指定视频采集设备 2. `-aframes` 音频帧率 3. `-b:a` 音频码率 4. `-ar` 采样率 5. `-ac` 声道 6. `-acodec` / `-codec:a` / `-c:a` 音频编码器 (libmp3lame, copy 保留原始编码方式) 7. `-af` 音频过滤器 8. `-an` 不处理音频 ##### 不常用参数/不常用参数取值,如何通过help获取 1. `-atag fourcc/tag` 指定音频编码器标签 2. `-sample_fmt format` 设置音频采样率 3. `-channel_layout layout` / `-ch_layout layout` 设置音频声道 4. `-guess_layout_max` 用于在音频转码时指定允许的最大通道布局数 5. `-apre preset` 同视频 ##### 使用中常见的error,原因及解决方法 ![img_12.png](img_12.png) ![img_14.png](img_14.png) #### [视频输出 - 播放](#video-play-title) ##### 播放时的默认参数有哪些 1. `-video_size` 视频宽高比,默认值 iw x ih 2. `-pixel_format` 像素格式 3. `-byte` 按字节进行拖动 0=off, 1=on, -1=auto 4. `-seek_interval` 自定义左右方向键拖动间隔,默认是 10s 5. `-window_title` 窗口名称,默认是输入文件名称 6. `-showmode` 设置显示模式,0=视频,1=音频波形,2=显示音频频谱,默认为 0,如果不存在视频,默认为 2 7. `-stats / -nostats` 是否显示音视频流详情 pts 等信息,默认开启 8. `-sync` 主时钟以谁为准,默认是 audio,可选项:audio (type=audio) / video (type=video) / external (type=ext) ##### 不常用参数/不常用参数取值,如何通过help获取 1. `-fs` 全屏模式 2. `-an / -vn / -sn` 禁用音频/视频/字幕 3. `-nodisp` 无图形化窗口,也没有视频 4. `-ss` 指定播放位置 5. `-t` 指定播放时长 6. `-loop` 指定播放循环次数 7. `-noboder` 指定图形化窗口没有边框 8. `-volume` 指定初始化音量大小 9. `-vf / -af` 指定音视频过滤器 10. `-ast / -vst / -sst` 如果一个 m3u8 包含多条视频流/多条音频流/多条字幕流,可以在初始化的时候指定 视频 1 播放视频 2 的音频,展示视频 3 的字幕流 11. `-autoexit` 自动退出 #### [音频输出 - 播放](#audio-play-title) ### 常见使用需求或复杂使用场景 ```Shell ffplay lk_start.mkv ``` // 应该有一个每个需求如何详细展示的例子,需要包含命令和其他什么? #### 音频 录制一段音频 ```Shell ffmpeg -f avfoundation -i ':0' cap.aac ``` 播放一段音频 ```Shell ffplay cap.aac ``` 播放PCM格式音频 ```Shell ffplay -f s16le -sample_fmt s16 -ar 48000 -ac 2 -f s16le cap.pcm ``` 边采集边播放音频 mp4提取音频,格式WAV ```Shell ffmpeg -i lk.mp4 -vn lk.wav ``` WAV格式音频转成PCM格式 ```Shell # 如果输入音频的采样率太大,必须指定 ar ffmpeg -i lk-mp4.wav -ar 44100 lk-mp4.pcm ``` 音频变速 ```Shell ffplay -af 'atempo=2' lk-mp4.wav ``` 播放抓包文件 音频格式转码 ??? ```Shell # 正常 ffmpeg -i lk.aac -c:a libmp3lame lk-01.mp3 # !!! !!! 失败,原因是在视频提取音频时没有定义好输出的 pcm ffmpeg -f s16le -ar 44100 -ac 2 -i lk-mp4.pcm -c:a libmp3lame lk-mp4.mp3 # 这个是好的 ffmpeg -i lk_start.mp4 -vn -f s16le -ar 44100 -ac 2 lk_start.pcm ffmpeg -f s16le -ar 44100 -ac 2 -i lk_start.pcm -c:a libmp3lame lk_start.mp3 ``` 抽取pcm数据 播放rtp流 重采样pcm数据 合并多个文件 - 转码 合并多个文件 - 非转码 推流,转推流,24小时循环文件推流 #### 视频 录制一段摄像头视频 ```Shell ffmpeg -f avfoundation -pix_fmt uyvy422 -r 30 -i '0:' cap.mp4 ``` 录制一段屏幕视频 ```Shell ffmpeg -f avfoundation -pix_fmt uyvy422 -r 30 -i '1:' cap.mp4 ``` 播放一段视频 ```Shell ffplay cap.mp4 ``` 播放YUV格式视频 ```Shell ffplay -pixel_format yuv420p -video_size vga cap.yuv ``` 播放h264格式视频 边采集边播放视频 ```Shell ffmpeg -s 1280x720 -r 30.0 -pix_fmt nv12 -f avfoundation -i '1:0' -c:v libx264 -c:a aac -f mpegts udp://127.0.0.1:1234 | ffplay -i udp://127.0.0.1:1234 ffmpeg -f avfoundation -r 30 -video_size 1280x720 -i "default" -vf "format=yuv420p" -f rawvideo -pix_fmt rgb24 - | ffplay -f rawvideo -pixel_format rgb24 -video_size 1280x720 - ``` mp4提取视频,格式YUV ```Shell ffmpeg -i lk_start.mp4 lk_start.yuv ``` 拼接视频片段 视频变速 ```Shell ffplay -pixel_format yuv420p -video_size 1920x1080 -vf 'setpts=PTS/2' lk_start.yuv ``` 间隔1s提取视频帧换面,保存为图片 截取视频片段 ```Shell ffmpeg -i lk_start.mp4 -ss 00:00:05 -t 10 lk_short.mp4 ``` 添加时间水印,自定义位置,颜色,大小 视频指定分辨率转码 ```Shell ffmpeg -i lk_start.mp4 -vf 'scale=640:-2' lk_scale.mp4 ``` 加水印 ```Shell ffmpeg -i lk_start.mp4 -vf 'drawtext=text="niubality“:x=10:y=10:fontcolor=red' lk_start_wp.mp4 ffmpeg -i lk_start.mp4 -i img.png -filter_complex '[0:v] [1:v] overlay=10:10 [out]' -map '[out]' lk_start_wpp.mp4 ``` 抽取264数据 播放抓包文件 视频格式转码 ```Shell ffmpeg -pix_fmt yuv420p -s 1920x1080 -i lk_start.yuv lk_start-01.mp4 ``` 播放rtp流 视频文件加字幕 合并多个文件 - 转码 合并多个文件 - 非转码 推流,转推流,24小时循环文件推流 截取视频中的某些帧,并存储成图片 截取直播流片段 直播添加水印 #### ffprobe 查看视频关键帧间隔,查看pts,dts ```Shell ffprobe -select_streams v -show_frames -show_entries frame=key_frame,pts,pkt_dts,pict_type -of json -i lk_start.mp4 | grep -B 3 '"pict_type": "I"' ``` 查看文件元信息 ```Shell ffprobe -of json -show_streams lk_start.mp4 ```