openvibers/openvibe.live Commits
finish-f1: Updated the Contracts status, corrected the five-table…
Changes
@@@ -5,7 +5,7 @@"runtime": "node 22, express, better-sqlite3, node-media-server, mediasoup; no build step","port": 3000,"domain": "openvibe.live (www, ingest, whip)",-- "contracts": "openvibe-contracts v0.71.0",++ "contracts": "openvibe-contracts v0.79.0","sdk": "openvibe-sdk v0.12.0","capabilities": ["live.chat_context.read",@@@ -21,7 +21,7 @@* kept rows point at nobody.** Never touched: the frozen tables (vods, clips, pastes, paste_likes, paste_comments, comments), which Media and-- * Community own and erase themselves. The six chat tables (channel_moderators, channel_moderation_settings, emotes,++ * Community own and erase themselves. The five chat tables (channel_moderators, channel_moderation_settings,* user_tags, chat_ai_summaries, chat_timeline_events) are OpenVibe.Chat's (roadmap T3) and erased by its eraser* (Chat server/chat/account-data.js), never here.*@@@ -61,6 +61,7 @@ assert.deepStrictEqual(manager._getCustomOverrides({ custom_encoder_preset: 'placonst fe = Manager.friendlyFfmpegError;assert.match(fe('rtmp://x: Server error: NetStream.Publish.BadName', 'twitch'), /Twitch rejected the stream key/);assert.match(fe('tcp://x: Connection refused', 'kick'), /Could not connect to Kick/);++assert.match(fe('tcp://x: Connection refused', 'custom'), /Could not connect to the destination/);assert.match(fe('Failed to resolve hostname live.example: Name or service not known', 'custom'), /resolve the ingest host/);assert.match(fe('gnutls: The TLS connection was non-properly terminated', 'youtube'), /TLS handshake/);assert.match(fe('av_interleaved_write_frame(): Broken pipe | End of file', 'twitch'), /closed the connection/);@@@ -112,11 +113,7 @@ manager.sessions.delete('1:9');manager._spawnFFmpeg(bad, ['-hide_banner', '-loglevel', 'warning', '-f', 'lavfi', '-i', 'testsrc=duration=1:size=64x64:rate=10', '-c:v', 'libx264', '-preset', 'ultrafast', '-f', 'flv', 'rtmp://127.0.0.1:1/live/k']);await new Promise((r) => bad.process.on('close', () => setTimeout(r, 50)));assert.strictEqual(bad.status, 'error');-- // The exact wording depends on how the environment fails the connection: a plain refused loopback-- // connect reads "Could not connect to the destination's ingest server", while a sandboxed/offline-- // run can surface an RTMP-level rejection for the same unreachable output. Both are friendly,-- // destination-scoped messages for an output that would not open — the strict refused-connection-- // mapping is asserted above (friendlyFfmpegError, 'Connection refused' → Kick).++ // FFmpeg can report either a refused connection or an RTMP rejection in restricted environments.assert.match(bad.lastError, /Could not connect to the destination|the destination rejected the stream key/, bad.lastError);assert.ok(bad.restartTimer, 'restart scheduled');assert.ok(bad.nextRestartAt > Date.now(), 'dashboard can count down to the retry');
@@ -5,7 +5,7 @@
@@ -5,7 +5,7 @@
"runtime": "node 22, express, better-sqlite3, node-media-server, mediasoup; no build step",
"runtime": "node 22, express, better-sqlite3, node-media-server, mediasoup; no build step",
"port": 3000,
"port": 3000,
"domain": "openvibe.live (www, ingest, whip)",
"domain": "openvibe.live (www, ingest, whip)",
- "contracts": "openvibe-contracts v0.71.0",
+ "contracts": "openvibe-contracts v0.79.0",
"sdk": "openvibe-sdk v0.12.0",
"sdk": "openvibe-sdk v0.12.0",
"capabilities": [
"capabilities": [
"live.chat_context.read",
"live.chat_context.read",
@@ -21,7 +21,7 @@
@@ -21,7 +21,7 @@
* kept rows point at nobody.
* kept rows point at nobody.
*
*
* Never touched: the frozen tables (vods, clips, pastes, paste_likes, paste_comments, comments), which Media and
* Never touched: the frozen tables (vods, clips, pastes, paste_likes, paste_comments, comments), which Media and
- * Community own and erase themselves. The six chat tables (channel_moderators, channel_moderation_settings, emotes,
+ * Community own and erase themselves. The five chat tables (channel_moderators, channel_moderation_settings,
* user_tags, chat_ai_summaries, chat_timeline_events) are OpenVibe.Chat's (roadmap T3) and erased by its eraser
* user_tags, chat_ai_summaries, chat_timeline_events) are OpenVibe.Chat's (roadmap T3) and erased by its eraser
* (Chat server/chat/account-data.js), never here.
* (Chat server/chat/account-data.js), never here.
*
*
@@ -61,6 +61,7 @@ assert.deepStrictEqual(manager._getCustomOverrides({ custom_encoder_preset: 'pla
@@ -61,6 +61,7 @@ assert.deepStrictEqual(manager._getCustomOverrides({ custom_encoder_preset: 'pla
const fe = Manager.friendlyFfmpegError;
const fe = Manager.friendlyFfmpegError;
assert.match(fe('rtmp://x: Server error: NetStream.Publish.BadName', 'twitch'), /Twitch rejected the stream key/);
assert.match(fe('rtmp://x: Server error: NetStream.Publish.BadName', 'twitch'), /Twitch rejected the stream key/);
assert.match(fe('tcp://x: Connection refused', 'kick'), /Could not connect to Kick/);
assert.match(fe('tcp://x: Connection refused', 'kick'), /Could not connect to Kick/);
+assert.match(fe('tcp://x: Connection refused', 'custom'), /Could not connect to the destination/);
assert.match(fe('Failed to resolve hostname live.example: Name or service not known', 'custom'), /resolve the ingest host/);
assert.match(fe('Failed to resolve hostname live.example: Name or service not known', 'custom'), /resolve the ingest host/);
assert.match(fe('gnutls: The TLS connection was non-properly terminated', 'youtube'), /TLS handshake/);
assert.match(fe('gnutls: The TLS connection was non-properly terminated', 'youtube'), /TLS handshake/);
assert.match(fe('av_interleaved_write_frame(): Broken pipe | End of file', 'twitch'), /closed the connection/);
assert.match(fe('av_interleaved_write_frame(): Broken pipe | End of file', 'twitch'), /closed the connection/);
@@ -112,11 +113,7 @@ manager.sessions.delete('1:9');
@@ -112,11 +113,7 @@ manager.sessions.delete('1:9');
manager._spawnFFmpeg(bad, ['-hide_banner', '-loglevel', 'warning', '-f', 'lavfi', '-i', 'testsrc=duration=1:size=64x64:rate=10', '-c:v', 'libx264', '-preset', 'ultrafast', '-f', 'flv', 'rtmp://127.0.0.1:1/live/k']);
manager._spawnFFmpeg(bad, ['-hide_banner', '-loglevel', 'warning', '-f', 'lavfi', '-i', 'testsrc=duration=1:size=64x64:rate=10', '-c:v', 'libx264', '-preset', 'ultrafast', '-f', 'flv', 'rtmp://127.0.0.1:1/live/k']);
await new Promise((r) => bad.process.on('close', () => setTimeout(r, 50)));
await new Promise((r) => bad.process.on('close', () => setTimeout(r, 50)));
assert.strictEqual(bad.status, 'error');
assert.strictEqual(bad.status, 'error');
- // The exact wording depends on how the environment fails the connection: a plain refused loopback
- // connect reads "Could not connect to the destination's ingest server", while a sandboxed/offline
- // run can surface an RTMP-level rejection for the same unreachable output. Both are friendly,
- // destination-scoped messages for an output that would not open — the strict refused-connection
- // mapping is asserted above (friendlyFfmpegError, 'Connection refused' → Kick).
+ // FFmpeg can report either a refused connection or an RTMP rejection in restricted environments.
assert.match(bad.lastError, /Could not connect to the destination|the destination rejected the stream key/, bad.lastError);
assert.match(bad.lastError, /Could not connect to the destination|the destination rejected the stream key/, bad.lastError);
assert.ok(bad.restartTimer, 'restart scheduled');
assert.ok(bad.restartTimer, 'restart scheduled');
assert.ok(bad.nextRestartAt > Date.now(), 'dashboard can count down to the retry');
assert.ok(bad.nextRestartAt > Date.now(), 'dashboard can count down to the retry');