You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用gortsplib/v4实现RTSP摘要认证的问题求助

解决gortsplib/v4中RTSP摘要认证的问题

问题1:获取401响应头及错误详情

调用client.Describe()返回的错误若为*base.Error类型,内部包含完整响应对象,可通过类型断言提取响应头:

desc, resp, err := client.Describe(u)
if err != nil {
    // 断言为base.Error类型以获取完整响应
    if baseErr, ok := err.(*base.Error); ok {
        // 打印摘要认证所需的WWW-Authenticate头
        fmt.Println("WWW-Authenticate:", baseErr.Response.Header.Get("WWW-Authenticate"))
        // 打印全部响应头
        fmt.Println("响应头:", baseErr.Response.Header)
    } else {
        fmt.Println("普通错误:", err)
    }
    return
}

注意你的代码存在流程错误:Describe后直接调用client.Close()会导致后续SetupAll、Play操作失效,必须移除提前关闭client的代码。

问题2:添加摘要认证信息到请求

gortsplib/v4已内置摘要认证自动处理逻辑,无需手动通过net包生成MD5摘要,以下两种方式任选:

方式1:提前设置认证凭据

启动client前直接配置用户名和密码,库会自动处理401重试及摘要生成:

client := &gortsplib.Client{}
// 设置认证凭据
client.SetCredentials("你的用户名", "你的密码")

设置后,当首次请求返回401时,client会自动生成认证头并重试请求,无需手动发起两次DESCRIBE。

方式2:手动处理认证流程(自定义场景)

若需手动控制认证步骤,按以下流程操作:

  1. 发送首次DESCRIBE请求,获取401响应的WWW-Authenticate头
  2. 解析头信息得到nonce、realm等参数
  3. 生成摘要认证的Authorization头
  4. 在后续请求中携带该头

示例代码片段:

// 首次发送DESCRIBE请求,获取401响应
desc, resp, err := client.Describe(u)
if err != nil {
    baseErr, ok := err.(*base.Error)
    if !ok || baseErr.Response.StatusCode != base.StatusUnauthorized {
        panic(err)
    }

    // 解析WWW-Authenticate头参数
    authHeader := baseErr.Response.Header.Get("WWW-Authenticate")
    authParams, err := base.ParseAuthenticateHeader(authHeader)
    if err != nil {
        panic(err)
    }

    // 生成Authorization头
    authValue := base.GenerateAuthorizationHeader(
        "DESCRIBE",
        u,
        authParams,
        "你的用户名",
        "你的密码",
    )

    // 构造带认证头的请求选项
    reqOpts := &base.RequestOptions{
        Header: base.Header{
            "Authorization": {authValue},
        },
    }

    // 二次发送DESCRIBE请求
    desc, resp, err = client.Describe(u, reqOpts)
    if err != nil {
        panic(err)
    }
}

修正后的完整代码示例

package main

import (
    "fmt"
    "log"

    "github.com/bluenviron/gortsplib/v4"
    "github.com/bluenviron/gortsplib/v4/pkg/base"
    "github.com/bluenviron/gortsplib/v4/pkg/description"
    "github.com/bluenviron/gortsplib/v4/pkg/format"
    "github.com/bluenviron/gortsplib/v4/pkg/rtp"
    "github.com/pion/rtcp"
)

func main() {
    // 解析RTSP地址
    u, err := base.ParseURL("rtsp://<ip>:<port>/<path>")
    if err != nil {
        panic(err)
    }

    // 初始化客户端并设置认证信息
    client := &gortsplib.Client{}
    client.SetCredentials("你的用户名", "你的密码")

    // 连接RTSP服务器
    err = client.Start(u.Scheme, u.Host)
    if err != nil {
        panic(err)
    }
    defer client.Close()

    // 获取媒体描述
    desc, _, err := client.Describe(u)
    if err != nil {
        panic(err)
    }

    // 建立所有媒体流连接
    err = client.SetupAll(desc.BaseURL, desc.Medias)
    if err != nil {
        panic(err)
    }

    // 监听RTP数据包
    client.OnPacketRTPAny(func(medi *description.Media, forma format.Format, pkt *rtp.Packet) {
        log.Printf("收到RTP包,媒体索引:%d", medi.Index)
    })

    // 监听RTCP数据包
    client.OnPacketRTCPAny(func(medi *description.Media, pkt rtcp.Packet) {
        log.Printf("收到RTCP包,媒体索引:%d,类型:%T", medi.Index, pkt)
    })

    // 开始播放流
    _, err = client.Play(nil)
    if err != nil {
        panic(err)
    }

    // 阻塞等待客户端运行(直到出现致命错误)
    panic(client.Wait())
}

内容的提问来源于stack exchange,提问作者Walter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:34:53