@wave-av/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +178 -0
- package/dist/index.js +4034 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
- package/templates/api-integration/.env.example +2 -0
- package/templates/api-integration/package.json +17 -0
- package/templates/api-integration/src/index.ts +24 -0
- package/templates/blank/.env.example +1 -0
- package/templates/blank/package.json +17 -0
- package/templates/blank/src/index.ts +16 -0
- package/templates/multi-camera/.env.example +1 -0
- package/templates/multi-camera/package.json +17 -0
- package/templates/multi-camera/src/index.ts +49 -0
- package/templates/podcast/.env.example +1 -0
- package/templates/podcast/package.json +17 -0
- package/templates/podcast/src/index.ts +33 -0
- package/templates/srt-contribution/.env.example +1 -0
- package/templates/srt-contribution/package.json +17 -0
- package/templates/srt-contribution/src/index.ts +29 -0
- package/templates/studio-plugin/.env.example +2 -0
- package/templates/studio-plugin/package.json +17 -0
- package/templates/studio-plugin/src/index.ts +32 -0
- package/templates/webhook-handler/.env.example +3 -0
- package/templates/webhook-handler/package.json +19 -0
- package/templates/webhook-handler/src/index.ts +52 -0
- package/templates/webrtc-demo/.env.example +1 -0
- package/templates/webrtc-demo/package.json +17 -0
- package/templates/webrtc-demo/src/index.ts +31 -0
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wave-av/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "WAVE CLI - Command-line interface for the WAVE streaming platform",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"wave": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"templates",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup",
|
|
17
|
+
"dev": "tsup --watch",
|
|
18
|
+
"type-check": "tsc --noEmit",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"lint": "eslint src/",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"wave",
|
|
26
|
+
"cli",
|
|
27
|
+
"streaming",
|
|
28
|
+
"video",
|
|
29
|
+
"broadcast",
|
|
30
|
+
"production"
|
|
31
|
+
],
|
|
32
|
+
"author": "WAVE Inc. <cli@wave.online>",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/wave-av/wave-surfer-connect.git",
|
|
37
|
+
"directory": "packages/cli"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://docs.wave.online/cli",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/wave-av/wave-surfer-connect/issues"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"registry": "https://registry.npmjs.org/"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@wave-av/sdk": "workspace:*",
|
|
52
|
+
"chalk": "^5.4.1",
|
|
53
|
+
"cli-table3": "^0.6.5",
|
|
54
|
+
"commander": "^13.1.0",
|
|
55
|
+
"conf": "^13.1.0",
|
|
56
|
+
"inquirer": "^12.3.2",
|
|
57
|
+
"keytar": "^7.9.0",
|
|
58
|
+
"open": "^10.1.0",
|
|
59
|
+
"ora": "^8.2.0",
|
|
60
|
+
"ws": "^8.18.0",
|
|
61
|
+
"yaml": "^2.7.0",
|
|
62
|
+
"zod": "3.25.76"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@sentry/node": "^9.4.0",
|
|
66
|
+
"@types/inquirer": "^9.0.7",
|
|
67
|
+
"@types/node": "^22.13.0",
|
|
68
|
+
"@types/ws": "^8.5.14",
|
|
69
|
+
"tsup": "^8.0.0",
|
|
70
|
+
"typescript": "^5.9.3",
|
|
71
|
+
"vitest": "^4.0.16"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-api-integration",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.9.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Wave } from "@wave/sdk";
|
|
2
|
+
|
|
3
|
+
const wave = new Wave({
|
|
4
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// List your streams
|
|
9
|
+
const streams = await wave.pipeline.list({ limit: 10 });
|
|
10
|
+
console.log(`Found ${streams.data.length} streams\n`);
|
|
11
|
+
|
|
12
|
+
for (const stream of streams.data) {
|
|
13
|
+
console.log(` ${stream.id} - ${stream.title} (${stream.status})`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Get organization usage
|
|
17
|
+
const usage = await wave.billing.getUsage();
|
|
18
|
+
console.log(`\nCurrent usage:`);
|
|
19
|
+
console.log(` Streams: ${usage.streams_count}`);
|
|
20
|
+
console.log(` Storage: ${usage.storage_gb}GB`);
|
|
21
|
+
console.log(` Bandwidth: ${usage.bandwidth_gb}GB`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
main().catch(console.error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
WAVE_API_KEY=wave_live_your_api_key_here
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-project",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.9.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Wave } from "@wave/sdk";
|
|
2
|
+
|
|
3
|
+
const wave = new Wave({
|
|
4
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
const streams = await wave.pipeline.list();
|
|
9
|
+
console.log(`Found ${streams.data.length} streams`);
|
|
10
|
+
|
|
11
|
+
for (const stream of streams.data) {
|
|
12
|
+
console.log(`- ${stream.title} (${stream.status})`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
main().catch(console.error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
WAVE_API_KEY=wave_live_your_api_key_here
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-multi-camera",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.9.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Wave } from "@wave/sdk";
|
|
2
|
+
|
|
3
|
+
const wave = new Wave({
|
|
4
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// Create a multi-camera production session
|
|
9
|
+
const production = await wave.studio.create({
|
|
10
|
+
title: "Multi-Camera Production",
|
|
11
|
+
description: "Multi-source production demo",
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
console.log(`Production created: ${production.id}`);
|
|
15
|
+
|
|
16
|
+
// Add camera sources
|
|
17
|
+
const cam1 = await wave.studio.addSource(production.id, {
|
|
18
|
+
type: "camera",
|
|
19
|
+
label: "Camera 1 - Wide",
|
|
20
|
+
url: "rtmp://localhost/live/cam1",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const cam2 = await wave.studio.addSource(production.id, {
|
|
24
|
+
type: "camera",
|
|
25
|
+
label: "Camera 2 - Close-up",
|
|
26
|
+
url: "rtmp://localhost/live/cam2",
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
console.log(`Sources added: ${cam1.id}, ${cam2.id}`);
|
|
30
|
+
|
|
31
|
+
// Create scenes
|
|
32
|
+
const fullscreen = await wave.studio.createScene(production.id, {
|
|
33
|
+
name: "Fullscreen",
|
|
34
|
+
layout: "single",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const sideBySide = await wave.studio.createScene(production.id, {
|
|
38
|
+
name: "Side by Side",
|
|
39
|
+
layout: "split",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
console.log(`Scenes created: ${fullscreen.id}, ${sideBySide.id}`);
|
|
43
|
+
|
|
44
|
+
// Start production
|
|
45
|
+
await wave.studio.start(production.id);
|
|
46
|
+
console.log("Production started!");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
main().catch(console.error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
WAVE_API_KEY=wave_live_your_api_key_here
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-podcast",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.9.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Wave } from "@wave/sdk";
|
|
2
|
+
|
|
3
|
+
const wave = new Wave({
|
|
4
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// Create a podcast episode recording
|
|
9
|
+
const stream = await wave.pipeline.create({
|
|
10
|
+
title: "Podcast Episode Recording",
|
|
11
|
+
protocol: "webrtc",
|
|
12
|
+
description: "Audio-focused recording session",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
console.log(`Recording session created: ${stream.id}`);
|
|
16
|
+
|
|
17
|
+
// Start recording
|
|
18
|
+
await wave.pipeline.start(stream.id);
|
|
19
|
+
const recording = await wave.pipeline.startRecording(stream.id);
|
|
20
|
+
console.log(`Recording started: ${recording.id}`);
|
|
21
|
+
|
|
22
|
+
// After recording, generate transcription
|
|
23
|
+
console.log("Generating transcription...");
|
|
24
|
+
const transcription = await wave.transcribe.create({
|
|
25
|
+
recording_id: recording.id,
|
|
26
|
+
language: "en",
|
|
27
|
+
model: "enhanced",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log(`Transcription: ${transcription.id} (${transcription.status})`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
main().catch(console.error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
WAVE_API_KEY=wave_live_your_api_key_here
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-srt-contribution",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.9.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Wave } from "@wave/sdk";
|
|
2
|
+
|
|
3
|
+
const wave = new Wave({
|
|
4
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// Create an SRT contribution stream (low-latency ingest)
|
|
9
|
+
const stream = await wave.pipeline.create({
|
|
10
|
+
title: "SRT Contribution Feed",
|
|
11
|
+
protocol: "srt",
|
|
12
|
+
description: "Low-latency SRT ingest for remote contribution",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
console.log(`SRT stream created: ${stream.id}`);
|
|
16
|
+
console.log(`SRT ingest URL: ${stream.ingest_url}`);
|
|
17
|
+
console.log(`Use this URL in your SRT encoder (OBS, vMix, etc.)`);
|
|
18
|
+
|
|
19
|
+
// Start accepting connections
|
|
20
|
+
const started = await wave.pipeline.start(stream.id);
|
|
21
|
+
console.log(`Status: ${started.status}`);
|
|
22
|
+
|
|
23
|
+
// Monitor health
|
|
24
|
+
const health = await wave.pipeline.getHealth(stream.id);
|
|
25
|
+
console.log(`Bitrate: ${health.bitrate_kbps}kbps`);
|
|
26
|
+
console.log(`Latency: ${health.latency_ms}ms`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-studio-plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.9.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Wave } from "@wave/sdk";
|
|
2
|
+
|
|
3
|
+
const wave = new Wave({
|
|
4
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// Register a custom Studio plugin
|
|
9
|
+
const plugin = await wave.studio.registerPlugin({
|
|
10
|
+
name: "My Custom Plugin",
|
|
11
|
+
description: "A custom production plugin for WAVE Studio",
|
|
12
|
+
version: "1.0.0",
|
|
13
|
+
capabilities: ["overlay", "transition"],
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
console.log(`Plugin registered: ${plugin.id}`);
|
|
17
|
+
|
|
18
|
+
// Listen for Studio events
|
|
19
|
+
const connection = await wave.studio.connect(plugin.id);
|
|
20
|
+
|
|
21
|
+
connection.on("scene.switch", (scene) => {
|
|
22
|
+
console.log(`Scene switched to: ${scene.name}`);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
connection.on("source.added", (source) => {
|
|
26
|
+
console.log(`New source added: ${source.name} (${source.type})`);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
console.log("Studio plugin connected and listening for events...");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-webhook-handler",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0",
|
|
12
|
+
"express": "^4.21.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/express": "^5.0.0",
|
|
16
|
+
"tsx": "^4.0.0",
|
|
17
|
+
"typescript": "^5.9.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { Wave } from "@wave/sdk";
|
|
3
|
+
|
|
4
|
+
const wave = new Wave({
|
|
5
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const app = express();
|
|
9
|
+
|
|
10
|
+
// WAVE sends JSON payloads for webhook events
|
|
11
|
+
app.use(express.json());
|
|
12
|
+
|
|
13
|
+
// Verify webhook signatures to ensure requests are from WAVE
|
|
14
|
+
app.post("/webhooks/wave", async (req, res) => {
|
|
15
|
+
const signature = req.headers["wave-signature"] as string | undefined;
|
|
16
|
+
const secret = process.env.WAVE_WEBHOOK_SECRET;
|
|
17
|
+
|
|
18
|
+
if (!signature || !secret) {
|
|
19
|
+
res.status(401).json({ error: "Missing signature or secret" });
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const isValid = wave.webhooks.verify(req.body, signature, secret);
|
|
24
|
+
if (!isValid) {
|
|
25
|
+
res.status(401).json({ error: "Invalid signature" });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const event = req.body;
|
|
30
|
+
console.log(`Received event: ${event.type}`);
|
|
31
|
+
|
|
32
|
+
switch (event.type) {
|
|
33
|
+
case "stream.started":
|
|
34
|
+
console.log(`Stream ${event.data.stream_id} started`);
|
|
35
|
+
break;
|
|
36
|
+
case "stream.ended":
|
|
37
|
+
console.log(`Stream ${event.data.stream_id} ended`);
|
|
38
|
+
break;
|
|
39
|
+
case "recording.ready":
|
|
40
|
+
console.log(`Recording ready: ${event.data.recording_url}`);
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
console.log(`Unhandled event type: ${event.type}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
res.json({ received: true });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const PORT = process.env.PORT ?? 3000;
|
|
50
|
+
app.listen(PORT, () => {
|
|
51
|
+
console.log(`Webhook server listening on port ${PORT}`);
|
|
52
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
WAVE_API_KEY=wave_live_your_api_key_here
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wave-webrtc-demo",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npx tsx src/index.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wave/sdk": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.9.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Wave } from "@wave/sdk";
|
|
2
|
+
|
|
3
|
+
const wave = new Wave({
|
|
4
|
+
apiKey: process.env.WAVE_API_KEY!,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// Create a WebRTC stream
|
|
9
|
+
const stream = await wave.pipeline.create({
|
|
10
|
+
title: "WebRTC Demo Stream",
|
|
11
|
+
protocol: "webrtc",
|
|
12
|
+
description: "Created with WAVE CLI",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
console.log(`Stream created: ${stream.id}`);
|
|
16
|
+
console.log(`Ingest URL: ${stream.ingest_url}`);
|
|
17
|
+
console.log(`Playback URL: ${stream.playback_url}`);
|
|
18
|
+
|
|
19
|
+
// Start the stream
|
|
20
|
+
const started = await wave.pipeline.start(stream.id);
|
|
21
|
+
console.log(`Stream status: ${started.status}`);
|
|
22
|
+
|
|
23
|
+
// Wait for it to go live
|
|
24
|
+
const live = await wave.pipeline.waitForLive(stream.id, {
|
|
25
|
+
timeout: 60000,
|
|
26
|
+
pollInterval: 2000,
|
|
27
|
+
});
|
|
28
|
+
console.log(`Stream is live! Viewers: ${live.viewer_count}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
main().catch(console.error);
|