mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
build(spf): build26 from 45504a2b
This commit is contained in:
+139
@@ -0,0 +1,139 @@
|
||||
import { SerialRunner, Task } from "../../../core/tasks/task.js";
|
||||
import { createMachineActor } from "../../../core/actors/create-machine-actor.js";
|
||||
import { appendSegment } from "../../../media/dom/mse/append-segment.js";
|
||||
import { flushBuffer } from "../../../media/dom/mse/buffer-flusher.js";
|
||||
import { SEGMENT_TIME_EPSILON } from "../../../media/types/index.js";
|
||||
//#region src/playback/actors/dom/source-buffer.ts
|
||||
function snapshotBuffered(buffered) {
|
||||
const ranges = [];
|
||||
for (let i = 0; i < buffered.length; i++) ranges.push({
|
||||
start: buffered.start(i),
|
||||
end: buffered.end(i)
|
||||
});
|
||||
return ranges;
|
||||
}
|
||||
function appendInitTask(message, { getContext, sourceBuffer }) {
|
||||
return new Task(async (taskSignal) => {
|
||||
const ctx = getContext();
|
||||
if (taskSignal.aborted) return ctx;
|
||||
await appendSegment(sourceBuffer, message.data);
|
||||
return {
|
||||
...ctx,
|
||||
initTrackId: message.meta.trackId,
|
||||
initTrackLanguage: message.meta.language
|
||||
};
|
||||
});
|
||||
}
|
||||
function appendSegmentTask(message, { getContext, sourceBuffer, setContext }) {
|
||||
return new Task(async (taskSignal) => {
|
||||
const ctx = getContext();
|
||||
if (taskSignal.aborted) return ctx;
|
||||
const { meta } = message;
|
||||
const filtered = ctx.segments.filter((s) => Math.abs(s.startTime - meta.startTime) >= SEGMENT_TIME_EPSILON);
|
||||
if (!(message.data instanceof ArrayBuffer)) setContext({
|
||||
...ctx,
|
||||
segments: [...filtered, {
|
||||
id: meta.id,
|
||||
startTime: meta.startTime,
|
||||
duration: meta.duration,
|
||||
trackId: meta.trackId,
|
||||
...meta.trackBandwidth !== void 0 && { trackBandwidth: meta.trackBandwidth },
|
||||
partial: true
|
||||
}],
|
||||
bufferedRanges: ctx.bufferedRanges
|
||||
});
|
||||
if (meta.timestampOffset != null && sourceBuffer.timestampOffset !== meta.timestampOffset) sourceBuffer.timestampOffset = meta.timestampOffset;
|
||||
await appendSegment(sourceBuffer, message.data, taskSignal);
|
||||
return {
|
||||
...ctx,
|
||||
segments: [...filtered, {
|
||||
id: meta.id,
|
||||
startTime: meta.startTime,
|
||||
duration: meta.duration,
|
||||
trackId: meta.trackId,
|
||||
...meta.trackBandwidth !== void 0 && { trackBandwidth: meta.trackBandwidth }
|
||||
}],
|
||||
bufferedRanges: snapshotBuffered(sourceBuffer.buffered)
|
||||
};
|
||||
});
|
||||
}
|
||||
function removeTask(message, { getContext, sourceBuffer }) {
|
||||
return new Task(async (taskSignal) => {
|
||||
const ctx = getContext();
|
||||
if (taskSignal.aborted) return ctx;
|
||||
await flushBuffer(sourceBuffer, message.start, message.end);
|
||||
const bufferedRanges = snapshotBuffered(sourceBuffer.buffered);
|
||||
const filtered = ctx.segments.filter((s) => {
|
||||
const midpoint = s.startTime + s.duration / 2;
|
||||
return bufferedRanges.some((r) => midpoint >= r.start && midpoint < r.end);
|
||||
});
|
||||
return {
|
||||
...ctx,
|
||||
segments: filtered,
|
||||
bufferedRanges
|
||||
};
|
||||
});
|
||||
}
|
||||
const messageTaskFactories = {
|
||||
"append-init": appendInitTask,
|
||||
"append-segment": appendSegmentTask,
|
||||
remove: removeTask
|
||||
};
|
||||
function messageToTask(message, options) {
|
||||
const factory = messageTaskFactories[message.type];
|
||||
return factory(message, options);
|
||||
}
|
||||
function createSourceBufferActor(sourceBuffer, initialContext) {
|
||||
const handleError = (e) => {
|
||||
if (!(e instanceof Error && e.name === "AbortError")) console.error("SourceBuffer operation failed:", e);
|
||||
};
|
||||
const onMessage = (msg, { transition, setContext, getContext, runner }) => {
|
||||
transition("updating");
|
||||
const task = messageToTask(msg, {
|
||||
getContext,
|
||||
sourceBuffer,
|
||||
setContext
|
||||
});
|
||||
runner.schedule(task).then(setContext, handleError);
|
||||
};
|
||||
return createMachineActor({
|
||||
runner: () => new SerialRunner(),
|
||||
initial: "idle",
|
||||
context: {
|
||||
segments: [],
|
||||
bufferedRanges: [],
|
||||
initTrackId: void 0,
|
||||
...initialContext
|
||||
},
|
||||
states: {
|
||||
idle: { on: {
|
||||
"append-init": onMessage,
|
||||
"append-segment": onMessage,
|
||||
remove: onMessage,
|
||||
batch: (msg, { transition, setContext, getContext, runner }) => {
|
||||
const { messages } = msg;
|
||||
if (messages.length === 0) return;
|
||||
transition("updating");
|
||||
messages.forEach((msg) => {
|
||||
const task = messageToTask(msg, {
|
||||
getContext,
|
||||
sourceBuffer,
|
||||
setContext
|
||||
});
|
||||
runner.schedule(task).then(setContext, handleError);
|
||||
});
|
||||
}
|
||||
} },
|
||||
updating: {
|
||||
onSettled: "idle",
|
||||
on: { cancel: (_, { runner }) => {
|
||||
runner.abortAll();
|
||||
} }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//#endregion
|
||||
export { createSourceBufferActor };
|
||||
|
||||
//# sourceMappingURL=source-buffer.js.map
|
||||
Reference in New Issue
Block a user