一、前言
玩转音视频转码、推流等,首先要了解你用的是什么平台。不同平台获取摄像头、麦克风的方式是不一样的
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的基本操作集合,本文部分内容和脚本来源于网络整理,如有侵权请联系我删除,希望本文对您有所帮助!