supervision 0.2.0-next.2 → 0.2.0-next.3
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.js +49 -7
- package/dist/index.js.map +1 -1
- package/dist/media/media-source.d.ts +2 -0
- package/dist/media/media-source.d.ts.map +1 -1
- package/dist/media/mediabunny-media-source.d.ts.map +1 -1
- package/dist/renderers/media-renderer-core.d.ts.map +1 -1
- package/dist/renderers/media-renderer-transport.d.ts.map +1 -1
- package/dist/web-video-engine/canvas-sink-scrub-cursor.d.ts +1 -1
- package/dist/web-video-engine/decode-scheduler.d.ts +1 -1
- package/dist/web-video-engine/engine-core.d.ts +1 -0
- package/dist/web-video-engine/engine.js +29 -5
- package/dist/web-video-engine/engine.worker.js +23 -7
- package/dist/web-video-engine/scrub-cursor.d.ts +3 -5
- package/dist/web-video-engine/video-engine.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1114,10 +1114,11 @@ async function openMediabunnyMediaSource(sourceInput) {
|
|
|
1114
1114
|
})
|
|
1115
1115
|
.catch(() => null)
|
|
1116
1116
|
: Promise.resolve(null);
|
|
1117
|
-
const [displayWidth, displayHeight, firstTimestamp, packetStats] = await Promise.all([
|
|
1117
|
+
const [displayWidth, displayHeight, firstTimestamp, timeResolution, packetStats,] = await Promise.all([
|
|
1118
1118
|
primaryVideoTrack.getDisplayWidth(),
|
|
1119
1119
|
primaryVideoTrack.getDisplayHeight(),
|
|
1120
1120
|
primaryVideoTrack.getFirstTimestamp(),
|
|
1121
|
+
primaryVideoTrack.getTimeResolution(),
|
|
1121
1122
|
packetStatsPromise,
|
|
1122
1123
|
]);
|
|
1123
1124
|
const duration = isUrlSourceInput(sourceInput)
|
|
@@ -1145,6 +1146,7 @@ async function openMediabunnyMediaSource(sourceInput) {
|
|
|
1145
1146
|
mimeType,
|
|
1146
1147
|
primaryVideoHeight: displayHeight,
|
|
1147
1148
|
primaryVideoWidth: displayWidth,
|
|
1149
|
+
timeResolution,
|
|
1148
1150
|
trackCount: tracks.length,
|
|
1149
1151
|
videoTrackCount: videoTracks.length,
|
|
1150
1152
|
},
|
|
@@ -3151,6 +3153,7 @@ function createMediaRendererTransport(options) {
|
|
|
3151
3153
|
// play the hold is waiting for, so a pause taken during it is not undone by
|
|
3152
3154
|
// the readiness that arrives afterwards.
|
|
3153
3155
|
let playbackIntent = 0;
|
|
3156
|
+
let stepIntent = null;
|
|
3154
3157
|
/** Intent a readiness wait belongs to, or null while none is running. */
|
|
3155
3158
|
let readinessHoldIntent = null;
|
|
3156
3159
|
/** Whether a readiness hold still owes the producer its release. */
|
|
@@ -3169,8 +3172,15 @@ function createMediaRendererTransport(options) {
|
|
|
3169
3172
|
const beginPlaybackIntent = () => {
|
|
3170
3173
|
activeReadinessWait?.abort();
|
|
3171
3174
|
activeReadinessWait = undefined;
|
|
3175
|
+
stepIntent = null;
|
|
3172
3176
|
return ++playbackIntent;
|
|
3173
3177
|
};
|
|
3178
|
+
const beginStepIntent = () => {
|
|
3179
|
+
if (stepIntent !== null)
|
|
3180
|
+
return stepIntent;
|
|
3181
|
+
stepIntent = beginPlaybackIntent();
|
|
3182
|
+
return stepIntent;
|
|
3183
|
+
};
|
|
3174
3184
|
const publishSeekSignals = () => {
|
|
3175
3185
|
options.onScrubbing(gestureInFlight);
|
|
3176
3186
|
options.onSeeking(isSettling(channel.getStatus(), channel.getSeeking()));
|
|
@@ -3460,15 +3470,23 @@ function createMediaRendererTransport(options) {
|
|
|
3460
3470
|
options.invalidatePresentedFrame?.();
|
|
3461
3471
|
const navigationPresentation = ++presentationWait;
|
|
3462
3472
|
presentationHold = null;
|
|
3463
|
-
|
|
3473
|
+
const intent = beginStepIntent();
|
|
3464
3474
|
await releaseGesture();
|
|
3475
|
+
if (intent !== playbackIntent)
|
|
3476
|
+
return;
|
|
3465
3477
|
if (navigationPresentation === presentationWait) {
|
|
3466
3478
|
await releaseReadinessFreeze();
|
|
3467
3479
|
}
|
|
3480
|
+
if (intent !== playbackIntent)
|
|
3481
|
+
return;
|
|
3468
3482
|
const presentation = options.beginPresentedFrameNavigation?.();
|
|
3469
3483
|
const before = channel.getPlayhead().frame;
|
|
3470
3484
|
try {
|
|
3471
3485
|
await channel.step(direction);
|
|
3486
|
+
if (intent !== playbackIntent) {
|
|
3487
|
+
presentation?.cancel();
|
|
3488
|
+
return;
|
|
3489
|
+
}
|
|
3472
3490
|
const after = channel.getPlayhead().frame;
|
|
3473
3491
|
if (before.index === after.index && before.ticks === after.ticks) {
|
|
3474
3492
|
// A boundary step intentionally emits no replacement frame. The
|
|
@@ -4002,6 +4020,7 @@ async function createMediaRendererCore(options, providers) {
|
|
|
4002
4020
|
let pushPresentationReady = false;
|
|
4003
4021
|
let sampleSink;
|
|
4004
4022
|
let firstTimestamp = 0;
|
|
4023
|
+
let sampleTimeResolution = null;
|
|
4005
4024
|
let navigationVersion = 0;
|
|
4006
4025
|
let outstandingSourceReads = 0;
|
|
4007
4026
|
let pendingPullScrubTime = null;
|
|
@@ -4654,6 +4673,12 @@ async function createMediaRendererCore(options, providers) {
|
|
|
4654
4673
|
}
|
|
4655
4674
|
const { metadata } = mediaSource;
|
|
4656
4675
|
firstTimestamp = metadata.firstTimestamp;
|
|
4676
|
+
sampleTimeResolution =
|
|
4677
|
+
metadata.timeResolution !== undefined &&
|
|
4678
|
+
Number.isFinite(metadata.timeResolution) &&
|
|
4679
|
+
metadata.timeResolution > 0
|
|
4680
|
+
? metadata.timeResolution
|
|
4681
|
+
: null;
|
|
4657
4682
|
// One central projection step for every detection input this renderer can
|
|
4658
4683
|
// receive: static frames, a caller-owned source, or a composite source.
|
|
4659
4684
|
// Media dimensions are known here, so a producer can declare its own
|
|
@@ -4901,21 +4926,38 @@ async function createMediaRendererCore(options, providers) {
|
|
|
4901
4926
|
playbackController.pause();
|
|
4902
4927
|
runtimeState.setPaused();
|
|
4903
4928
|
const currentTime = runtimeState.currentTime();
|
|
4904
|
-
const epsilon = 1e-6;
|
|
4905
4929
|
let sample = null;
|
|
4906
4930
|
try {
|
|
4907
4931
|
if (direction === "backward") {
|
|
4908
|
-
|
|
4932
|
+
if (currentTime <= firstTimestamp) {
|
|
4933
|
+
return;
|
|
4934
|
+
}
|
|
4935
|
+
const stepSeconds = sampleTimeResolution === null ? 1e-6 : 1 / sampleTimeResolution;
|
|
4936
|
+
sample = await trackSourceRead(sampleSink.getSample(Math.max(firstTimestamp, currentTime - stepSeconds), {
|
|
4909
4937
|
skipLiveWait: true,
|
|
4910
4938
|
}));
|
|
4911
4939
|
}
|
|
4912
4940
|
else {
|
|
4913
|
-
const iterator = sampleSink.samples(currentTime
|
|
4941
|
+
const iterator = sampleSink.samples(currentTime, undefined, {
|
|
4914
4942
|
skipLiveWait: true,
|
|
4915
4943
|
});
|
|
4916
4944
|
try {
|
|
4917
|
-
|
|
4918
|
-
|
|
4945
|
+
while (true) {
|
|
4946
|
+
const result = await trackSourceRead(iterator.next());
|
|
4947
|
+
if (result.done) {
|
|
4948
|
+
break;
|
|
4949
|
+
}
|
|
4950
|
+
if (requestVersion !== navigationVersion ||
|
|
4951
|
+
runtimeState.isDestroyed()) {
|
|
4952
|
+
result.value.close();
|
|
4953
|
+
return;
|
|
4954
|
+
}
|
|
4955
|
+
if (result.value.timestamp > currentTime) {
|
|
4956
|
+
sample = result.value;
|
|
4957
|
+
break;
|
|
4958
|
+
}
|
|
4959
|
+
result.value.close();
|
|
4960
|
+
}
|
|
4919
4961
|
}
|
|
4920
4962
|
finally {
|
|
4921
4963
|
await iterator.return?.();
|