使用FFmpeg玩转音视频处理(操作大全)

一、前言

玩转音视频转码、推流等,首先要了解你用的是什么平台。不同平台获取摄像头、麦克风的方式是不一样的

1.1 查看设备信息

1.1.1 Windows平台

 在“计算机”右键——“管理”——“设备管理器”中就可以查看摄像头和麦克风的信息

或通过ffmpeg查询相关信息:

ffmpeg -list_devices true -f dshow -i dummy

注:Windows平台使用dshow即可显示所有设备,Linux平台需要分类型显示设备,因此需要注意命令中的dshow、alsa、v4l2等参数区别:

dshow:指DirectShow,是一个Windows平台的流媒体框架,提供高质量的多媒体流采集和回访功能
alsa:指Advanced Linux Sound Architecture,是一个高级Linux声音架构,提供了音频和MIDI的支持
Video4linux2:简称V4L2,是Linux平台关于视频设备的内核驱动,提供了图片、视频、音频采集所需的API

本文后续命令,需根据自己的平台自行替换相关参数

1.1.2 Linux平台

1)麦克风管理

Linux上查询麦克风的方法很多,但要注意判断能否用于ffmpeg

a.查询麦克风信息
# 列出所有声卡设备
aplay -l	

# 列出所有录音设备
arecord -l	

# 列出所有录音设备(获取音频采集时声卡名称用这个)
arecord -L	

# 查看card2信息
ll /proc/asound/card2	

# 查看声卡支持的格式(通道信息、支持的采样率等)
cat /proc/asound/card2/stream0	

 b.配置声卡
# 安装pavucontrol控制器软件
sudo apt install pavucontrol

# 使用pavucontrol控制器配置声卡
pavucontrol
c.使用声卡录音
arecord -D "plughw:1,0" -f S16_LE -r 44100 -d 5 -t wav file.wav

# 参数说明:
# -D	设备名称,“plughw:1,0”中1表示card1,0表示subdevice
# -r	采样率
# -f	录音格式,S16_LE表示16bit位宽
# -d	录音时长
# -t	输出音频格式
d.播放录音
aplay file.wav

2)摄像头管理

查询摄像头信息
ls /dev/video*

或安装v4l2工具查看

# 安装v4l2工具包
sudo apt install v4l-utils

# 查看摄像头设备
sudo v4l2-ctl --list-devices

# 查看当前摄像头支持的视频压缩格式
$ sudo v4l2-ctl -d /dev/video0 --list-formats

# 查看摄像头所有参数
$ sudo v4l2-ctl -d  /dev/video0 --all

 # 查看摄像头所支持的分辨率
 sudo v4l2-ctl --list-framesizes=MJPG -d /dev/video0

二、FFmpeg套装

        FFmpeg可能是目前最强大的音视频编解码工具自由软件,它同时也是一个音视频编辑套件。它能够实现音视频编码、解码、转码、流处理、音视频过滤、音视频播放等功能。它还具有高度可移植性,可以在各种环境中构建,跨Linux、Mac OS、Windows、BSD、Solaris等平台。它包含可以由应用程序使用的libacvodec、libavutil、libavformat、libavfilter、libavdevice、libswscale和libswresample组件,同时ffmpeg包含ffmpeg、ffplay、ffprobe等工具,用户可以通过这些工具和组件实现音视频自由转码和播放。

2.1 FFmpeg使用

2.1.1 ffmpeg参数说明

公共参数:
    -i             指定输入源
    -codec    指直接复制流
    -vn          去掉视频(不处理视频)
    -an         去掉音频(不处理音频)
    -t            持续时间
    -ss          起始时间
    -f             输出格式或编码(h264 表示输出时的视频编码;mp4 表示输出的是mp4视频格式;mpegts 表示输出的是ts视频流;rtsp 表示输出的是rtsp视频流)


视频参数:
    -vframes     设置要输出的视频帧数
    -b:v             视频码率
    -r                 帧率(默认25)
    -s                帧大小(W*H)
    -aspect       纵横比(4:3/16:9)
    -vcodec      视频选项,一般后面加copy表示原始解码数据必须被拷贝
    -vf               视频过滤器


音频参数:
    -aframes     设置要输出的音频帧数
    -b:a             音频码率
    -ar               音频采样率
    -ac              设定声音通道数(一般为左右两声道,即2)
    -acodec      音频选项,一般后面加copy表示原始解码数据必须被拷贝
    -af               音频过滤器

 2.1.2 本地音视频处理

1)视频格式转换

