@roboflow/inference-sdk 0.1.10 → 0.1.11
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/dist/index.es.js +139 -128
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/webrtc.d.ts +8 -0
- package/dist/webrtc.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.es.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var l = (r, e, t) =>
|
|
1
|
+
var K = Object.defineProperty;
|
|
2
|
+
var B = (r, e, t) => e in r ? K(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
|
|
3
|
+
var l = (r, e, t) => B(r, typeof e != "symbol" ? e + "" : e, t);
|
|
4
4
|
var L;
|
|
5
|
-
const
|
|
5
|
+
const j = typeof process < "u" && ((L = process.env) != null && L.RF_API_BASE_URL) ? process.env.RF_API_BASE_URL : "https://api.roboflow.com", V = [
|
|
6
6
|
"https://serverless.roboflow.com"
|
|
7
7
|
];
|
|
8
|
-
class
|
|
8
|
+
class b {
|
|
9
9
|
/**
|
|
10
10
|
* @private
|
|
11
11
|
* Use InferenceHTTPClient.init() instead
|
|
@@ -18,7 +18,7 @@ class T {
|
|
|
18
18
|
static init({ apiKey: e, serverUrl: t }) {
|
|
19
19
|
if (!e)
|
|
20
20
|
throw new Error("apiKey is required");
|
|
21
|
-
return new
|
|
21
|
+
return new b(e, t);
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Initialize a WebRTC worker pipeline
|
|
@@ -49,15 +49,15 @@ class T {
|
|
|
49
49
|
offer: e,
|
|
50
50
|
workflowSpec: t,
|
|
51
51
|
workspaceName: n,
|
|
52
|
-
workflowId:
|
|
52
|
+
workflowId: i,
|
|
53
53
|
config: a = {}
|
|
54
54
|
}) {
|
|
55
55
|
if (!e || !e.sdp || !e.type)
|
|
56
56
|
throw new Error("offer with sdp and type is required");
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
57
|
+
const o = !!t, f = !!(n && i);
|
|
58
|
+
if (!o && !f)
|
|
59
59
|
throw new Error("Either workflowSpec OR (workspaceName + workflowId) is required");
|
|
60
|
-
if (
|
|
60
|
+
if (o && f)
|
|
61
61
|
throw new Error("Provide either workflowSpec OR (workspaceName + workflowId), not both");
|
|
62
62
|
const {
|
|
63
63
|
imageInputName: d = "image",
|
|
@@ -65,11 +65,11 @@ class T {
|
|
|
65
65
|
dataOutputNames: s = [],
|
|
66
66
|
threadPoolWorkers: y = 4,
|
|
67
67
|
workflowsParameters: S = {},
|
|
68
|
-
iceServers:
|
|
68
|
+
iceServers: p,
|
|
69
69
|
processingTimeout: u,
|
|
70
|
-
requestedPlan:
|
|
70
|
+
requestedPlan: h,
|
|
71
71
|
requestedRegion: C,
|
|
72
|
-
realtimeProcessing:
|
|
72
|
+
realtimeProcessing: E = !0,
|
|
73
73
|
rtspUrl: R
|
|
74
74
|
} = a, v = {
|
|
75
75
|
type: "WorkflowConfiguration",
|
|
@@ -79,28 +79,28 @@ class T {
|
|
|
79
79
|
cancel_thread_pool_tasks_on_exit: !0,
|
|
80
80
|
video_metadata_input_name: "video_metadata"
|
|
81
81
|
};
|
|
82
|
-
|
|
82
|
+
o ? v.workflow_specification = t : (v.workspace_name = n, v.workflow_id = i);
|
|
83
83
|
const m = {
|
|
84
84
|
workflow_configuration: v,
|
|
85
85
|
api_key: this.apiKey,
|
|
86
|
-
webrtc_realtime_processing:
|
|
86
|
+
webrtc_realtime_processing: E,
|
|
87
87
|
webrtc_offer: {
|
|
88
88
|
sdp: e.sdp,
|
|
89
89
|
type: e.type
|
|
90
90
|
},
|
|
91
|
-
webrtc_config:
|
|
91
|
+
webrtc_config: p ? { iceServers: p } : null,
|
|
92
92
|
stream_output: c,
|
|
93
93
|
data_output: s
|
|
94
94
|
};
|
|
95
|
-
u !== void 0 && (m.processing_timeout = u),
|
|
95
|
+
u !== void 0 && (m.processing_timeout = u), h !== void 0 && (m.requested_plan = h), C !== void 0 && (m.requested_region = C), R && (m.rtsp_url = R);
|
|
96
96
|
const w = await fetch(`${this.serverUrl}/initialise_webrtc_worker`, {
|
|
97
97
|
method: "POST",
|
|
98
98
|
headers: { "Content-Type": "application/json" },
|
|
99
99
|
body: JSON.stringify(m)
|
|
100
100
|
});
|
|
101
101
|
if (!w.ok) {
|
|
102
|
-
const
|
|
103
|
-
throw new Error(`initialise_webrtc_worker failed (${w.status}): ${
|
|
102
|
+
const T = await w.text().catch(() => "");
|
|
103
|
+
throw new Error(`initialise_webrtc_worker failed (${w.status}): ${T}`);
|
|
104
104
|
}
|
|
105
105
|
return await w.json();
|
|
106
106
|
}
|
|
@@ -132,11 +132,11 @@ class T {
|
|
|
132
132
|
* ```
|
|
133
133
|
*/
|
|
134
134
|
async fetchTurnConfig() {
|
|
135
|
-
if (!
|
|
135
|
+
if (!V.includes(this.serverUrl))
|
|
136
136
|
return null;
|
|
137
137
|
try {
|
|
138
138
|
const e = await fetch(
|
|
139
|
-
`${
|
|
139
|
+
`${j}/webrtc_turn_config?api_key=${this.apiKey}`,
|
|
140
140
|
{
|
|
141
141
|
method: "GET",
|
|
142
142
|
headers: { "Content-Type": "application/json" }
|
|
@@ -164,7 +164,7 @@ class T {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
-
const
|
|
167
|
+
const ie = {
|
|
168
168
|
/**
|
|
169
169
|
* Create a connector that uses API key directly
|
|
170
170
|
*
|
|
@@ -188,10 +188,10 @@ const ae = {
|
|
|
188
188
|
typeof window < "u" && console.warn(
|
|
189
189
|
"[Security Warning] Using API key directly in browser will expose it. Use connectors.withProxyUrl() for production. See: https://docs.roboflow.com/api-reference/authentication#securing-your-api-key"
|
|
190
190
|
);
|
|
191
|
-
const n =
|
|
191
|
+
const n = b.init({ apiKey: r, serverUrl: t });
|
|
192
192
|
return {
|
|
193
|
-
connectWrtc: async (
|
|
194
|
-
offer:
|
|
193
|
+
connectWrtc: async (i, a) => (console.debug("wrtcParams", a), await n.initializeWebrtcWorker({
|
|
194
|
+
offer: i,
|
|
195
195
|
workflowSpec: a.workflowSpec,
|
|
196
196
|
workspaceName: a.workspaceName,
|
|
197
197
|
workflowId: a.workflowId,
|
|
@@ -284,18 +284,18 @@ const ae = {
|
|
|
284
284
|
withProxyUrl(r, e = {}) {
|
|
285
285
|
const { turnConfigUrl: t } = e;
|
|
286
286
|
return {
|
|
287
|
-
connectWrtc: async (n,
|
|
287
|
+
connectWrtc: async (n, i) => {
|
|
288
288
|
const a = await fetch(r, {
|
|
289
289
|
method: "POST",
|
|
290
290
|
headers: { "Content-Type": "application/json" },
|
|
291
291
|
body: JSON.stringify({
|
|
292
292
|
offer: n,
|
|
293
|
-
wrtcParams:
|
|
293
|
+
wrtcParams: i
|
|
294
294
|
})
|
|
295
295
|
});
|
|
296
296
|
if (!a.ok) {
|
|
297
|
-
const
|
|
298
|
-
throw new Error(`Proxy request failed (${a.status}): ${
|
|
297
|
+
const o = await a.text().catch(() => "");
|
|
298
|
+
throw new Error(`Proxy request failed (${a.status}): ${o}`);
|
|
299
299
|
}
|
|
300
300
|
return await a.json();
|
|
301
301
|
},
|
|
@@ -317,7 +317,7 @@ const ae = {
|
|
|
317
317
|
};
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
|
-
async function
|
|
320
|
+
async function $(r = { video: !0 }) {
|
|
321
321
|
try {
|
|
322
322
|
console.log("[RFStreams] requesting with", r);
|
|
323
323
|
const e = await navigator.mediaDevices.getUserMedia(r);
|
|
@@ -334,12 +334,12 @@ function O(r) {
|
|
|
334
334
|
const oe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
335
335
|
__proto__: null,
|
|
336
336
|
stopStream: O,
|
|
337
|
-
useCamera:
|
|
338
|
-
}, Symbol.toStringTag, { value: "Module" })), k = 49152,
|
|
339
|
-
function
|
|
337
|
+
useCamera: $
|
|
338
|
+
}, Symbol.toStringTag, { value: "Module" })), k = 49152, M = 262144, z = 10;
|
|
339
|
+
function H(r) {
|
|
340
340
|
return new Promise((e) => setTimeout(e, r));
|
|
341
341
|
}
|
|
342
|
-
class
|
|
342
|
+
class N {
|
|
343
343
|
constructor(e, t) {
|
|
344
344
|
l(this, "file");
|
|
345
345
|
l(this, "channel");
|
|
@@ -365,40 +365,40 @@ class D {
|
|
|
365
365
|
throw new Error("Upload cancelled");
|
|
366
366
|
if (this.channel.readyState !== "open")
|
|
367
367
|
throw new Error("Video upload interrupted");
|
|
368
|
-
const
|
|
369
|
-
for (c.setUint32(0, n, !0), c.setUint32(4, this.totalChunks, !0), new Uint8Array(d, 8).set(
|
|
368
|
+
const i = n * k, a = Math.min(i + k, t), o = this.file.slice(i, a), f = new Uint8Array(await o.arrayBuffer()), d = new ArrayBuffer(8 + f.length), c = new DataView(d);
|
|
369
|
+
for (c.setUint32(0, n, !0), c.setUint32(4, this.totalChunks, !0), new Uint8Array(d, 8).set(f); this.channel.bufferedAmount > M; ) {
|
|
370
370
|
if (this.channel.readyState !== "open")
|
|
371
371
|
throw new Error("Video upload interrupted");
|
|
372
|
-
await z
|
|
372
|
+
await H(z);
|
|
373
373
|
}
|
|
374
374
|
this.channel.send(d), e && e(a, t);
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
|
-
const
|
|
379
|
-
class
|
|
378
|
+
const J = 12;
|
|
379
|
+
class D {
|
|
380
380
|
constructor() {
|
|
381
381
|
l(this, "pendingFrames", /* @__PURE__ */ new Map());
|
|
382
382
|
}
|
|
383
383
|
/**
|
|
384
384
|
* Process an incoming chunk and return the complete message if all chunks received
|
|
385
385
|
*/
|
|
386
|
-
processChunk(e, t, n,
|
|
386
|
+
processChunk(e, t, n, i) {
|
|
387
387
|
if (n === 1)
|
|
388
|
-
return
|
|
388
|
+
return i;
|
|
389
389
|
this.pendingFrames.has(e) || this.pendingFrames.set(e, {
|
|
390
390
|
chunks: /* @__PURE__ */ new Map(),
|
|
391
391
|
totalChunks: n
|
|
392
392
|
});
|
|
393
393
|
const a = this.pendingFrames.get(e);
|
|
394
|
-
if (a.chunks.set(t,
|
|
395
|
-
const
|
|
394
|
+
if (a.chunks.set(t, i), a.chunks.size === n) {
|
|
395
|
+
const o = Array.from(a.chunks.values()).reduce((c, s) => c + s.length, 0), f = new Uint8Array(o);
|
|
396
396
|
let d = 0;
|
|
397
397
|
for (let c = 0; c < n; c++) {
|
|
398
398
|
const s = a.chunks.get(c);
|
|
399
|
-
|
|
399
|
+
f.set(s, d), d += s.length;
|
|
400
400
|
}
|
|
401
|
-
return this.pendingFrames.delete(e),
|
|
401
|
+
return this.pendingFrames.delete(e), f;
|
|
402
402
|
}
|
|
403
403
|
return null;
|
|
404
404
|
}
|
|
@@ -410,27 +410,27 @@ class N {
|
|
|
410
410
|
}
|
|
411
411
|
}
|
|
412
412
|
function A(r) {
|
|
413
|
-
const e = new DataView(r), t = e.getUint32(0, !0), n = e.getUint32(4, !0),
|
|
414
|
-
return { frameId: t, chunkIndex: n, totalChunks:
|
|
413
|
+
const e = new DataView(r), t = e.getUint32(0, !0), n = e.getUint32(4, !0), i = e.getUint32(8, !0), a = new Uint8Array(r, J);
|
|
414
|
+
return { frameId: t, chunkIndex: n, totalChunks: i, payload: a };
|
|
415
415
|
}
|
|
416
416
|
async function G(r, e = 6e3) {
|
|
417
417
|
if (r.iceGatheringState === "complete") return;
|
|
418
418
|
let t = !1;
|
|
419
|
-
const n = (
|
|
420
|
-
|
|
419
|
+
const n = (i) => {
|
|
420
|
+
i.candidate && i.candidate.type === "srflx" && (t = !0);
|
|
421
421
|
};
|
|
422
422
|
r.addEventListener("icecandidate", n);
|
|
423
423
|
try {
|
|
424
424
|
await Promise.race([
|
|
425
|
-
new Promise((
|
|
425
|
+
new Promise((i) => {
|
|
426
426
|
const a = () => {
|
|
427
|
-
r.iceGatheringState === "complete" && (r.removeEventListener("icegatheringstatechange", a),
|
|
427
|
+
r.iceGatheringState === "complete" && (r.removeEventListener("icegatheringstatechange", a), i());
|
|
428
428
|
};
|
|
429
429
|
r.addEventListener("icegatheringstatechange", a);
|
|
430
430
|
}),
|
|
431
|
-
new Promise((
|
|
431
|
+
new Promise((i, a) => {
|
|
432
432
|
setTimeout(() => {
|
|
433
|
-
t ?
|
|
433
|
+
t ? i() : (console.error("[ICE] timeout with NO srflx candidate! Connection may fail."), a(new Error("ICE gathering timeout without srflx candidate")));
|
|
434
434
|
}, e);
|
|
435
435
|
})
|
|
436
436
|
]);
|
|
@@ -438,52 +438,52 @@ async function G(r, e = 6e3) {
|
|
|
438
438
|
r.removeEventListener("icecandidate", n);
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
|
-
function
|
|
441
|
+
function Z(r) {
|
|
442
442
|
return new Promise((e) => {
|
|
443
443
|
r.addEventListener("track", (t) => {
|
|
444
444
|
t.streams && t.streams[0] && e(t.streams[0]);
|
|
445
445
|
});
|
|
446
446
|
});
|
|
447
447
|
}
|
|
448
|
-
const
|
|
448
|
+
const Q = [
|
|
449
449
|
{ urls: ["stun:stun.l.google.com:19302"] }
|
|
450
450
|
];
|
|
451
|
-
async function
|
|
451
|
+
async function X(r, e, t, n, i) {
|
|
452
452
|
if ([!!r, !!e, !!n].filter(Boolean).length !== 1)
|
|
453
453
|
throw new Error("Exactly one of localStream, file, or rtspUrl must be provided");
|
|
454
|
-
const c = t ??
|
|
454
|
+
const c = t ?? Q, s = new RTCPeerConnection({
|
|
455
455
|
iceServers: c
|
|
456
456
|
});
|
|
457
|
-
|
|
457
|
+
i != null && i.onPeerConnectionCreated && await i.onPeerConnectionCreated(s);
|
|
458
458
|
try {
|
|
459
459
|
s.addTransceiver("video", { direction: "recvonly" });
|
|
460
|
-
} catch (
|
|
461
|
-
console.warn("[RFWebRTC] Could not add transceiver:",
|
|
460
|
+
} catch (h) {
|
|
461
|
+
console.warn("[RFWebRTC] Could not add transceiver:", h);
|
|
462
462
|
}
|
|
463
463
|
if (r)
|
|
464
|
-
for (const
|
|
465
|
-
const C = s.addTrack(
|
|
466
|
-
|
|
464
|
+
for (const h of r.getVideoTracks()) {
|
|
465
|
+
const C = s.addTrack(h, r);
|
|
466
|
+
i != null && i.onTrackAdded && await i.onTrackAdded(h, C, s);
|
|
467
467
|
}
|
|
468
|
-
const y =
|
|
468
|
+
const y = Z(s), S = s.createDataChannel("inference", {
|
|
469
469
|
ordered: !0
|
|
470
470
|
});
|
|
471
|
-
let
|
|
472
|
-
e && (
|
|
471
|
+
let p;
|
|
472
|
+
e && (p = s.createDataChannel("video_upload"));
|
|
473
473
|
let u = await s.createOffer();
|
|
474
|
-
if (
|
|
475
|
-
const
|
|
476
|
-
|
|
474
|
+
if (i != null && i.onOfferCreated) {
|
|
475
|
+
const h = await i.onOfferCreated(u);
|
|
476
|
+
h && (u = h);
|
|
477
477
|
}
|
|
478
478
|
return await s.setLocalDescription(u), await G(s), {
|
|
479
479
|
pc: s,
|
|
480
480
|
offer: s.localDescription,
|
|
481
481
|
remoteStreamPromise: y,
|
|
482
482
|
dataChannel: S,
|
|
483
|
-
uploadChannel:
|
|
483
|
+
uploadChannel: p
|
|
484
484
|
};
|
|
485
485
|
}
|
|
486
|
-
async function
|
|
486
|
+
async function Y(r) {
|
|
487
487
|
const e = r.getSenders().find((n) => n.track && n.track.kind === "video");
|
|
488
488
|
if (!e) return;
|
|
489
489
|
const t = e.getParameters();
|
|
@@ -494,25 +494,25 @@ async function X(r) {
|
|
|
494
494
|
console.warn("[RFWebRTC] Failed to set encoding parameters:", n);
|
|
495
495
|
}
|
|
496
496
|
}
|
|
497
|
-
function
|
|
497
|
+
function ee(r, e = 3e4) {
|
|
498
498
|
return new Promise((t, n) => {
|
|
499
499
|
if (r.readyState === "open") {
|
|
500
500
|
t();
|
|
501
501
|
return;
|
|
502
502
|
}
|
|
503
|
-
const
|
|
504
|
-
r.removeEventListener("open",
|
|
503
|
+
const i = () => {
|
|
504
|
+
r.removeEventListener("open", i), r.removeEventListener("error", a), clearTimeout(o), t();
|
|
505
505
|
}, a = () => {
|
|
506
|
-
r.removeEventListener("open",
|
|
507
|
-
},
|
|
508
|
-
r.removeEventListener("open",
|
|
506
|
+
r.removeEventListener("open", i), r.removeEventListener("error", a), clearTimeout(o), n(new Error("Datachannel error"));
|
|
507
|
+
}, o = setTimeout(() => {
|
|
508
|
+
r.removeEventListener("open", i), r.removeEventListener("error", a), n(new Error("Datachannel open timeout"));
|
|
509
509
|
}, e);
|
|
510
|
-
r.addEventListener("open",
|
|
510
|
+
r.addEventListener("open", i), r.addEventListener("error", a);
|
|
511
511
|
});
|
|
512
512
|
}
|
|
513
513
|
class x {
|
|
514
514
|
/** @private */
|
|
515
|
-
constructor(e, t, n,
|
|
515
|
+
constructor(e, t, n, i, a, o) {
|
|
516
516
|
/**
|
|
517
517
|
* The underlying RTCPeerConnection.
|
|
518
518
|
* Exposed for advanced use cases like getting stats or accessing senders.
|
|
@@ -528,6 +528,7 @@ class x {
|
|
|
528
528
|
*/
|
|
529
529
|
l(this, "dataChannel");
|
|
530
530
|
l(this, "reassembler");
|
|
531
|
+
l(this, "ackPacingEnabled");
|
|
531
532
|
/**
|
|
532
533
|
* The data channel used for uploading video files (only available in file upload mode).
|
|
533
534
|
* Exposed for advanced use cases.
|
|
@@ -535,19 +536,21 @@ class x {
|
|
|
535
536
|
l(this, "uploadChannel");
|
|
536
537
|
l(this, "uploader");
|
|
537
538
|
l(this, "onComplete");
|
|
538
|
-
this.peerConnection = e, this._localStream =
|
|
539
|
-
const
|
|
540
|
-
|
|
539
|
+
this.peerConnection = e, this._localStream = o == null ? void 0 : o.localStream, this.remoteStreamPromise = t, this.pipelineId = n, this.apiKey = i, this.dataChannel = a, this.reassembler = new D(), this.ackPacingEnabled = (o == null ? void 0 : o.ackPacingEnabled) === !0, this.uploadChannel = o == null ? void 0 : o.uploadChannel, this.onComplete = o == null ? void 0 : o.onComplete, this.dataChannel.binaryType = "arraybuffer";
|
|
540
|
+
const f = o == null ? void 0 : o.onData;
|
|
541
|
+
f && (this.dataChannel.addEventListener("message", (d) => {
|
|
541
542
|
try {
|
|
542
543
|
if (d.data instanceof ArrayBuffer) {
|
|
543
|
-
const { frameId: c, chunkIndex: s, totalChunks: y, payload: S } = A(d.data),
|
|
544
|
-
if (
|
|
545
|
-
const
|
|
546
|
-
|
|
544
|
+
const { frameId: c, chunkIndex: s, totalChunks: y, payload: S } = A(d.data), p = this.reassembler.processChunk(c, s, y, S);
|
|
545
|
+
if (p) {
|
|
546
|
+
const h = new TextDecoder("utf-8").decode(p), C = JSON.parse(h);
|
|
547
|
+
Promise.resolve(f(C)).finally(() => {
|
|
548
|
+
this.maybeSendAck(c);
|
|
549
|
+
});
|
|
547
550
|
}
|
|
548
551
|
} else {
|
|
549
552
|
const c = JSON.parse(d.data);
|
|
550
|
-
|
|
553
|
+
f(c);
|
|
551
554
|
}
|
|
552
555
|
} catch (c) {
|
|
553
556
|
console.error("[RFWebRTC] Failed to parse data channel message:", c);
|
|
@@ -558,6 +561,13 @@ class x {
|
|
|
558
561
|
this.reassembler.clear(), this.onComplete && this.onComplete();
|
|
559
562
|
});
|
|
560
563
|
}
|
|
564
|
+
/**
|
|
565
|
+
* Send cumulative ACK after a frame is fully handled.
|
|
566
|
+
* Only used in batch mode (realtimeProcessing=false).
|
|
567
|
+
*/
|
|
568
|
+
maybeSendAck(e) {
|
|
569
|
+
this.ackPacingEnabled && this.dataChannel.readyState === "open" && this.dataChannel.send(JSON.stringify({ ack: e }));
|
|
570
|
+
}
|
|
561
571
|
/**
|
|
562
572
|
* Get the remote stream (processed video from Roboflow)
|
|
563
573
|
*
|
|
@@ -608,7 +618,7 @@ class x {
|
|
|
608
618
|
async cleanup() {
|
|
609
619
|
if (this.uploader && this.uploader.cancel(), this.reassembler.clear(), this.pipelineId && this.apiKey)
|
|
610
620
|
try {
|
|
611
|
-
await
|
|
621
|
+
await b.init({ apiKey: this.apiKey }).terminatePipeline({ pipelineId: this.pipelineId });
|
|
612
622
|
} catch (e) {
|
|
613
623
|
console.warn("[RFWebRTC] Failed to terminate pipeline:", e);
|
|
614
624
|
}
|
|
@@ -632,7 +642,7 @@ class x {
|
|
|
632
642
|
async startUpload(e, t) {
|
|
633
643
|
if (!this.uploadChannel)
|
|
634
644
|
throw new Error("No upload channel available. This connection was not created for file uploads.");
|
|
635
|
-
await
|
|
645
|
+
await ee(this.uploadChannel), this.uploader = new N(e, this.uploadChannel), await this.uploader.upload(t);
|
|
636
646
|
}
|
|
637
647
|
/**
|
|
638
648
|
* Cancel any ongoing file upload
|
|
@@ -698,42 +708,42 @@ async function F({
|
|
|
698
708
|
rtspUrl: e,
|
|
699
709
|
connector: t,
|
|
700
710
|
wrtcParams: n,
|
|
701
|
-
onData:
|
|
711
|
+
onData: i,
|
|
702
712
|
onComplete: a,
|
|
703
|
-
onFileUploadProgress:
|
|
704
|
-
options:
|
|
713
|
+
onFileUploadProgress: o,
|
|
714
|
+
options: f = {},
|
|
705
715
|
hooks: d
|
|
706
716
|
}) {
|
|
707
|
-
var
|
|
717
|
+
var W;
|
|
708
718
|
if (!t || typeof t.connectWrtc != "function")
|
|
709
719
|
throw new Error("connector must have a connectWrtc method");
|
|
710
720
|
const c = !!e, s = !c && r instanceof File, y = !c && !s && r ? r : void 0, S = s ? r : void 0;
|
|
711
|
-
let
|
|
712
|
-
if ((!
|
|
721
|
+
let p = n.iceServers;
|
|
722
|
+
if ((!p || p.length === 0) && t.getIceServers)
|
|
713
723
|
try {
|
|
714
724
|
const g = await t.getIceServers();
|
|
715
|
-
g && g.length > 0 && (
|
|
725
|
+
g && g.length > 0 && (p = g, console.log("[RFWebRTC] Using TURN servers from connector"));
|
|
716
726
|
} catch (g) {
|
|
717
727
|
console.warn("[RFWebRTC] Failed to fetch TURN config, using defaults:", g);
|
|
718
728
|
}
|
|
719
|
-
const { pc: u, offer:
|
|
729
|
+
const { pc: u, offer: h, remoteStreamPromise: C, dataChannel: E, uploadChannel: R } = await X(
|
|
720
730
|
y,
|
|
721
731
|
S,
|
|
722
|
-
|
|
732
|
+
p,
|
|
723
733
|
e,
|
|
724
734
|
d
|
|
725
735
|
), v = {
|
|
726
736
|
...n,
|
|
727
|
-
iceServers:
|
|
737
|
+
iceServers: p,
|
|
728
738
|
realtimeProcessing: n.realtimeProcessing ?? !s,
|
|
729
739
|
rtspUrl: e
|
|
730
740
|
}, m = await t.connectWrtc(
|
|
731
|
-
{ sdp:
|
|
741
|
+
{ sdp: h.sdp, type: h.type },
|
|
732
742
|
v
|
|
733
743
|
), w = { sdp: m.sdp, type: m.type };
|
|
734
744
|
if (!(w != null && w.sdp) || !(w != null && w.type))
|
|
735
745
|
throw console.error("[RFWebRTC] Invalid answer from server:", m), new Error("connector.connectWrtc must return answer with sdp and type");
|
|
736
|
-
const U = ((
|
|
746
|
+
const U = ((W = m == null ? void 0 : m.context) == null ? void 0 : W.pipeline_id) || null;
|
|
737
747
|
await u.setRemoteDescription(w), await new Promise((g, I) => {
|
|
738
748
|
const _ = () => {
|
|
739
749
|
u.connectionState === "connected" ? (u.removeEventListener("connectionstatechange", _), g()) : u.connectionState === "failed" && (u.removeEventListener("connectionstatechange", _), I(new Error("WebRTC connection failed")));
|
|
@@ -741,30 +751,31 @@ async function F({
|
|
|
741
751
|
u.addEventListener("connectionstatechange", _), _(), setTimeout(() => {
|
|
742
752
|
u.removeEventListener("connectionstatechange", _), I(new Error("WebRTC connection timeout after 30s"));
|
|
743
753
|
}, 3e4);
|
|
744
|
-
}), y &&
|
|
745
|
-
const
|
|
754
|
+
}), y && f.disableInputStreamDownscaling !== !1 && await Y(u);
|
|
755
|
+
const T = t._apiKey || null, q = v.realtimeProcessing === !1, P = new x(
|
|
746
756
|
u,
|
|
747
757
|
C,
|
|
748
758
|
U,
|
|
759
|
+
T,
|
|
749
760
|
E,
|
|
750
|
-
b,
|
|
751
761
|
{
|
|
752
762
|
localStream: y,
|
|
753
763
|
uploadChannel: R,
|
|
754
|
-
onData:
|
|
755
|
-
onComplete: a
|
|
764
|
+
onData: i,
|
|
765
|
+
onComplete: a,
|
|
766
|
+
ackPacingEnabled: q
|
|
756
767
|
}
|
|
757
768
|
);
|
|
758
|
-
return S && R &&
|
|
769
|
+
return S && R && P.startUpload(S, o).catch((g) => {
|
|
759
770
|
console.error("[RFWebRTC] Upload error:", g);
|
|
760
|
-
}),
|
|
771
|
+
}), P;
|
|
761
772
|
}
|
|
762
|
-
async function
|
|
773
|
+
async function te({
|
|
763
774
|
source: r,
|
|
764
775
|
connector: e,
|
|
765
776
|
wrtcParams: t,
|
|
766
777
|
onData: n,
|
|
767
|
-
options:
|
|
778
|
+
options: i = {},
|
|
768
779
|
hooks: a
|
|
769
780
|
}) {
|
|
770
781
|
if (r instanceof File)
|
|
@@ -774,18 +785,18 @@ async function ee({
|
|
|
774
785
|
connector: e,
|
|
775
786
|
wrtcParams: t,
|
|
776
787
|
onData: n,
|
|
777
|
-
options:
|
|
788
|
+
options: i,
|
|
778
789
|
hooks: a
|
|
779
790
|
});
|
|
780
791
|
}
|
|
781
|
-
async function
|
|
792
|
+
async function re({
|
|
782
793
|
file: r,
|
|
783
794
|
connector: e,
|
|
784
795
|
wrtcParams: t,
|
|
785
796
|
onData: n,
|
|
786
|
-
onUploadProgress:
|
|
797
|
+
onUploadProgress: i,
|
|
787
798
|
onComplete: a,
|
|
788
|
-
hooks:
|
|
799
|
+
hooks: o
|
|
789
800
|
}) {
|
|
790
801
|
return F({
|
|
791
802
|
source: r,
|
|
@@ -796,16 +807,16 @@ async function te({
|
|
|
796
807
|
},
|
|
797
808
|
onData: n,
|
|
798
809
|
onComplete: a,
|
|
799
|
-
onFileUploadProgress:
|
|
800
|
-
hooks:
|
|
810
|
+
onFileUploadProgress: i,
|
|
811
|
+
hooks: o
|
|
801
812
|
});
|
|
802
813
|
}
|
|
803
|
-
async function
|
|
814
|
+
async function ne({
|
|
804
815
|
rtspUrl: r,
|
|
805
816
|
connector: e,
|
|
806
817
|
wrtcParams: t,
|
|
807
818
|
onData: n,
|
|
808
|
-
hooks:
|
|
819
|
+
hooks: i
|
|
809
820
|
}) {
|
|
810
821
|
if (!r.startsWith("rtsp://") && !r.startsWith("rtsps://"))
|
|
811
822
|
throw new Error("Invalid RTSP URL: must start with rtsp:// or rtsps://");
|
|
@@ -814,23 +825,23 @@ async function re({
|
|
|
814
825
|
connector: e,
|
|
815
826
|
wrtcParams: t,
|
|
816
827
|
onData: n,
|
|
817
|
-
hooks:
|
|
828
|
+
hooks: i
|
|
818
829
|
});
|
|
819
830
|
}
|
|
820
|
-
const
|
|
831
|
+
const se = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
821
832
|
__proto__: null,
|
|
822
|
-
ChunkReassembler:
|
|
823
|
-
FileUploader:
|
|
833
|
+
ChunkReassembler: D,
|
|
834
|
+
FileUploader: N,
|
|
824
835
|
RFWebRTCConnection: x,
|
|
825
836
|
parseBinaryHeader: A,
|
|
826
|
-
useRtspStream:
|
|
827
|
-
useStream:
|
|
828
|
-
useVideoFile:
|
|
837
|
+
useRtspStream: ne,
|
|
838
|
+
useStream: te,
|
|
839
|
+
useVideoFile: re
|
|
829
840
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
830
841
|
export {
|
|
831
|
-
|
|
832
|
-
|
|
842
|
+
b as InferenceHTTPClient,
|
|
843
|
+
ie as connectors,
|
|
833
844
|
oe as streams,
|
|
834
|
-
|
|
845
|
+
se as webrtc
|
|
835
846
|
};
|
|
836
847
|
//# sourceMappingURL=index.es.js.map
|