Files
nginx-stream-server/internal/mtx/mtx.go
jbergner 42e484c47c
Some checks failed
release-tag / release-image (push) Failing after 1m2s
staging
2025-09-21 14:58:13 +02:00

82 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package mtx
import (
"context"
"fmt"
"io"
"net/http"
"time"
"github.com/goccy/go-json"
)
// Minimaler Client für MediaMTX Control API v3
// Standard-Ports: API :9997, HLS :8888, RTMP :1935
type Client struct {
BaseURL string // z.B. http://127.0.0.1:9997
HTTP *http.Client
User string
Pass string
}
type PathsList struct {
Items []PathItem `json:"items"`
}
type PathItem struct {
Name string `json:"name"`
// publisher kann nil sein, wenn keiner sendet
Publisher *SessionRef `json:"publisher"`
// readSessions sind aktive Zuschauer
ReadSessions []SessionRef `json:"readSessions"`
// BytesIn/Out können je nach Version fehlen deshalb optional halten
BytesReceived *int64 `json:"bytesReceived,omitempty"`
BytesSent *int64 `json:"bytesSent,omitempty"`
}
type SessionRef struct {
ID string `json:"id"`
// Bitrate und weitere Felder variieren je nach Version, wir zeigen defensiv nur das Nötigste an
}
func (c *Client) do(ctx context.Context, method, path string, out any) error {
if c.HTTP == nil {
c.HTTP = &http.Client{Timeout: 5 * time.Second}
}
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, nil)
if err != nil {
return err
}
if c.User != "" || c.Pass != "" {
req.SetBasicAuth(c.User, c.Pass)
}
resp, err := c.HTTP.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
b, _ := io.ReadAll(resp.Body)
return fmt.Errorf("mtx api %s: %s", resp.Status, string(b))
}
return json.NewDecoder(resp.Body).Decode(out)
}
func (c *Client) Paths(ctx context.Context) (*PathsList, error) {
var out PathsList
err := c.do(ctx, http.MethodGet, "/v3/paths/list", &out)
if err != nil {
return nil, err
}
return &out, nil
}
func (p PathItem) Live() bool { return p.Publisher != nil }
func (p PathItem) Viewers() int { return len(p.ReadSessions) }
// HLS-URL Form: http://<host>:8888/<path> (Playlist wird automatisch geliefert)
func HLSURL(publicHost, path string) string {
return fmt.Sprintf("%s/%s", publicHost, path)
}