mirror of
https://github.com/koush/scrypted.git
synced 2026-02-03 06:03:27 +00:00
webrtc: update werift, datachannel connectRPCObject, publish
This commit is contained in:
14
common/package-lock.json
generated
14
common/package-lock.json
generated
@@ -15,14 +15,14 @@
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.0",
|
||||
"@types/node": "^20.19.11",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.5.29",
|
||||
"version": "0.5.39",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.27.1",
|
||||
@@ -3340,11 +3340,13 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.11.0",
|
||||
"version": "20.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz",
|
||||
"integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
@@ -3479,7 +3481,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.0",
|
||||
"@types/node": "^20.19.11",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
|
||||
@@ -9,6 +9,16 @@ export function createAsyncQueue<T>() {
|
||||
const waiting: Deferred<T>[] = [];
|
||||
const queued: { item: T, dequeued?: Deferred<void> }[] = [];
|
||||
|
||||
const wait = async (index: number) => {
|
||||
const q = queued[index];
|
||||
if (!q)
|
||||
return;
|
||||
if (!q.dequeued) {
|
||||
q.dequeued = new Deferred<void>();
|
||||
}
|
||||
return q.dequeued.promise;
|
||||
}
|
||||
|
||||
const dequeue = async () => {
|
||||
if (queued.length) {
|
||||
const { item, dequeued: enqueue } = queued.shift()!;
|
||||
@@ -66,7 +76,7 @@ export function createAsyncQueue<T>() {
|
||||
dequeued?.reject(new Error('abort'));
|
||||
};
|
||||
|
||||
dequeued?.promise.catch(() => {}).finally(() => signal.removeEventListener('abort', h));
|
||||
dequeued?.promise.catch(() => { }).finally(() => signal.removeEventListener('abort', h));
|
||||
signal.addEventListener('abort', h);
|
||||
|
||||
return true;
|
||||
@@ -154,13 +164,14 @@ export function createAsyncQueue<T>() {
|
||||
dequeue,
|
||||
get queue() {
|
||||
return queue();
|
||||
}
|
||||
},
|
||||
wait,
|
||||
}
|
||||
}
|
||||
|
||||
export function createAsyncQueueFromGenerator<T>(generator: AsyncGenerator<T>) {
|
||||
const q = createAsyncQueue<T>();
|
||||
(async() => {
|
||||
(async () => {
|
||||
try {
|
||||
for await (const i of generator) {
|
||||
await q.enqueue(i);
|
||||
|
||||
2
external/werift
vendored
2
external/werift
vendored
Submodule external/werift updated: 280e9d9dc0...44d2480c62
4
plugins/webrtc/package-lock.json
generated
4
plugins/webrtc/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/webrtc",
|
||||
"version": "0.2.82",
|
||||
"version": "0.2.83",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/webrtc",
|
||||
"version": "0.2.82",
|
||||
"version": "0.2.83",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/webrtc",
|
||||
"version": "0.2.82",
|
||||
"version": "0.2.83",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
"prescrypted-setup-project": "scrypted-package-json",
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import { MediaStreamTrack, PeerConfig, RTCDataChannel, RTCPeerConnection, RTCRtpTransceiver, RtpPacket } from "./werift";
|
||||
|
||||
import { Deferred } from "@scrypted/common/src/deferred";
|
||||
import sdk, { FFmpegInput, FFmpegTranscodeStream, Intercom, MediaObject, MediaStreamDestination, MediaStreamFeedback, RequestMediaStream, RTCAVSignalingSetup, RTCConnectionManagement, RTCGeneratorDataChannel, RTCInputMediaObjectTrack, RTCOutputMediaObjectTrack, RTCSignalingOptions, RTCSignalingSession, ScryptedInterface, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import { ScryptedSessionControl } from "./session-control";
|
||||
import { optionalVideoCodec, opusAudioCodecOnly, requiredAudioCodecs, requiredVideoCodec } from "./webrtc-required-codecs";
|
||||
import { logIsLocalIceTransport } from "./werift-util";
|
||||
|
||||
import { addVideoFilterArguments } from "@scrypted/common/src/ffmpeg-helpers";
|
||||
import { connectRTCSignalingClients, legacyGetSignalingSessionOptions } from "@scrypted/common/src/rtc-signaling";
|
||||
import { getSpsPps, getSpsPpsVps, MSection } from "@scrypted/common/src/sdp-utils";
|
||||
import sdk, { FFmpegInput, FFmpegTranscodeStream, Intercom, MediaObject, MediaStreamDestination, MediaStreamFeedback, RequestMediaStream, RTCAVSignalingSetup, RTCConnectionManagement, RTCInputMediaObjectTrack, RTCOutputMediaObjectTrack, RTCSignalingOptions, RTCSignalingSession, ScryptedInterface, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import { H264Repacketizer } from "../../homekit/src/types/camera/h264-packetizer";
|
||||
import { OpusRepacketizer } from "../../homekit/src/types/camera/opus-repacketizer";
|
||||
import { H265Repacketizer } from "./h265-packetizer";
|
||||
import { logConnectionState, waitClosed, waitConnected, waitIceConnected } from "./peerconnection-util";
|
||||
import { RtpCodecCopy, RtpTrack, RtpTracks, startRtpForwarderProcess } from "./rtp-forwarders";
|
||||
import { getAudioCodec, getFFmpegRtpAudioOutputArguments } from "./webrtc-required-codecs";
|
||||
import { ScryptedSessionControl } from "./session-control";
|
||||
import { getAudioCodec, getFFmpegRtpAudioOutputArguments, optionalVideoCodec, opusAudioCodecOnly, requiredAudioCodecs, requiredVideoCodec } from "./webrtc-required-codecs";
|
||||
import { MediaStreamTrack, PeerConfig, RTCPeerConnection, RTCRtpTransceiver, RtpPacket } from "./werift";
|
||||
import { WeriftSignalingSession } from "./werift-signaling-session";
|
||||
import { logIsLocalIceTransport } from "./werift-util";
|
||||
|
||||
function getDebugModeH264EncoderArgs() {
|
||||
return [
|
||||
|
||||
@@ -4,7 +4,7 @@ import { timeoutPromise } from '@scrypted/common/src/promise-utils';
|
||||
import { legacyGetSignalingSessionOptions } from '@scrypted/common/src/rtc-signaling';
|
||||
import { SettingsMixinDeviceBase, SettingsMixinDeviceOptions } from '@scrypted/common/src/settings-mixin';
|
||||
import { createZygote } from '@scrypted/common/src/zygote';
|
||||
import sdk, { DeviceCreator, DeviceCreatorSettings, DeviceProvider, FFmpegInput, ForkWorker, Intercom, MediaConverter, MediaObject, MediaObjectOptions, MixinProvider, RTCSessionControl, RTCSignalingChannel, RTCSignalingClient, RTCSignalingOptions, RTCSignalingSession, RequestMediaStream, RequestMediaStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, ScryptedNativeId, Setting, SettingValue, Settings, VideoCamera, WritableDeviceState } from '@scrypted/sdk';
|
||||
import sdk, { DeviceCreator, DeviceCreatorSettings, DeviceProvider, FFmpegInput, ForkWorker, Intercom, MediaConverter, MediaObject, MediaObjectOptions, MixinProvider, PluginFork, RTCSessionControl, RTCSignalingChannel, RTCSignalingClient, RTCSignalingOptions, RTCSignalingSession, RequestMediaStream, RequestMediaStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, ScryptedNativeId, Setting, SettingValue, Settings, VideoCamera, WritableDeviceState } from '@scrypted/sdk';
|
||||
import { StorageSettings } from '@scrypted/sdk/storage-settings';
|
||||
import { RpcPeer } from '@scrypted/server/src/rpc';
|
||||
import crypto from 'crypto';
|
||||
@@ -27,9 +27,12 @@ defaultPeerConfig.headerExtensions = {
|
||||
audio: [],
|
||||
};
|
||||
|
||||
function delayWorkerExit(worker: ForkWorker) {
|
||||
function delayWorkerExit(f: PluginFork<ReturnType<typeof fork>>) {
|
||||
setTimeout(() => {
|
||||
worker.terminate();
|
||||
f.result.then(r => r.then(rr => rr.exit())).catch(() => { });
|
||||
}, 1000);
|
||||
setTimeout(() => {
|
||||
f.worker.terminate();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
@@ -175,13 +178,13 @@ class WebRTCMixin extends SettingsMixinDeviceBase<RTCSignalingClient & VideoCame
|
||||
const pcc = pcClose();
|
||||
pcc.finally(() => {
|
||||
this.webrtcIntercom = undefined;
|
||||
delayWorkerExit(result.worker);
|
||||
delayWorkerExit(result);
|
||||
});
|
||||
|
||||
return mediaObject;
|
||||
}
|
||||
catch (e) {
|
||||
delayWorkerExit(result.worker);
|
||||
delayWorkerExit(result);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -375,7 +378,7 @@ export class WebRTCPlugin extends AutoenableMixinProvider implements DeviceCreat
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
delayWorkerExit(result.worker);
|
||||
delayWorkerExit(result);
|
||||
throw e;
|
||||
}
|
||||
await connection.negotiateRTCSignalingSession();
|
||||
@@ -404,7 +407,7 @@ export class WebRTCPlugin extends AutoenableMixinProvider implements DeviceCreat
|
||||
const mediaStreamUrl = rtcSource.mediaObject;
|
||||
return await mediaManager.convertMediaObjectToJSON<FFmpegInput>(mediaStreamUrl, ScryptedMimeTypes.FFmpegInput);
|
||||
} catch (e) {
|
||||
delayWorkerExit(result.worker);
|
||||
delayWorkerExit(result);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -424,11 +427,11 @@ export class WebRTCPlugin extends AutoenableMixinProvider implements DeviceCreat
|
||||
try {
|
||||
const connection = await timeoutPromise(2 * 60 * 1000, this.convertToRTCConnectionManagement(result, data, fromMimeType, toMimeType, options));
|
||||
// wait a bit to allow ffmpegs to get terminated by the thread.
|
||||
connection.waitClosed().finally(() => delayWorkerExit(result.worker));
|
||||
connection.waitClosed().finally(() => delayWorkerExit(result));
|
||||
return connection;
|
||||
}
|
||||
catch (e) {
|
||||
delayWorkerExit(result.worker);
|
||||
delayWorkerExit(result);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -438,7 +441,7 @@ export class WebRTCPlugin extends AutoenableMixinProvider implements DeviceCreat
|
||||
return await timeoutPromise(2 * 60 * 1000, this.convertToFFmpegInput(result, data, fromMimeType, toMimeType, options));
|
||||
}
|
||||
catch (e) {
|
||||
delayWorkerExit(result.worker);
|
||||
delayWorkerExit(result);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -699,8 +702,12 @@ async function createConnection(
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
export async function fork() {
|
||||
return {
|
||||
exit() {
|
||||
delayProcessExit();
|
||||
},
|
||||
async createRTCPeerConnectionSource(options: {
|
||||
__json_copy_serialize_children: true,
|
||||
mixinId: string,
|
||||
@@ -710,13 +717,15 @@ export async function fork() {
|
||||
maximumCompatibilityMode: boolean,
|
||||
}): Promise<RTCPeerConnectionPipe> {
|
||||
try {
|
||||
return await createRTCPeerConnectionSource({
|
||||
const ret = await createRTCPeerConnectionSource({
|
||||
nativeId: this.nativeId,
|
||||
mixinId: options.mixinId,
|
||||
mediaStreamOptions: options.mediaStreamOptions,
|
||||
startRTCSignalingSession: (session) => options.startRTCSignalingSession(session),
|
||||
maximumCompatibilityMode: options.maximumCompatibilityMode,
|
||||
});
|
||||
ret.pcClose().finally(() => delayProcessExit());
|
||||
return ret;
|
||||
}
|
||||
catch (e) {
|
||||
delayProcessExit();
|
||||
@@ -736,7 +745,9 @@ export async function fork() {
|
||||
ipv4Ban?: string[];
|
||||
}) {
|
||||
try {
|
||||
return await createConnection(clientSession, requireOpus, maximumCompatibilityMode, clientOptions, options);
|
||||
const ret = await createConnection(clientSession, requireOpus, maximumCompatibilityMode, clientOptions, options);
|
||||
ret.waitClosed().finally(() => delayProcessExit());
|
||||
return ret;
|
||||
}
|
||||
catch (e) {
|
||||
delayProcessExit();
|
||||
|
||||
@@ -367,10 +367,6 @@ export async function createRTCPeerConnectionSource(options: {
|
||||
};
|
||||
}
|
||||
|
||||
interface ReceivedRtpPacket extends RtpPacket {
|
||||
uptime?: number;
|
||||
}
|
||||
|
||||
export function getRTCMediaStreamOptions(id: string, name: string): ResponseMediaStreamOptions {
|
||||
return {
|
||||
// set by consumer
|
||||
|
||||
Reference in New Issue
Block a user