staging
Some checks failed
release-tag / release-image (push) Failing after 1m2s

This commit is contained in:
2025-09-21 14:58:13 +02:00
parent 536dd3d416
commit 42e484c47c
12 changed files with 566 additions and 1 deletions

81
internal/mtx/mtx.go Normal file
View File

@@ -0,0 +1,81 @@
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)
}