FFmpeg入门实践

191 阅读9分钟

环境

系统ffmpeg版本
macOS m15.0.3

安装

  1. 下载源码

git clone github.com/FFmpeg/FFmp…

  1. 安装
# macOS 采用源码安装的ffmpeg 可使用此方法安装libfdk-aac
sudo ./configure --prefix=/usr/local/ffmpeg/ --enable-shared --disable-static --enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libx264 --enable-libx265
sudo make -j 4
sudo make install

遇到问题可以在这里来看一下是否有答案

查询设备支持

# 可以使用下面的命令查看mac上有哪些设备:
ffmpeg -f avfoundation -list_devices true -i ""
# 如何查看音频参数
​
​
ffmpeg version 5.0.3 Copyright (c) 2000-2022 the FFmpeg developers
  built with Apple clang version 13.0.0 (clang-1300.0.29.3)
  configuration: --prefix=/usr/local/ffmpeg/ --enable-shared --disable-static --enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libx264 --enable-libx265
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
[AVFoundation indev @ 0x12d00a0f0] AVFoundation video devices: 视频设备
[AVFoundation indev @ 0x12d00a0f0] [0] FaceTime HD Camera
[AVFoundation indev @ 0x12d00a0f0] [1] Capture screen 0
[AVFoundation indev @ 0x12d00a0f0] AVFoundation audio devices: 音频设备
[AVFoundation indev @ 0x12d00a0f0] [0] 外置麦克风
[AVFoundation indev @ 0x12d00a0f0] [1] MacBook Pro麦克风
​

基本信息查询命令

指令说明指令说明
-version显示版本-formats显示可用格式
-demuxers显示可用的demuxers,在多媒体处理中,通常需要将一个媒体流分解成多个单独的流,例如将一个视频流分解成音频流和视频流。这个过程就是由demuxers完成的,可以理解为解封装-protocols显示可用协议
-muxers显示可用的muxers,muxers将多个单独的流合并成一个文件,例如将视频流、音频流和字幕流合并为一个视频文件。这个过程中,muxers会将这些流编码成特定的格式,例如MP4、AVI、FLV等。可以理解为封装-filters显示可以的过滤器
-devices显示可用设备-pix_fmt显示可用的像素格式
-codecs显示所有的编解码器-sample_fmt显示可用的采样格式
-decoders显示可用的解码器-layouts显示channel名称
-encoders显示可用的编码器-colors显示识别的颜色名称
-bsfs显示比特流filter

录制命令

录屏命令

yuv

ffmpeg -f avfoundation -i 1 -r 30 pingmu.yuv
# 录制完成后屏幕内会有 分辨率 与 色彩空间信息,使用ffplay播放需要参考以上信息
ffplay -pix_fmt uyvy422 -s 3024x1964 pingmu.yuv
​
# -f 指定使用avfoundation采集数据
# -i 指定从哪采集数据,它是一个文件索引,0代表摄像头 1代码表屏幕
# -r 指定帧率。按ffmpeg官方文档说-r与-framerate作用相同,但实际测试时发现不同。-framerate 用于限制输入,而-r用于限制输出。
# -s 分辨率
# pix_fmt 像素空间
​
​
# 抽取视频yuv
ffmpeg -i lizi.mp4 -an -c:v rawvideo -pix_fmt yuv420p out.yuv
ffplay -pix_fmt yuv420p -s 1920x1080 out.yuv
​

mp4

# 录制
ffmpeg -framerate 30 -f avfoundation -i 0 out.mp4
-framerate 限制视频的采集帧率。这个必须要根据提示要求进行设置,如果不设置就会报错。
-f 指定使用 avfoundation 采集数据。
-i 指定视频设备的索引号。
播放命令:
ffplay out.mp4
​

录音命令

wav

# 录制音频
ffmpeg -f avfoundation -i :0 out.wav
-f 指定使用 avfoundation 采集数据。
-i 指定从哪儿采集数据,它是一个文件索引号。
: 冒号前面的是视频采集索引号,冒号后面是音频采集索引号
# 播放声音的命令
ffplay out.wav
​
ffplay -ar 48000 -ac 1 -f s16le out.wav

pcm

#录制音频裸数据
ffmpeg -f avfoundation -i :0 -ar 48000 -f s16le out.pcm
#播放 mac m1
ffplay -ar 48000 -ac 1 -f s16le out.pcm 
---
#使用FFmpeg录制声音时,如果将立体声音频转换为单声道,可能会出现速度不一致的问题。这是因为立体声音频的左右通道通常具有不同的延迟和相位特性,#而在单声道模式下,这些特性会变得相同。
#当将立体声音频转换为单声道时,FFmpeg会将其视为两个相同的通道,并将它们的信号混合在一起。由于立体声音频的左右通道具有不同的延迟和相位特性,因此混合后的单声道音频可能会出现速度不一致的问题。
#采样 mac m1
ffplay -ar 48000 -ac 1 -f f32le sampling.pcm
#重采样 mac m1
ffplay -ar 44100 -ac 1 -f s16le resample.pcm

acc

# 编码acc
ffmpeg -ar 48000 -ac 1 -f f32le -i sampling.pcm output.aac
ffmpeg -ar 48000 -ac 1 -f f32le -i input.pcm -c:a pcm_s16be output.acc
ffmpeg -ar 48000 -ac 1 -f f32le -i sampling.pcm -c:a libfdk_aac output.acc

录制音视频

# 摄像头录制
ffmpeg -f avfoundation -video_size 1280x720 -framerate 30 -r 30 -pixel_format uyvy422 -i "0:0" -vcodec libx264 -preset ultrafast -acodec libfdk_aac -f flv out.flv
​
ffmpeg -f avfoundation -video_size 640x480 -framerate 30 -r 30 -pixel_format uyvy422 -i "0:0" -c:v libx264 -crf 0 -c:a libfdk_aac out.mp4 
​
# -f avfoundation 表示使用AVFoundation框架作为输入源。
# -video_size 1280x720 表示设置视频分辨率为1280x720像素。
# -framerate 30 表示设置帧率为30帧每秒。
# -r 30 表示设置视频的帧率与音频的帧率相同,均为30帧每秒。
# -pixel_format uyvy422 表示设置像素格式为UYVY422。
# -i "0:0" 表示指定输入设备为第一个摄像头(编号为0)。
# -vcodec libx264 表示使用libx264编码器对视频流进行编码。
# -preset ultrafast 表示使用ultrafast预设参数进行编码,以获得最快的编码速度。
# -acodec libfdk_aac 表示使用libfdk_aac编码器对音频流进行编码。
# -f flv 表示将输出文件保存为FLV格式。
# out.flv 表示输出文件的名称为out.flv。# -c:v  与 -vcodec 意思一样吗?
# 在FFmpeg中,-c:v和-vcodec参数的作用是一样的,它们都用于指定视频编解码器# 屏幕录制
ffmpeg -f avfoundation -video_size 640x480 -framerate 30 -r 30 -pixel_format uyvy422 -i "1:0" -c:v libx264 -crf 0 -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k out.mp4
​

分解/复用命令

# 多媒体文件格式的转换
 _______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets 解封装| -----+
|_______|            |______________|      |
                                           v
                                       _________
                                      |         |
                                      | decoded |
                                      | frames  |
                                      |_________|
 ________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets 封装  |   encoder
|________|           |______________|
​
​

mp4 -> flv

# 不改变音视频编解码,只是将封装格式由 mp4 到 flv
ffmpeg -i lizi.mp4 -vcodec copy -acodec copy out.flv
# -i 输入文件
# -vcodec 视频编解码器
# -acodec 音频编解码器
# copy 复制不改变

抽取视频

#首先确认视频使用的h264编码
ffmpeg -i lizi.mp4 -an -vcodec copy out.h264
# -i 输入文件
# -an 音频不拷贝 (audio no)
# -vcodec 音频编解码器
# copy 复制

抽取音频

#首先确认音频使用的aac编码
ffmpeg -i lizi.mp4 -vn -acodec copy out.aac
# -i 输入文件
# -an 音频不拷贝 (audio no)
# -vcodec 音频编解码器
# copy 复制
​
ffmpeg -re -i out.aac -c copy -f flv  rtmp://localhost/live/livestream 

处理原始数据命令

提取yuv

