【视频转码】基于ZLMediakit的视频转码技术概述

小明 2025-04-29 23:03:22 6

一、概述

zlmediakit pro版本支持基于ffmpeg的转码能力,在开源版本强大功能的基础上,新增支持如下能力:

  • 1、音视频间任意转码(包括h265/h264/opus/g711/aac等)。
  • 2、基于配置文件的转码,支持设置比特率,codec类型等参数。
  • 3、基于http api的动态增减转码,支持设置比特率,分辨率倍数,codec类型、滤镜等参数。
  • 4、支持硬件、软件自适应转码。
  • 5、支持按需转码,有人观看才转码。
  • 6、支持负载过高时,转码主动降低帧率且不花屏。
  • 7、支持滤镜,支持添加osd文本以及logo角标等能力。

    二、转码实现原理

    • 视频转码原理

    • 音频转码原理

      三、使用方法

      目前zlmediakit pro转码能力支持两种使用方式,第一种是基于配置文件方式,在设置好配置文件后,所有流都支持转码为目标编码格式直播流,第二种模式基于http api方式,此方式更灵活,功能强大,可以指定更多转码相关参数。

      3.1 基于配置文件的转码

      [transcode]
      #转码stream_id后缀,为空时关闭转码
      suffix=
      #默认转码视频目标codec,支持H264/H265/JPEG/copy 
      vcodec=H264
      #默认转码音频目标codec,支持mpeg4-generic/PCMA/PCMU/opus/copy
      acodec=mpeg4-generic
      #是否开启ffmpeg日志
      enable_ffmpeg_log=0
      # 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
      

      在上述配置文件中,如果用户配置好suffix,那么zlmediakit将统一把所有直播流转码为目标编码格式,用户通过访问新的流地址即可确保为预期编码格式视频。

      例如源视频地址为:rtmp://127.0.0.1/live/test, 那么转码后地址即为:rtmp://127.0.0.1/live/test_H

      当配置文件修改为suffix=null时,转码后流会直接替换原始流(不会有_suffix后缀);替换模式下,建议rtsp.directProxy/rtmp.directProxy都设置为0。

      如果源视频编码格式与目标编码格式一致,那么zlmediakit为了确保性能最优,将直接拷贝流数据(不会编码)。

      基于配置文件方式的转码使用最简单,可以使用于安防行业H265视频无法webrtc/mse播放的场景。

      3.2 基于http api的转码

      zlmediakit同时还提供基于http api的转码方式,这种方式支持的功能更强大,使用更灵活,同时支持一个流转码成多个目标流(比如说不同分辨率的场景)。

      • 请求地址:/index/api/setupTranscode

      • 请求参数:

        参数参数类型释意是否必选
        secretstringapi操作密钥(配置文件配置)Y
        vhoststring流的虚拟主机,例如__defaultVhost__Y
        appstring流的应用名,例如liveY
        streamstring流的id名,例如testY
        namestring转码名(后缀),功能类似配置文件transcode.suffixY
        addint1:添加转码; 0: 删除转码Y
        video_codecstring视频转码的codec,支持H264/H265/JPEG/copyY
        video_bitrateint转码后视频的比特率Y
        video_scalefloat转码视频宽高拉伸比例,取值范围0.1~10Y
        audio_codecstring音频转码codec,支持mpeg4-generic/PCMA/PCMU/opus/copyY
        audio_bitrateint转码后音频比特率Y
        audio_samplerateint转码后音频采样率率Y
        filterstringavfilter滤镜参数,用法与ffmpeg -vf 参数一致Y
        forcebool是否强制转码,强制转码时不管目标编码是否一致,默认否N
        decoder_threadsint解码线程数,默认2个,最大16个,音频强制为1个N
        encoder_threadsint编码线程数,默认4个,最大16个,音频强制为1个N
        hw_decoderbool是否启用硬件解码器,默认启用N
        hw_encoderbool是否启用硬件编码器,默认启用N
        decoder_liststring视频ffmpeg解码器列表,例如: h264_cuvid,h264_qsvN
        encoder_liststring视频ffmpeg编码器列表,例如: hevc_nvenc,hevc_qsvN
        gpu_indexint硬件编解码gpu索引号,默认0N
        enable_hlsbool转码后是否转换成hls-mpegts协议N
        enable_hls_fmp4bool转码后是否转换成hls-fmp4协议N
        enable_mp4bool转码后是否允许mp4录制N
        enable_rtspbool转码后是否转rtsp协议N
        enable_rtmpbool转码后是否转rtmp/flv协议N
        enable_tsbool转码后是否转http-ts/ws-ts协议N
        enable_fmp4bool转码后是否转http-fmp4/ws-fmp4协议N
        hls_demandbool转码后该协议是否有人观看才生成N
        rtsp_demandbool转码后该协议是否有人观看才生成N
        rtmp_demandbool转码后该协议是否有人观看才生成N
        ts_demandbool转码后该协议是否有人观看才生成N
        fmp4_demandbool转码后该协议是否有人观看才生成N
        enable_audiobool转码后转协议时是否开启音频N
        add_mute_audiobool转码后无音频是否添加静音aac音频N
        mp4_save_pathstring转码后mp4录制文件保存根目录,置空使用默认N
        mp4_max_secondint转码后mp4录制切片大小,单位秒N
        mp4_as_playerbool转码后MP4录制是否当作观看者参与播放人数计数N
        hls_save_pathstring转码后hls文件保存保存根目录,置空使用默认N
        modify_stampint转码后该流是否开启时间戳覆盖(0:绝对时间戳/1:系统时间戳/2:相对时间戳)N
        auto_closebool转码后无人观看是否自动关闭流(不触发无人观看hook)N
      • 响应:

        {
           "code" : 0,
           "msg" : "success"
        }
        

        3.3 使用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__"
          }
          

          技术交流QQ群: 1033175645

The End
微信