82 lines
2.0 KiB
Go
82 lines
2.0 KiB
Go
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)
|
||
}
|