Initial commit: Null DRM Official
Capture, decrypt, and restream toolkit with compiled-in app modules (RTE, TG4, BBC), on-device MITM proxy, streamd control plane, and www. BBC module.yaml is published (clear streams); other module values stay local.
This commit is contained in:
commit
2fa8f2435f
121 changed files with 17802 additions and 0 deletions
118
apps/agent/internal/client/client.go
Normal file
118
apps/agent/internal/client/client.go
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
Token string
|
||||
HTTP *http.Client
|
||||
UserAgent string
|
||||
}
|
||||
|
||||
func New(baseURL, token string) *Client {
|
||||
return &Client{
|
||||
BaseURL: strings.TrimRight(baseURL, "/"),
|
||||
Token: token,
|
||||
HTTP: &http.Client{Timeout: 30 * time.Second},
|
||||
UserAgent: "drm-agent/1.0",
|
||||
}
|
||||
}
|
||||
|
||||
type Stream struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Title string `json:"title"`
|
||||
App string `json:"app"`
|
||||
Channel string `json:"channel"`
|
||||
MPD string `json:"mpd"`
|
||||
Key string `json:"key"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Health string `json:"health"`
|
||||
LastError string `json:"last_error"`
|
||||
PlaylistAgeS float64 `json:"playlist_age_s"`
|
||||
ClaimedBy string `json:"claimed_by"`
|
||||
}
|
||||
|
||||
type Credentials struct {
|
||||
MPD string `json:"mpd"`
|
||||
Key string `json:"key"`
|
||||
PSSH string `json:"pssh,omitempty"`
|
||||
Auth string `json:"auth,omitempty"`
|
||||
PID string `json:"pid,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Client) Health() error {
|
||||
_, err := c.do(http.MethodGet, "/api/health", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) ListStreams() ([]Stream, error) {
|
||||
body, err := c.do(http.MethodGet, "/api/streams", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var wrap struct {
|
||||
Streams []Stream `json:"streams"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &wrap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return wrap.Streams, nil
|
||||
}
|
||||
|
||||
func (c *Client) Claim(id int64, agentID string, ttlSec int) error {
|
||||
payload := map[string]any{"agent_id": agentID, "ttl_sec": ttlSec}
|
||||
_, err := c.do(http.MethodPost, fmt.Sprintf("/api/streams/%d/claim", id), payload)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) ReleaseClaim(id int64, agentID string) error {
|
||||
payload := map[string]any{"agent_id": agentID}
|
||||
_, err := c.do(http.MethodPost, fmt.Sprintf("/api/streams/%d/claim/release", id), payload)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) PostCredentials(id int64, cred Credentials) error {
|
||||
_, err := c.do(http.MethodPost, fmt.Sprintf("/api/streams/%d/credentials", id), cred)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) do(method, path string, payload any) ([]byte, error) {
|
||||
var rdr io.Reader
|
||||
if payload != nil {
|
||||
b, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rdr = bytes.NewReader(b)
|
||||
}
|
||||
req, err := http.NewRequest(method, c.BaseURL+path, rdr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if payload != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("User-Agent", c.UserAgent)
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
}
|
||||
resp, err := c.HTTP.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("%s %s: %s — %s", method, path, resp.Status, strings.TrimSpace(string(body)))
|
||||
}
|
||||
return body, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue