@meframe/core
Version:
Next generation media processing framework based on WebCodecs
62 lines (61 loc) • 1.89 kB
JavaScript
const MICROSECONDS_PER_SECOND = 1e6;
const DEFAULT_FPS = 30;
const DEFAULT_FRAME_TOLERANCE_US = 33333;
function normalizeFps(value) {
if (!Number.isFinite(value) || value <= 0) {
return DEFAULT_FPS;
}
return value;
}
function frameDurationFromFps(fps) {
const normalized = normalizeFps(fps);
const duration = MICROSECONDS_PER_SECOND / normalized;
return Math.max(Math.round(duration), 1);
}
function frameIndexFromTimestamp(baseTimestampUs, timestampUs, fps, strategy = "nearest") {
const frameDurationUs = frameDurationFromFps(fps);
if (frameDurationUs <= 0) {
return 0;
}
const delta = timestampUs - baseTimestampUs;
const rawIndex = delta / frameDurationUs;
if (!Number.isFinite(rawIndex)) {
return 0;
}
switch (strategy) {
case "floor":
return Math.floor(rawIndex);
case "ceil":
return Math.ceil(rawIndex);
default:
return Math.round(rawIndex);
}
}
function quantizeTimestampToFrame(timestampUs, baseTimestampUs, fps, strategy = "nearest") {
const frameDurationUs = frameDurationFromFps(fps);
const index = frameIndexFromTimestamp(baseTimestampUs, timestampUs, fps, strategy);
return baseTimestampUs + index * frameDurationUs;
}
function isTimestampWithinFrame(targetTimeUs, frameTimestampUs, frameDurationUs, toleranceUs = DEFAULT_FRAME_TOLERANCE_US) {
if (!Number.isFinite(frameTimestampUs)) {
return false;
}
const delta = Math.abs(targetTimeUs - frameTimestampUs);
if (delta <= toleranceUs) {
return true;
}
if (frameDurationUs > 0 && frameTimestampUs <= targetTimeUs) {
return targetTimeUs < frameTimestampUs + frameDurationUs;
}
return false;
}
export {
DEFAULT_FRAME_TOLERANCE_US,
MICROSECONDS_PER_SECOND,
frameDurationFromFps,
frameIndexFromTimestamp,
isTimestampWithinFrame,
normalizeFps,
quantizeTimestampToFrame
};
//# sourceMappingURL=time-utils.js.map