Skip to content

undefined error=streams: user/pass not provided caller=github.com/AlexxIT/go2rtc/internal/hls/hls.go:76 #31

Description

@yur1us

I'm using zonemindere v1.38.1 with go2rtc version: 1.9.14
GO2RTC_PATH
http://127.0.0.1:1984/api
/etc/go2rtc.yml

api:
  listen: "127.0.0.1:1984"
rtsp:
  listen: "127.0.0.1:8554"

streams:
  3_ZoneMinderPrimary:
    - rtsp://127.0.0.1:2000/monitor3
  3_CameraDirectPrimary:
    - rtsp://user:pass@172.20.224.66:554/Streaming/Channels/101
  3_CameraDirectSecondary:
    - rtsp://user:pass@172.20.224.66:554/Streaming/Channels/102
  "3":
    - rtsp://127.0.0.1:2000/monitor3

i made proxy with nginx to go2rtc

map $cookie_hls_session $bypass_secure_link {
    "authorized"  "1";
    default       $secure_link;
}
    location /hls/ {
        secure_link $arg_md5,$arg_expires;
        secure_link_md5 "someSALThash$arg_expires";
        if ($bypass_secure_link = "") { return 403; }
        if ($bypass_secure_link = "0") { return 410; }
        add_header Set-Cookie "hls_session=authorized; Path=/hls/; Max-Age=7200; HttpOnly; SameSite=Strict";
        proxy_pass http://127.0.0.1:1984/;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

i use .py script to generate temp link hls stream for player

#!/usr/bin/env python3
import time
import hashlib
import base64
import sys

# ==================== SETTINGS ====================
SECRET = "someSALThash"

# External IP or domain of your ZoneMinder server
SERVER_IP = "******"

# The protected path configured in Nginx
URI = "/hls/api/stream.m3u8"

# URL expiration time in seconds (3600 = 1 hour)
TTL_SECONDS = 3600
# ===================================================

def generate_secure_url(monitor_id):
    # 1. Calculate the link expiration timestamp (current time + TTL)
    expires = int(time.time()) + TTL_SECONDS

    # 2. Construct the string for hashing exactly as Nginx secure_link_md5 expects:
    # secure_link_md5 "Secret$arg_expires";
    protected_string = f"{SECRET}{expires}".encode('utf-8')
    
    # 3. Calculate the binary MD5 hash
    md5_binary = hashlib.md5(protected_string).digest()

    # 4. Encode to URL-safe Base64 format (replacing + with -, / with _, and removing '=')
    md5_base64 = base64.urlsafe_b64encode(md5_binary).decode('utf-8').replace('=', '')

    # 5. Assemble the final URL, appending the camera identifier to the 'src' parameter
    final_url = f"http://{SERVER_IP}{URI}?src={monitor_id}&md5={md5_base64}&expires={expires}"
    return final_url, expires

if __name__ == "__main__":
    # If the monitor ID is passed as a CLI argument, use it; otherwise default to Monitor 3
    monitor = sys.argv[1] if len(sys.argv) > 1 else "3"

    url, exp_time = generate_secure_url(monitor)

    print("\n" + "="*60)
    print(f" SECURE URL FOR WEB PLAYER OR SMARTPHONE (ZM Monitor: {monitor})")
    print("="*60)
    print(url)
    print("="*60)
    print(f"Link is valid until: {time.ctime(exp_time)} (1 hour)\n")

on web server log is good
**** - - [16/Jun/2026:13:41:22 +0300] "GET /hls/api/stream.m3u8?src=3&md5=7fIds9YjOof2TLpleDbYKg&expires=1781610035 HTTP/1.1" 200 0 "http://****/hls/api/stream.m3u8?src=3&md5=7fIds9YjOof2TLpleDbYKg&expires=1781610035" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36" "-"
but at go2rtc:
undefined error=streams: user/pass not provided caller=github.com/AlexxIT/go2rtc/internal/hls/hls.go:76

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions