Skip to content

Commit 871f699

Browse files
Brandon Salzbergclaude
andcommitted
Use hosted API player assets for video playback
Local HTML files now load JS/CSS from the hosted API player at bs-api-player.console.itg.rhombussystems.com instead of using the inline dash.js CDN player. This gives full Rhombus player functionality (seekbar, events, bounding boxes, VOD, realtime). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 040c9fd commit 871f699

2 files changed

Lines changed: 50 additions & 25 deletions

File tree

cmd/alert.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ func runAlertPlay(cmd *cobra.Command, args []string) error {
210210
}
211211

212212
deviceUuid, _ := alert["deviceUuid"].(string)
213-
region := getAlertRegion(alert, "clipLocation")
214213
tsMs, _ := alert["timestampMs"].(float64)
215214
durSec, _ := alert["durationSec"].(float64)
216215

@@ -231,11 +230,7 @@ func runAlertPlay(cmd *cobra.Command, args []string) error {
231230
}
232231
federatedToken, _ := fedResp["federatedSessionToken"].(string)
233232

234-
clipMpdURL := fmt.Sprintf("%s/media/metadata/%s/%s/%s/clip.mpd",
235-
mediaBaseURL, deviceUuid, region, alertUuid)
236-
streamURL := clipMpdURL + "?x-auth-scheme=federated-token&x-auth-ft=" + federatedToken
237-
238-
htmlPath, err := generatePlayerHTML(fmt.Sprintf("%s — Alert", camName), streamURL)
233+
htmlPath, err := generateApiPlayerHTML(deviceUuid, camName, federatedToken)
239234
if err != nil {
240235
return fmt.Errorf("generating player: %w", err)
241236
}

cmd/live.go

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,29 +50,12 @@ func runLive(cmd *cobra.Command, args []string) error {
5050
return fmt.Errorf("no federated token returned")
5151
}
5252

53-
// Get media URIs
54-
mediaResp, err := client.APICall(cfg, "/api/camera/getMediaUris", map[string]any{
55-
"cameraUuid": cameraUUID,
56-
})
57-
if err != nil {
58-
return fmt.Errorf("getting media URIs: %w", err)
59-
}
60-
61-
mpdUri, _ := mediaResp["wanLiveMpdUri"].(string)
62-
if mpdUri == "" {
63-
return fmt.Errorf("no live MPD URI available for this camera")
64-
}
65-
66-
// Append federated token auth
67-
streamURL := mpdUri + "?x-auth-scheme=federated-token&x-auth-ft=" + federatedToken
68-
69-
// Generate HTML file
70-
htmlPath, err := generatePlayerHTML(cameraName, streamURL)
53+
// Generate local HTML that loads the hosted API player assets
54+
htmlPath, err := generateApiPlayerHTML(cameraUUID, cameraName, federatedToken)
7155
if err != nil {
7256
return fmt.Errorf("generating player: %w", err)
7357
}
7458

75-
// Open in browser
7659
openInBrowser("file://" + htmlPath)
7760

7861
fmt.Printf("Live stream opened in browser.\n")
@@ -317,3 +300,50 @@ func openInBrowser(url string) {
317300
}
318301
_ = cmd.Start()
319302
}
303+
304+
const apiPlayerAssetsBase = "https://bs-api-player.console.itg.rhombussystems.com/api"
305+
306+
func generateApiPlayerHTML(cameraUUID, cameraName, federatedToken string) (string, error) {
307+
tmpDir := filepath.Join(os.TempDir(), "rhombus-live")
308+
if err := os.MkdirAll(tmpDir, 0755); err != nil {
309+
return "", err
310+
}
311+
312+
htmlPath := filepath.Join(tmpDir, "player.html")
313+
314+
html := fmt.Sprintf(`<!DOCTYPE html>
315+
<html lang="en">
316+
<head>
317+
<meta charset="UTF-8" />
318+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
319+
<title>%s — Rhombus Player</title>
320+
<link rel="stylesheet" href="%s/assets/index-D66MeRQc.css" />
321+
<style>
322+
html, body, #root { height: 100%%; margin: 0; }
323+
</style>
324+
</head>
325+
<body>
326+
<div id="root" style="height: 100%%"></div>
327+
<script>
328+
// Inject player config before the app loads
329+
window.__RHOMBUS_API_PLAYER__ = {
330+
cameraUuid: "%s",
331+
cameraName: "%s",
332+
federatedToken: "%s",
333+
};
334+
// Rewrite location so the app's router matches /api/player/:cameraUuid
335+
history.replaceState(null, "", "/api/player/%s?ft=%s&name=%s");
336+
</script>
337+
<script type="module" src="%s/assets/index-CW-Rip9v.js"></script>
338+
</body>
339+
</html>`, cameraName, apiPlayerAssetsBase,
340+
cameraUUID, cameraName, federatedToken,
341+
cameraUUID, federatedToken, cameraName,
342+
apiPlayerAssetsBase)
343+
344+
if err := os.WriteFile(htmlPath, []byte(html), 0644); err != nil {
345+
return "", err
346+
}
347+
348+
return htmlPath, nil
349+
}

0 commit comments

Comments
 (0)