# 视频格式转换(将h264格式转为ts格式)
ffmpeg -i test.h264 -vcodec copy -f mpegts test.ts
# 视频格式转换(将h264格式转为MP4格式)
ffmpeg -i test.h264 -vcodec copy -f mp4 test.mp4

# RGB和YUV数据转换
ffmpeg -s 640*480 -i yuv420p_640x480.yuv  -pix_fmt yuv420p -pix_fmt rgb24 -s 640*480 rgb24_640x480.rgb

2)视频转码

# 改变视频编码格式
ffmpeg -i test_1280x720.mp4 -vcodec libx265 -acodec libmp3lame out_h265_mp3.mkv
# 改变帧率
ffmpeg -i test_1280x720.mp4 -r 15 output2.mp4
# 改变视频码率
ffmpeg -i test.mp4 -b 400k output_b.mkv
# 改变视频码率(仅视频)
ffmpeg -i test.mp4 -b:v 400k output_bv.mkv
# 改变视频码率(仅音频)
ffmpeg -i test.mp4 -b:a 192k output_ba.mp4
# 改变视音频码率
ffmpeg -i test.mp4 -b:v 400k -b:a 192k output_bva.mp4
# 改变视频分辨率
ffmpeg -i test.mp4 -s 480x270 output_480x270.mp4
# 视频码率调整
ffmpeg -i test.mp4 -vframes 300 -b:v 400k -r 30 -s 640x480 -aspect 16:9 -vcodec libx265
# 改变音频采样率
ffmpeg -i test.mp4 -ar 44100 output_44100hz.mp4

3)音视频提取

# 直接提取视频画面
ffmpeg -i test_1280x720.mp4 -vcodec copy -an video.mp4
# 提取视频画面并强制格式
ffmpeg -i test_1280x720.mp4 -vcodec libx264 -an video.h264
# 直接提取视频音轨
ffmpeg -i test_1280x720.mp4 -acodec copy -vn audio.mp4
# 提取视频音轨并强制编码
ffmpeg -i test_1280x720.mp4 -acodec libmp3lame -vn audio.mp3
# 提取指定码率的音频
ffmpeg -i test_1280x720.mp4 -b:a 192k -ar 48000 -ac 2 -acodec aac -aframes 200 out2.mp3

# 提取yuv数据(提取3秒,分辨率和源视频保持一致)
ffmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p yuv420p_orig.yuv
# 提取yuv数据(提取3秒,分辨率转为320*240)
ffmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p -s  640*480 yuv420p_320x240.yuv

# 提取rgb数据(提取3秒,分辨率转为320*240)
ffmpeg -i test.mp4 -t 3 -pix_fmt rgb24 -s 320x240 rgb24_320x240.rgb

 4)音视频裁剪

# 视频裁剪(从第10秒到第20秒)
ffmpeg -i input.mp4 -ss 00:00:10 -t 00:00:20 -c:v copy -c:a copy output.mp4
# 视频拆分(每10秒拆分成一个视频文件)
ffmpeg -i input.mp4 -f segment -segment_time 10 -c copy output%d.mp4
# 视频截图(在test.mp4中截图)
ffmpeg -i test.mp4  -t 0.001 -s 352x240 1.jpg
# 视频截图(将test.mp4前30帧做成gif动图)
ffmpeg -i test.mp4 -vframes 30 -y -f gif 1.gif
# 视频截图(从视频前10s中取图像,1s提取一帧)
ffmpeg -i test.mp4 -t 10 -r 1 pic-%03d.jpg

5)音视频合成

# 查看视频信息(显示音视频轨道信息、码率等)
ffmpeg -i Hotel.Transylvania.4.Transformania.2022.中英字幕.mkv

# 视频中合并字幕,并强制视频编码为H264编码
ffmpeg -y -i「视频全名」 -vf subtitles=「字幕文件名」 -vcodec h264 「导出的视频文件名」
# 视频中合并字幕,并强制视频编码为x264编码(此方式提高crf值,但清晰度很高)
ffmpeg -y -i filename.mkv -vf subtitles='filename.mkv' -disposition:s default+forced -c:v libx264 -c:a libmp3lame -crf 27 -preset ultrafast filename.mp4 

# 视频剥离多音轨和字幕(仅保留视频轨道和音频默认轨道)
ffmpeg -i Hotel.Transylvania.4.Transformania.2022.中英字幕.mkv -map 0:0 -map 0:1  OutPut.mkv

# 截取并融合字幕轨道到视频轨道中(适用于subrip类型字幕)
ffmpeg -i Hotel.Transylvania.4.Transformania.2022.中英字幕.mkv -filter_complex "[0:v:0]subtitles=Hotel.Transylvania.4.Transformania.2022.中英字幕.mkv:si=2[v]" -map "[v]" -map 0:1  Hotel.mp4
## 注:
	-filter_complex "[0:v:0]subtitles=Hotel.Transylvania.4.Transformania.2022.中英字幕.mkv:si=2[v]" -map "[v]" 	表示截取并融合视频文件的视频轨道与字母轨道,融合后再与音频轨道融合并渲染
# 截取并融合字幕轨道到视频轨道中(适用于hdmv_pgs_subtitle类型字幕)
ffmpeg -i HotelTransylvania.mkv -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" -map 0:a:0 out.mp4

# 视频上增加水印(文字水印)
ffmpeg -i input.mp4 -vf "drawtext=text='Your Watermark':fontsize=20:fontcolor=white:x=10:y=10" -c:v libx264 -crf 18 output.mp4
# 视频上增加水印(图片水印)
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=10:10" -c:v libx264 -crf 18 output.mp4

# 视频拼接(将test1.h264和test2.h264视频拼接起来,输出out12.h264视频)
ffmpeg -i "concat:test1.h264|test2.h264" -vcodec copy -f h264 out12.h264
# 视频双宫格显示
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -filter_complex "nullsrc=size=640x480[base];[0:v]setpts=PTS-STARTPTS,scale=320x240[upperleft];[1:v]setpts=PTS-STARTPTS,scale=320x240[upperright];[base][upperleft]overlay=shortest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=320" out2.mp4
# 视频四宫格显示
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -filter_complex "nullsrc=size=640x480[base];[0:v] setpts=PTS-STARTPTS,scale=320x240[upperleft];[1:v]setpts=PTS-STARTPTS,scale=320x240[upperright];[2:v]setpts=PTS-STARTPTS, scale=320x240[lowerleft];[3:v]setpts=PTS-STARTPTS,scale=320x240[lowerright];[base][upperleft]overlay=shortest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=320[tmp2];[tmp2][lowerleft]overlay=shortest=1:y=240[tmp3];[tmp3][lowerright]overlay=shortest=1:x=320:y=240" out3.mp4

 2.1.3 音视频流处理

1)捕获本地摄像头、麦克风

# 捕获摄像头视频
ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 mycamera.mkv

# 捕获麦克风声音
ffmpeg -f dshow -i audio="麦克风(High Definition Audio 设备)" -acodec aac d:\temp.aac

# 捕获桌面和声卡声音录制成flv文件
ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="virtual-audio-capturer" -pix_fmt yuv420p -ar 48000 -vcodec libx264 -crf 23 -preset veryslow -x264opts b-adapt=2:bframes=0:aq-strength=1:psy-rd=0.8,0 -vsync vfr -acodec aac -bsf:a aac_adtstoasc -f flv temp.flv
## 注:
##	上面使用x264编码,若想提高x264编码速度,可使用-preset:v ultrafast -tune:v zerolatency  两个参数
##	如:ffmpeg -f dshow -i video="Integrated Webcam" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency d:\test.mp4

# 创建空白视频(指定颜色与时长)
ffmpeg -ss 0 -t 00:00:05.300  -f lavfi -i color=c=0x000000:s=1280x720:r=25 -vcodec libx264 D:/linux-share-dir/video_file/video/test.mp4
## 注:
##	-t 是视频的时长
##	color=c=0x000000:s=1280x720:r=25 画面颜色、尺寸、帧率

 2)本地摄像头、麦克风推流

# 查看本机设备信息
ffmpeg -list_devices true -f dshow -i dummy

## 注:本机硬件推送流发出后,必须有配套的RTMP/RTSP服务器接收数据流

# 推送音视频流到RTMP服务器(Windows平台)
ffmpeg -f dshow -i video="Lenovo EasyCamera":audio="麦克风 (Realtek High Definition Audio)" -vcodec libx264 -acodec copy -preset:v ultrafast -tune:v zerolatency -f flv "rtmp://192.168.1.85:8553/test"

# 推送音视频流到RTSP服务器(Windows平台)
ffmpeg -f dshow -i video="Lenovo EasyCamera":audio="麦克风 (Realtek High Definition Audio)" -vcodec libx264 -acodec libvo_aacenc -preset:v ultrafast -tune:v zerolatency -f rtsp rtmp://192.168.1.85:8554/test
# 推送音视频流到RTSP服务器(设置帧率)
ffmpeg -f dshow -i video="Lenovo EasyCamera":audio="麦克风 (Realtek High Definition Audio)" -vcodec libx264 -acodec libvo_aacenc -b 1080k -r 25 -preset:v ultrafast -tune:v zerolatency -f rtmp://192.168.1.85:8554/test
## 注:设置帧率信息要在推流地址前面,在摄像头信息后面

# 推送音频流到RTSP服务器(Linux默认声卡)
ffmpeg -f alsa -i default -ac 2 -ar 44100 -acodec aac -f rtsp rtsp://192.168.1.204:8554/audio
# 推送音频流到RTSP服务器(Linux指定声卡,查询声卡信息可以使用arecord -L获取声卡名称)
ffmpeg -f alsa -i plughw:CARD=sbj3308,DEV=0 -ac 2 -ar 44100 -acodec aac -f rtsp rtsp://192.168.1.204:8554/audio

# RTMP/RTSP方式推麦克风
ffmpeg -f alsa -thread_queue_size 1024 -ac 2-ar 44100 -i hw:0,0 -acodec aac -f flv rtmp://192.168.8.222:1935/live/stream0
ffmpeg -f alsa -thread_queue_size 1024 -ac 2-ar 44100 -i hw:0,0 -acodec aac -f rtsp rtsp://192.168.8.222:1935/live/stream0

# RTMP/RTSP方式推摄像头
ffmpeg -f video4linux2 -r 30 -i /dev/video0 -vcodec h264 -f flv rtmp://192.168.8.222:1935/live/stream0
ffmpeg -f video4linux2 -r 30 -i /dev/video0 -vcodec h264 -f rtsp rtsp://192.168.8.222:1935/live/stream0

# RTMP/RTSP方式推摄像头和麦克风
ffmpeg -f video4linux2 -r 30 -i /dev/video0 -vcodec h264 -f alsa -thread_queue_size 1024 -ac 2 -ar 44100 -i hw:0,0 -acodec mp3 -f flv rtmp://192.168.8.222:1935/live/stream0
ffmpeg -f video4linux2 -r 30 -i /dev/video0 -vcodec h264 -f alsa -thread_queue_size 1024 -ac 2 -ar 44100 -i hw:0,0 -acodec mp3 -f rtsp rtsp://192.168.8.222:1935/live/stream0

# 生成空的视频结合麦克风音频输出RTSP流
ffmpeg -f lavfi -i color=c=0x000000:s=1280*720:r=25 -vcodec libx264 -f alsa -i plughw:CARD=sbj3308,DEV=0 -ac 2 -ar 44100 -acodec aac -f rtsp rtsp://192.168.1.204:8554/audio
ffmpeg -f lavfi -i color=c=0x000000:s=1280*720:r=25 -vcodec h264 -f alsa -i plughw:CARD=sbj3308,DEV=0 -ac 2 -ar 44100 -acodec aac -f rtsp rtsp://192.168.1.204:8554/audio

注:自建RTSP流接收服务器可以使用MediaMTX(原rtsp-simple-server)来快速构建。项目地址: https://github.com/bluenviron/mediamtx

3)捕获网络流到本地

# 将RTSP流保存为文件
ffmpeg -i rtsp://@192.168.241.1:62156 -acodec copy -vcodec copy -f mp4 c:/abc.mp4
## 注:
##	也可以重新编码以提高画质
##	ffmpeg -i rtsp://@192.168.241.1:62156 -b 900k -vcodec copy -r 60 -y MyVdeoFFmpeg.avi

# 直播录制
ffmpeg -i https://xxx/Mintimate.m3u8 -c:v copy -c:a copy -bsf:a aac_adtstoasc Output.mp4

 2.2 FFplay使用

2.2.1 ffplay参数说明

    -i     指定输入源
    -volume     指定声道数量
    -x     指定画面宽度
    -y     指定画面高度
    -s     指定画面宽度和高度信息(如:640*480)
    -f         指定输出格式

    -t     指定播放时长
    -framerate     指定帧率
    -fs     全屏播放
    -an     禁用音频
    -vn     禁用视频
    -sn     禁用字幕
    -ss     开始播放位置
    -acodec     指定音频播放解码器,等同于-codec:a
    -vcodec     指定视频播放解码器,等同于-codec:v
    -window_title lpf     指定播放器播放视频时显示的名称
    -loop number     指定播放循环次数
    -nostats     不输出视频相关信息(通过这个可以查看ffplay如何收集视频信息,自己写播放器时可以借鉴)
    -ast     执行音频流索引
    -vst     执行视频流索引
    -autoexit     播放完毕后自动退出

2.2.2 视频播放

# 强制视频播放宽度和高度
ffplay -i test_1920x1080.mp4 -volume 1 -x 800 -y 480

# 从指定位置开始播放视频
ffplay -i test_1280x720.mp4 -volume 1 -x 800 -y 480 -fs -ss 00:05:55

# 控制视频播放流的索引
ffplay -i mult.ts -x 800 -y 480 -vst 4 -ast 3

# 指定播放时长,超过时长自动退出
ffplay -i mult.ts -x 800 -y 480 -t 5 -autoexit

# 指定视频播放解码器
ffplay -i test_1280x720.mp4 -x 800 -y 480 -t 5 -autoexit -codec:v h264

# 指定音频播放解码器
ffplay -i test_1280x720.mp4 -x 800 -y 480  -t 5 -autoexit -codec:a libfdk_aac

# 播放rtmp流媒体
ffplay -window_title "cctv1" -x 640 -y 480 rtmp://media3.scctv.net/live/scctv_800

# 原编码流播放
ffplay -i test_1280x720.mp4 -codec copy -ss 10 -t 20 -f flv out.mp4

# 播放yuv裸流视频(裸流视频播放必须指定宽度和高度、视频格式、帧率信息,其中宽度和高度不指定会绿屏或花屏)
ffplay -pixel_format yuv420p -video_size 320x240 -framerate 5 yuv420p_320x240.yuv
或
ffplay -i yuv420p_640x480.yuv -s 640*480

# 播放rgb视频(rgb格式数据播放时必须指定-pixel_format rgb24以及分辨率,否则播放不出来,不指定-pixel_format会花屏或绿屏)
ffplay -i rgb24_320x240.rgb -pixel_format rgb24 -video_size 320x240 

# 播放pcm音频(裸流视频必须指定采样率、通道数、位深信息)
ffplay -ar 48000 -ac 2 -f f32le 48000_2_f32le.pcm

 2.2.3 加滤镜播放

# 视频旋转播放
ffplay -i test_1280x720.mp4 -x 800 -y 480  -t 25 -autoexit -codec:a libfdk_aac  -window_title lpf -vf transpose=1

# 视频反转播放
ffplay test.mp4 -vf hflip
ffplay test.mp4 -vf vflip

# 视频旋转和反转播放
ffplay test.mp4 -vf hflip,transpose=1

# 音频变速播放
ffplay -i test_1280x720.mp4 -x 800 -y 480  -t 25 -autoexit -codec:a libfdk_aac  -window_title lpf -af atempo=2

# 视频变速播放
ffplay -i test.mp4 -vf setpts=PTS/2

# 视频和音频同时变速播放
ffplay -i test_1280x720.mp4 -x 800 -y 480  -t 25 -autoexit -codec:a libfdk_aac  -window_title lpf -af atempo=2 -vf setpts=PTS/2

# 画中画(副视频停下后默认显示最后一帧图像)
ffplay -i input.mp4 -vf "movie=sub_320x240.mp4[sub];[in][sub]overlay=x=20:y=20[out]"

# 画中画(短的视频停止后都会停止,通过eof_action控制)
ffplay -i input.mp4 -vf "movie=sub_320x240.mp4[sub];[in][sub]overlay=x=20:y=20:eof_action=1[out]"
# 画中画(短的视频停止后都会停止,通过shortest控制)
ffplay -i input.mp4 -vf "movie=sub_320x240.mp4[sub];[in][sub]overlay=x=20:y=20:shortest=1[out]"

# 画中画(短的视频停止后画面结束)
ffplay -i input.mp4 -vf "movie=sub_320x240.mp4[sub];[in][sub]overlay=x=20:y=20:eof_action=2[out]"

# 对副视频进行缩放播放
ffplay -i input.mp4 -vf "movie=sub_320x240.mp4,scale=640x480[sub];[in][sub]overlay=x=20:y=20[out]"

# 跑马灯播放
ffplay -i test_60_1280x720.mp4 -vf "movie=test_60_1280x720.mp4,scale=320x270[test];[in][test]overlay=x=mod(50*t\,main_w):y=abs(sin(t))*main_h*0.7[out]"

本文中涉及FFmpeg使用的脚本中包含各种解码器需要独立安装,如执行脚本时提示无法识别解码器(如H264、x264等),请自行安装并更新FFmpeg(如有必要,后续会再整理一篇FFmpeg解码器安装篇)。

以上就是FFmpeg的基本操作集合,本文部分内容和脚本来源于网络整理,如有侵权请联系我删除,希望本文对您有所帮助!

猜你喜欢

转载自blog.csdn.net/Asgard_Hu/article/details/131943392