# 提取yuv
ffmpeg -i input.mp4 -an -c:v rawvideo -pix_fmt yuv420p out.yuv
# -i 输入文件
# -an 音频不拷贝 (audio no)
# -c:v rawvideo 拷贝原始视频
# -pix_fmt 像素空间 yuv420p#yuv是原始数据 播放需要指定 分辨率 像素空间 
ffplay -pix_fmt yuv420p -s 640x480 out.yuv
#播放y分量
ffplay -s 640x480 -vf extractplanes='y' yuvH264.yuv
#播放u分量
ffplay -s 640x480 -vf extractplanes='u' yuvH264.yuv
#播放v分量
ffplay -s 640x480 -vf extractplanes='v' yuvH264.yuv
​

提取yuv分量

#提取yuv各个分量
ffmpeg -i lizi.mp4 -filter_complex 'extractplanes=y+u+v[y][u][v]' -map '[y]' y.yuv -map '[u]' u.yuv -map '[v]' v.yuv
#播放y分量
ffplay -s 640x480 -pix_fmt gray y.yuv
#播放u分量 分辨率除以2
ffplay -s (640/2)x(480/2) -pix_fmt gray u.yuv
#播放v分量 分辨率除以2
ffplay -s (640/2)x(480/2) -pix_fmt gray v.yuv

yuv转h264

# YUV转H264
ffmpeg -f rawvideo -pix_fmt yuv420p -s 768x320 -r 30 -i out.yuv -c:v libx264 -f rawvideo out.h264

提取pcm

ffmpeg -i out.mp4 -vn -ar 44100 -ac 2 -f s16le out.pcm
# pcm 是原始数据,播放时候需要指定 采样率 声道数 位深
ffplay -ar 44100 -ac 1 -f s16le resample.pcm

裁剪与合并命令

#裁剪
ffmpeg -i in.mp4 -ss 00:02:00 -t 10 out.ts
# -ss 起始位置
# -t 持续时间#拼接
ffmpeg -i "concat:input1.mp4|input2.mp4" -c copy output.mp4
ffmpeg -i "concat:input1.mp3|input2.mp3" -c copy output.mp3
​
#合并
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac -strict experimental output.mp4
# -i video.mp4 表示输入的视频文件为video.mp4。
# -i audio.mp3 表示输入的音频文件为audio.mp3。
# -c:v copy 表示复制视频流,即不重新编码视频流,而是直接从输入文件中读取。
# -c:a aac 表示重新编码音频流,将其转换为AAC格式。
# -strict experimental 表示启用实验性的严格模式,以确保输入文件符合预期的格式和规范。
# output.mp4 表示输出的文件名为output.mp4。
​
​
ffmpeg -f concat -i inputs.txt out.fly

inputs.txt 内容

file '1.ts'
file '2.ts'

图片/视频互相转

视频转图片

ffmpeg -i in.flv -r 1 -f image2 image-%3d.jpeg
# -i 输入文件
# -r 帧率 每秒生成图片
# -f 文件格式

图片转视频

ffmpeg -i image-%3d.jpeg out.mp4

直播相关命令

推流

ffmpeg -re -i out.mp4 -c copy -f flv rtmp://sever/live/streamName
# -re 减慢帧率速度,使播放的帧率与该文件的实际帧率保持一致
# -i 输入文件
# -c 音视频编解码
# copy 复制
# -f 文件格式

拉流

ffmpeg -i rtmp://server/live/streamName -c copy dump.flv
# -i 输入文件
# -c 音视频编解码
# copy 复制

各种滤镜命令

ffmpeg -i in.mov -vf crop=in_w-200:in_h-200 -c:v libx264 -c:a copy out.mp4
# -i 输入文件
# -vf 视频滤镜
# crop 格式 crop=out_w:out_h:x:y

推流拉流播放

## 将本地的mp4 推流到流媒体地址rtmp://localhost/live/test
-re:保证音视频同步
-c copy:阻止该视频从新编码,损失画质
-c:v 视频进行拷贝
ffmpeg -re -i ~/xxx/xxx_file.mp4 -c:v copy -f flv rtmp://localhost/live/test
## 拉取rtmp://localhost/live/test地址流并且播放出来
ffplay rtmp://localhost/live/test