This commit is contained in:
81
internal/mtx/mtx.go
Normal file
81
internal/mtx/mtx.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user