音视频转码功能 - xia-chu/zlmediakit-pro GitHub Wiki
一、概述
zlmediakit pro版本支持基于ffmpeg的转码能力,在开源版本强大功能的基础上,新增支持如下能力:
- 1、音视频间任意转码(包括h265/h264/opus/g711/aac/g722/g722.1/mp3/svac。
- 2、基于配置文件的转码,支持设置比特率,codec类型等参数。
- 3、基于http api的动态增减转码,支持设置比特率,分辨率倍数,codec类型、滤镜等参数。
- 4、支持硬件、软件自适应转码。
- 5、支持按需转码,有人观看才转码。
- 6、支持负载过高时,转码主动降低帧率且不花屏。
- 7、支持滤镜,支持添加osd文本以及logo角标等能力。
- 8、支持全GPU硬件编解码与滤镜,防止显存与内存频繁拷贝。
二、转码实现原理
- 视频转码原理
- 音频转码原理
三、使用方法
目前zlmediakit pro转码能力支持两种使用方式,第一种是基于配置文件方式,在设置好配置文件后,所有流都支持转码为目标编码格式直播流,第二种模式基于http api方式,此方式更灵活,功能强大,可以指定更多转码相关参数。
3.1 基于配置文件的转码
[transcode]
#是否开启ffmpeg日志
enable_ffmpeg_log=0
#转码stream_id后缀,为空时关闭转码,为null时为透明/替换转码模式,转码流id与原始流一致
suffix=null
#是否强制转码,开启后就算目标编码格式一样也会解码再编码,开启滤镜或插件功能时,相当于强制开启转码
force=0
#开启转码的流的百分比,默认全部流开启转码,50时一半流转码,一半不转码
percent=100
#视频转码目标codec,支持H264/H265/JPEG/copy
video_codec=H264
#视频转码后的目标比特率,默认为0(如果是h265转码h264,bitrate默认翻倍否则相等)
video_bitrate=4000000
#视频编码器设置选项
video_encoder_opt=zerolatency=1,preset=ultrafast,profile=main,tune=zerolatency,nal-hrd=vbr
#视频解码器设置选项,用法与video_encoder_opt类似
video_decoder_opt=
#音频转码目标codec,支持mpeg4-generic/PCMA/PCMU/opus/copy
audio_codec=mpeg4-generic
#转码后音频比特率
audio_bitrate=32000
#转码后音频采样率率
audio_samplerate=8000
#转码后音频通道数
audio_channel=1
#avfilter滤镜参数,用法与ffmpeg -vf 参数一致
filter=
#视频滤镜线程数
filter_threads=4
#是否启用硬件解码器
hw_encoder=1
#是否启用硬件编码器
hw_decoder=1
#解码线程数,最大32个,音频强制为1个,视频默认2个
decoder_threads=4
#编码线程数,最大32个,音频强制为1个,视频默认4个
encoder_threads=4
# h264解码器白名单,前面的优先级更高
decoder_h264=h264_cuvid,h264_qsv,h264_videotoolbox,h264_nvmpi,h264_bm,libopenh264
# h265解码器白名单,前面的优先级更高
decoder_h265=hevc_cuvid,hevc_qsv,hevc_videotoolbox,hevc_nvmpi,hevc_bm
# h264编码器白名单,前面的优先级更高
encoder_h264=h264_nvenc,h264_qsv,h264_videotoolbox,h264_nvmpi,h264_bm,libx264,libopenh264
# h265编码器白名单,前面的优先级更高
encoder_h265=hevc_nvenc,hevc_qsv,hevc_videotoolbox,hevc_nvmpi,hevc_bm,libx265
#全硬件转码开关,开启后,解码->编码之间传递显存类AVFrame,不经过内存中转,大幅提高性能
#支持cuda/qsv/videotoolbox/ascend等
hwaccel=
#是否按需转码,开启后,如果无人观看,会暂停转码
demand=1
#如果音频转码生效了,是否根据pcm数据量重新计算音频时间戳
modify_audio_stamp=1
#每张编解码器最大通道数,限制每张显卡最多编解码实例数,只对ascend显卡生效
max_channel=256
#视频处理插件文件夹路径,里面存放so/dll 插件文件,不可存放非插件文件(插件依赖的so/dll应当存放其他路径)!
pluginDir=
#转码时,是否经过插件处理AVFrame视频帧,处理顺序为解码->滤镜->插件->编码,在pluginDir设置并加载插件后,此参数可以选择特定的插件
plugin=
#插件并发线程数,建议设置为0(同步输入插件),特定插件加大此参数能提高性能
plugin_threads=0
#插件处理后,视频帧数据是否重绘,开启后会重新编码视频
#否则只解码并输入插件,不重新编码(适用于纯视频分析类插件)
#此参数设置为0时,可以节省视频编码开销
paint=1
在上述配置文件中,如果用户配置好suffix,那么zlmediakit将统一把所有直播流转码为目标编码格式,用户通过访问新的流地址即可确保为预期编码格式视频。
例如源视频地址为:rtmp://127.0.0.1/live/test, 那么转码后地址即为:rtmp://127.0.0.1/live/test_H264。
当配置文件修改为suffix=null时,转码后流会直接替换原始流(不会有_suffix后缀),如果需要播放原始流,可以在url上加上?origin_stream=1后缀
;替换模式下,建议rtsp.directProxy/rtmp.directProxy都设置为0。
如果源视频编码格式与目标编码格式一致,那么zlmediakit为了确保性能最优,将直接拷贝流数据(不会编码)。
基于配置文件方式的转码使用最简单,可以使用于安防行业H265视频无法webrtc/mse播放的场景。
3.2 多转码配置方案
基于配置文件的转码方案,同时支持多种转码预设方案,用户可以通过播放不同的url后缀来实现选择播放不同转码流,例如原始流、1080P、720P:
[transcode]
#默认转码切记务必关闭
suffix=
[transcode_1080p]
filter=scale=1920:1080
# 4Mb/s
video_bitrate=4000000
#其他转码参数如果未指定,则使用[transcode]域下的,请参考3.1
[transcode_720p]
filter=scale=1280:720
# 1Mb/s
video_bitrate=1000000
#其他转码参数如果未指定,则使用[transcode]域下的,请参考3.1
如果原始流id为test, 那么播放test_1080p时,zlm会自动采用[transcode_1080p]下的转码参数转码并生成test_1080p转码流,
[transcode_720p]以此类推,当该转码流无人观看时,则会自动关闭转码,如果需要无人观看时保持一直转码,可以在[transcode]下新增配置项const_transcode=1080p,720p
3.3 基于http api的转码
zlmediakit同时还提供基于http api的转码方式,这种方式支持的功能更强大,使用更灵活,同时支持一个流转码成多个目标流( 比如说不同分辨率的场景)。
-
请求地址:
/index/api/setupTranscode -
说明:该接口支持所有protocol转协议相关参数,转协议参数如果不指定则采用配置文件protocol域下同名配置参数;转码相关参数支持所有transcode相关参数,如果不指定则采用配置文件transcode域下同名配置参数。
-
请求参数:
| 参数 | 参数类型 | 释意 | 是否必选 |
|---|---|---|---|
secret |
string |
api操作密钥(配置文件配置) | Y |
vhost |
string |
流的虚拟主机,例如__defaultVhost__ |
Y |
app |
string |
流的应用名,例如live | Y |
stream |
string |
流的id名,例如test | Y |
name |
string |
转码名(后缀),功能类似配置文件transcode.suffix | Y |
add |
int |
1:添加转码; 0: 删除转码 | Y |
video_codec |
string |
视频转码的codec,支持H264/H265/JPEG/copy | Y |
video_bitrate |
int |
转码后视频的比特率 | N |
video_decoder_opt |
string |
视频解码器配置参数 | N |
video_encoder_opt |
string |
视频编码器配置参数,例如preset=ultrafast,profile=high,tune=zerolatency | N |
audio_codec |
string |
音频转码codec,支持mpeg4-generic/PCMA/PCMU/opus/copy | Y |
audio_bitrate |
int |
转码后音频比特率 | N |
audio_samplerate |
int |
转码后音频采样率率 | N |
audio_channel |
int |
转码后音频通道数 | N |
filter |
string |
avfilter滤镜参数,用法与ffmpeg -vf 参数一致 | N |
filter_threads |
int |
视频滤镜线程数 | |
force |
bool |
是否强制转码,强制转码时不管目标编码是否一致,默认否 | N |
decoder_threads |
int |
解码线程数,默认2个,最大32个,音频强制为1个 | N |
encoder_threads |
int |
编码线程数,默认4个,最大32个,音频强制为1个 | N |
hw_decoder |
bool |
是否启用硬件解码器,默认启用 | N |
hw_encoder |
bool |
是否启用硬件编码器,默认启用 | N |
decoder_list |
string |
视频ffmpeg解码器列表,例如: h264_cuvid,h264_qsv | N |
encoder_list |
string |
视频ffmpeg编码器列表,例如: hevc_nvenc,hevc_qsv | N |
enable_hls |
bool |
转码后是否转换成hls-mpegts协议 | N |
enable_hls_fmp4 |
bool |
转码后是否转换成hls-fmp4协议 | N |
enable_mp4 |
bool |
转码后是否允许mp4录制 | N |
enable_rtsp |
bool |
转码后是否转rtsp协议 | N |
enable_rtmp |
bool |
转码后是否转rtmp/flv协议 | N |
enable_ts |
bool |
转码后是否转http-ts/ws-ts协议 | N |
enable_fmp4 |
bool |
转码后是否转http-fmp4/ws-fmp4协议 | N |
hls_demand |
bool |
转码后该协议是否有人观看才生成 | N |
rtsp_demand |
bool |
转码后该协议是否有人观看才生成 | N |
rtmp_demand |
bool |
转码后该协议是否有人观看才生成 | N |
ts_demand |
bool |
转码后该协议是否有人观看才生成 | N |
fmp4_demand |
bool |
转码后该协议是否有人观看才生成 | N |
enable_audio |
bool |
转码后转协议时是否开启音频 | N |
add_mute_audio |
bool |
转码后无音频是否添加静音aac音频 | N |
mp4_save_path |
string |
转码后mp4录制文件保存根目录,置空使用默认 | N |
mp4_max_second |
int |
转码后mp4录制切片大小,单位秒 | N |
mp4_as_player |
bool |
转码后MP4录制是否当作观看者参与播放人数计数 | N |
hls_save_path |
string |
转码后hls文件保存保存根目录,置空使用默认 | N |
modify_stamp |
int |
转码后该流是否开启时间戳覆盖(0:绝对时间戳/1:系统时间戳/2:相对时间戳) | N |
auto_close |
bool |
转码后无人观看是否自动关闭流(不触发无人观看hook) | N |
-
响应:
{ "code" : 0, "msg" : "success" }
3.4 使用http api获取转码信息
- 请求接口:/index/api/getMediaInfo
- 请求回复:请查看
transcode字段
{
"aliveSecond": 88,
"app": "live",
"bytesSpeed": 330246,
"code": 0,
"createStamp": 1691902256,
"isRecordingHLS": true,
"isRecordingMP4": false,
"originSock": {
"identifier": "2-51",
"local_ip": "192.168.31.101",
"local_port": 8000,
"peer_ip": "192.168.31.101",
"peer_port": 61801
},
"originType": 8,
"originTypeStr": "rtc_push",
"originUrl": "rtc://127.0.0.1/live/test?app=live&stream=test&type=push&session=1-50",
"readerCount": 0,
"schema": "rtsp",
"stream": "test",
"totalReaderCount": 0,
"tracks": [
{
"codec_id": 0,
"codec_id_name": "H264",
"codec_type": 0,
"fps": 30.0,
"frames": 2648,
"gop_interval_ms": 2012,
"gop_size": 60,
"height": 556,
"key_frames": 51,
"loss": 0.0,
"ready": true,
"width": 990
},
{
"channels": 1,
"codec_id": 4,
"codec_id_name": "PCMU",
"codec_type": 1,
"frames": 4434,
"loss": 0.0,
"ready": true,
"sample_bit": 16,
"sample_rate": 8000
}
],
"transcode": [
{
"name": "codec",
// 转码名称
"setting": {
// 转码配置信息
"adecoder_threads": 1,
// 音频解码器线程数
"aencoder_threads": 1,
// 音频编码器线程数
"hw_decoder": true,
// 启动硬件解码器
"hw_encoder": true,
// 启动硬件编码器
"target_acodec": "mpeg4-generic",
// 目标音频编码格式
"target_vcodec": "H265",
// 目标视频编码格式
"vdecoder_threads": 4,
// 视频解码器线程数
"vencoder_threads": 8,
// 视频编码器线程数
"force": false,
// 是否强制转码
"filter": "",
// 滤镜参数
"decoder_list": [
"h264_cuvid",
"h264_qsv"
],
// 解码器列表
"encoder_list": [
"hevc_nvenc",
"hevc_qsv"
]
// 编码器列表
},
"adec": "pcm_mulaw",
// 音频解码器名称
"aenc": "aac",
// 音频编码器名称
"aenc_ctx": {
// 音频AVCodecContext信息
"bit_rate": 32000,
// 比特率
"channels": 1,
// 通道数
"frame_number": 4055,
// 已编码帧数
"frame_size": 1024,
// 每帧采样数
"sample_fmt": "fltp",
// 音频编码输入格式
"sample_rate": 48000
// 编码器采样率
},
"vdec": "h264",
// 视频解码器名称
"venc": "hevc_videotoolbox",
// 视频编码器名称
"venc_ctx": {
// 视频AVCodecContext信息
"bit_rate": 1000000,
// 比特率
"fps": 20,
// 帧率
"frame_number": 2595,
// 已编码帧数
"gop": 60,
// gop大小
"has_b_frames": 0,
// 是否编码b帧
"height": 556,
// 视频高度
"pix_fmt": "nv12",
// 编码器输入图片格式
"width": 990
// 视频宽度
}
}
],
"vhost": "__defaultVhost__"
}