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:
+14
@@ -0,0 +1,14 @@
|
||||
//#region src/media/buffer/back-buffer.d.ts
|
||||
/**
|
||||
* Back buffer configuration.
|
||||
*/
|
||||
interface BackBufferConfig {
|
||||
/**
|
||||
* Number of segments to keep behind current playback position.
|
||||
* Default: 2 segments.
|
||||
*/
|
||||
keepSegments: number;
|
||||
}
|
||||
//#endregion
|
||||
export { BackBufferConfig };
|
||||
//# sourceMappingURL=back-buffer.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"back-buffer.d.ts","names":[],"sources":["../../../../src/media/buffer/back-buffer.ts"],"mappings":";;;;UAYiB;;;;;EAKf"}
|
||||
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
//#region src/media/buffer/back-buffer.ts
|
||||
/**
|
||||
* Default back buffer configuration.
|
||||
*/
|
||||
const DEFAULT_BACK_BUFFER_CONFIG = { keepSegments: 2 };
|
||||
/**
|
||||
* Calculate back buffer flush point.
|
||||
*
|
||||
* Determines where to flush old segments from the back buffer.
|
||||
* Keeps a fixed number of segments behind the current playback position.
|
||||
*
|
||||
* Algorithm:
|
||||
* 1. Find segments before currentTime
|
||||
* 2. Count back N segments (keepSegments)
|
||||
* 3. Return startTime of segment N+1 back (flush everything before this)
|
||||
*
|
||||
* @param segments - Available segments (should be sorted by startTime)
|
||||
* @param currentTime - Current playback position in seconds
|
||||
* @param config - Optional back buffer configuration
|
||||
* @returns Time in seconds to flush up to (flush range: [0, flushEnd))
|
||||
*
|
||||
* @example
|
||||
* const segments = [
|
||||
* { startTime: 0, duration: 6, ... },
|
||||
* { startTime: 6, duration: 6, ... },
|
||||
* { startTime: 12, duration: 6, ... },
|
||||
* { startTime: 18, duration: 6, ... },
|
||||
* ];
|
||||
*
|
||||
* // Playing at 18s, keep 2 segments
|
||||
* const flushEnd = calculateBackBufferFlushPoint(segments, 18);
|
||||
* // Returns 6 (flush [0, 6), keep [6-18))
|
||||
*/
|
||||
function calculateBackBufferFlushPoint(segments, currentTime, config = DEFAULT_BACK_BUFFER_CONFIG) {
|
||||
if (segments.length === 0) return 0;
|
||||
const segmentsBefore = segments.filter((seg) => seg.startTime < currentTime);
|
||||
if (segmentsBefore.length === 0) return 0;
|
||||
const segmentsToFlush = segmentsBefore.length - config.keepSegments;
|
||||
if (segmentsToFlush <= 0) return 0;
|
||||
if (segmentsToFlush >= segmentsBefore.length) return currentTime;
|
||||
return segmentsBefore[segmentsToFlush].startTime;
|
||||
}
|
||||
//#endregion
|
||||
export { DEFAULT_BACK_BUFFER_CONFIG, calculateBackBufferFlushPoint };
|
||||
|
||||
//# sourceMappingURL=back-buffer.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"back-buffer.js","names":[],"sources":["../../../../src/media/buffer/back-buffer.ts"],"sourcesContent":["/**\n * Back Buffer Strategy (Simple)\n *\n * Calculates flush points for back buffer management.\n * V1 uses simple \"keep N segments\" strategy.\n */\n\nimport type { Segment } from '../types';\n\n/**\n * Back buffer configuration.\n */\nexport interface BackBufferConfig {\n /**\n * Number of segments to keep behind current playback position.\n * Default: 2 segments.\n */\n keepSegments: number;\n}\n\n/**\n * Default back buffer configuration.\n */\nexport const DEFAULT_BACK_BUFFER_CONFIG: BackBufferConfig = {\n keepSegments: 2,\n};\n\n/**\n * Calculate back buffer flush point.\n *\n * Determines where to flush old segments from the back buffer.\n * Keeps a fixed number of segments behind the current playback position.\n *\n * Algorithm:\n * 1. Find segments before currentTime\n * 2. Count back N segments (keepSegments)\n * 3. Return startTime of segment N+1 back (flush everything before this)\n *\n * @param segments - Available segments (should be sorted by startTime)\n * @param currentTime - Current playback position in seconds\n * @param config - Optional back buffer configuration\n * @returns Time in seconds to flush up to (flush range: [0, flushEnd))\n *\n * @example\n * const segments = [\n * { startTime: 0, duration: 6, ... },\n * { startTime: 6, duration: 6, ... },\n * { startTime: 12, duration: 6, ... },\n * { startTime: 18, duration: 6, ... },\n * ];\n *\n * // Playing at 18s, keep 2 segments\n * const flushEnd = calculateBackBufferFlushPoint(segments, 18);\n * // Returns 6 (flush [0, 6), keep [6-18))\n */\nexport function calculateBackBufferFlushPoint(\n segments: Segment[],\n currentTime: number,\n config: BackBufferConfig = DEFAULT_BACK_BUFFER_CONFIG\n): number {\n if (segments.length === 0) {\n return 0;\n }\n\n // Find all segments before current time (not including current segment)\n const segmentsBefore = segments.filter((seg) => seg.startTime < currentTime);\n\n // If no segments before current time, nothing to flush\n if (segmentsBefore.length === 0) {\n return 0;\n }\n\n // Calculate how many segments to flush\n // Keep last N segments, flush the rest\n const segmentsToFlush = segmentsBefore.length - config.keepSegments;\n\n // If we don't have enough segments to flush, keep everything\n if (segmentsToFlush <= 0) {\n return 0;\n }\n\n // If we want to flush all segments, return currentTime\n // (flush everything before current playback position)\n if (segmentsToFlush >= segmentsBefore.length) {\n return currentTime;\n }\n\n // Return the startTime of the first segment we want to keep\n // Everything before this will be flushed\n return segmentsBefore[segmentsToFlush]!.startTime;\n}\n"],"mappings":";;;;AAuBA,MAAa,6BAA+C,EAC1D,cAAc,EAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,8BACd,UACA,aACA,SAA2B,4BACnB;CACR,IAAI,SAAS,WAAW,GACtB,OAAO;CAIT,MAAM,iBAAiB,SAAS,QAAQ,QAAQ,IAAI,YAAY,WAAW;CAG3E,IAAI,eAAe,WAAW,GAC5B,OAAO;CAKT,MAAM,kBAAkB,eAAe,SAAS,OAAO;CAGvD,IAAI,mBAAmB,GACrB,OAAO;CAKT,IAAI,mBAAmB,eAAe,QACpC,OAAO;CAKT,OAAO,eAAe,gBAAgB,CAAE;AAC1C"}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
//#region src/media/buffer/forward-buffer.d.ts
|
||||
/**
|
||||
* Forward buffer configuration.
|
||||
*/
|
||||
interface ForwardBufferConfig {
|
||||
/**
|
||||
* Duration in seconds to buffer ahead of current playback position.
|
||||
* Default: 30 seconds.
|
||||
*/
|
||||
bufferDuration: number;
|
||||
}
|
||||
//#endregion
|
||||
export { ForwardBufferConfig };
|
||||
//# sourceMappingURL=forward-buffer.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"forward-buffer.d.ts","names":[],"sources":["../../../../src/media/buffer/forward-buffer.ts"],"mappings":";;;;UAmDiB;;;;;EAKf"}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
import { SEGMENT_TIME_EPSILON } from "../types/index.js";
|
||||
//#region src/media/buffer/forward-buffer.ts
|
||||
/**
|
||||
* Forward Buffer Strategy (Simple)
|
||||
*
|
||||
* Determines which segments to load for forward buffer management.
|
||||
* V1 uses simple fixed-duration strategy (buffer N seconds ahead).
|
||||
*/
|
||||
/**
|
||||
* Merge intervals into sorted, disjoint ranges; touching or overlapping ranges
|
||||
* (gap ≤ `epsilon`) are joined. Empty/inverted ranges are dropped.
|
||||
*/
|
||||
function mergeTimeRanges(ranges, epsilon = SEGMENT_TIME_EPSILON) {
|
||||
const sorted = ranges.filter((r) => r.end > r.start).sort((a, b) => a.start - b.start);
|
||||
const merged = [];
|
||||
for (const r of sorted) {
|
||||
const last = merged[merged.length - 1];
|
||||
if (last && r.start <= last.end + epsilon) last.end = Math.max(last.end, r.end);
|
||||
else merged.push({
|
||||
start: r.start,
|
||||
end: r.end
|
||||
});
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
/**
|
||||
* Whether `[start, end)` is fully covered by the union of `merged` ranges,
|
||||
* tolerating `epsilon` of overhang at each edge. `merged` must be disjoint and
|
||||
* sorted (as returned by `mergeTimeRanges`), so full coverage means a single
|
||||
* merged range contains the interval.
|
||||
*/
|
||||
function isTimeRangeCovered(start, end, merged, epsilon = SEGMENT_TIME_EPSILON) {
|
||||
return merged.some((r) => r.start <= start + epsilon && r.end >= end - epsilon);
|
||||
}
|
||||
/**
|
||||
* Default forward buffer configuration.
|
||||
*/
|
||||
const DEFAULT_FORWARD_BUFFER_CONFIG = { bufferDuration: 30 };
|
||||
/**
|
||||
* Get segments that need to be loaded for forward buffer.
|
||||
*
|
||||
* Determines which segments to load to maintain target buffer duration.
|
||||
* Handles discontiguous buffering (gaps after seeks).
|
||||
*
|
||||
* Algorithm:
|
||||
* 1. Calculate target time: currentTime + bufferDuration
|
||||
* 2. Find all segments in range [currentTime, targetTime)
|
||||
* 3. Filter out segments already buffered at that time position
|
||||
* 4. Return segments to load (fills gaps + extends to target)
|
||||
*
|
||||
* @param segments - All available segments from playlist
|
||||
* @param bufferedSegments - Segments already buffered (ordered by startTime)
|
||||
* @param currentTime - Current playback position in seconds
|
||||
* @param config - Optional forward buffer configuration
|
||||
* @returns Array of segments to load (empty if buffer is sufficient)
|
||||
*
|
||||
* @example
|
||||
* // After seek: buffered [0-12, 18-30], playing at 7s
|
||||
* const toLoad = getSegmentsToLoad(segments, buffered, 7, { bufferDuration: 24 });
|
||||
* // Returns [seg-12, seg-30] (fills gap, extends to target 31s)
|
||||
*/
|
||||
/**
|
||||
* Calculate the start time from which to flush forward buffer content.
|
||||
*
|
||||
* Content that starts at or beyond `currentTime + bufferDuration` is no
|
||||
* longer needed for the current playback position and should be removed
|
||||
* from the SourceBuffer. This prevents unbounded accumulation of scattered
|
||||
* SourceBuffer content after seeks, which can cause QuotaExceededError on
|
||||
* long-form content.
|
||||
*
|
||||
* Returns `Infinity` when nothing needs flushing (no buffered segments
|
||||
* exist beyond the threshold).
|
||||
*
|
||||
* @param bufferedSegments - Segments currently tracked in the buffer model
|
||||
* @param currentTime - Current playback position in seconds
|
||||
* @param config - Optional forward buffer configuration
|
||||
* @returns Start time to flush from (flush range: [flushStart, Infinity)),
|
||||
* or Infinity if no flush is needed
|
||||
*
|
||||
* @example
|
||||
* // Playing at 0s, buffered [0,6,12,18,24,30,36], bufferDuration=30
|
||||
* const flushStart = calculateForwardFlushPoint(segments, 0);
|
||||
* // Returns 30 — flush [30, Infinity), keep [0, 30)
|
||||
*/
|
||||
function calculateForwardFlushPoint(bufferedSegments, currentTime, config = DEFAULT_FORWARD_BUFFER_CONFIG) {
|
||||
if (bufferedSegments.length === 0) return Infinity;
|
||||
const threshold = currentTime + config.bufferDuration;
|
||||
const beyond = bufferedSegments.filter((seg) => seg.startTime >= threshold);
|
||||
if (beyond.length === 0) return Infinity;
|
||||
return Math.min(...beyond.map((seg) => seg.startTime));
|
||||
}
|
||||
/**
|
||||
* Find the start time of the segment containing `currentTime` (or the last
|
||||
* segment if `currentTime` is past the end). Returns `undefined` when
|
||||
* `currentTime` is undefined or when no segment matches.
|
||||
*
|
||||
* Used to detect "meaningful currentTime change" — two times that map to the
|
||||
* same segment start aren't a load-trigger; crossing a segment boundary is.
|
||||
*/
|
||||
function segmentStartForTime(currentTime, segments) {
|
||||
if (currentTime == null) return void 0;
|
||||
return segments?.find(({ startTime, duration }, i, all) => currentTime >= startTime && (currentTime < startTime + duration || i === all.length - 1))?.startTime;
|
||||
}
|
||||
function getSegmentsToLoad(segments, bufferedSegments, currentTime, config = DEFAULT_FORWARD_BUFFER_CONFIG) {
|
||||
if (segments.length === 0) return [];
|
||||
const targetTime = currentTime + config.bufferDuration;
|
||||
const bufferedStartTimes = new Set(bufferedSegments.map((seg) => seg.startTime));
|
||||
return segments.filter((seg, i) => {
|
||||
const segmentEnd = seg.startTime + seg.duration;
|
||||
const overlapsPlayhead = i === segments.length - 1 || segmentEnd > currentTime;
|
||||
const isInRange = seg.startTime < targetTime && overlapsPlayhead;
|
||||
const isNotBuffered = !bufferedStartTimes.has(seg.startTime);
|
||||
return isInRange && isNotBuffered;
|
||||
});
|
||||
}
|
||||
//#endregion
|
||||
export { DEFAULT_FORWARD_BUFFER_CONFIG, calculateForwardFlushPoint, getSegmentsToLoad, isTimeRangeCovered, mergeTimeRanges, segmentStartForTime };
|
||||
|
||||
//# sourceMappingURL=forward-buffer.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user