remotion
Version:
Make videos programmatically
87 lines (86 loc) • 3.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useAppendVideoFragment = exports.appendVideoFragment = exports.isIosSafari = void 0;
const react_1 = require("react");
const toSeconds = (time, fps) => {
return Math.round((time / fps) * 100) / 100;
};
const isIosSafari = () => {
if (typeof window === 'undefined') {
return false;
}
const isIpadIPodIPhone = /iP(ad|od|hone)/i.test(window.navigator.userAgent);
const isAppleWebKit = /AppleWebKit/.test(window.navigator.userAgent);
return isIpadIPodIPhone && isAppleWebKit;
};
exports.isIosSafari = isIosSafari;
// https://github.com/remotion-dev/remotion/issues/1655
const isIOSSafariAndBlob = (actualSrc) => {
return (0, exports.isIosSafari)() && actualSrc.startsWith('blob:');
};
const getVideoFragmentStart = ({ actualFrom, fps, }) => {
return toSeconds(Math.max(0, -actualFrom), fps);
};
const getVideoFragmentEnd = ({ duration, fps, }) => {
return toSeconds(duration, fps);
};
const appendVideoFragment = ({ actualSrc, actualFrom, duration, fps, }) => {
var _a;
if (isIOSSafariAndBlob(actualSrc)) {
return actualSrc;
}
if (actualSrc.startsWith('data:')) {
return actualSrc;
}
const existingHash = Boolean(new URL(actualSrc, (_a = (typeof window === 'undefined' ? null : window.location.href)) !== null && _a !== void 0 ? _a : 'http://localhost:3000').hash);
if (existingHash) {
return actualSrc;
}
if (!Number.isFinite(actualFrom)) {
return actualSrc;
}
const withStartHash = `${actualSrc}#t=${getVideoFragmentStart({ actualFrom, fps })}`;
if (!Number.isFinite(duration)) {
return withStartHash;
}
return `${withStartHash},${getVideoFragmentEnd({ duration, fps })}`;
};
exports.appendVideoFragment = appendVideoFragment;
const isSubsetOfDuration = ({ prevStartFrom, newStartFrom, prevDuration, newDuration, fps, }) => {
const previousFrom = getVideoFragmentStart({ actualFrom: prevStartFrom, fps });
const newFrom = getVideoFragmentStart({ actualFrom: newStartFrom, fps });
const previousEnd = getVideoFragmentEnd({ duration: prevDuration, fps });
const newEnd = getVideoFragmentEnd({ duration: newDuration, fps });
if (newFrom < previousFrom) {
return false;
}
if (newEnd > previousEnd) {
return false;
}
return true;
};
const useAppendVideoFragment = ({ actualSrc: initialActualSrc, actualFrom: initialActualFrom, duration: initialDuration, fps, }) => {
const actualFromRef = (0, react_1.useRef)(initialActualFrom);
const actualDuration = (0, react_1.useRef)(initialDuration);
const actualSrc = (0, react_1.useRef)(initialActualSrc);
if (!isSubsetOfDuration({
prevStartFrom: actualFromRef.current,
newStartFrom: initialActualFrom,
prevDuration: actualDuration.current,
newDuration: initialDuration,
fps,
}) ||
initialActualSrc !== actualSrc.current) {
actualFromRef.current = initialActualFrom;
actualDuration.current = initialDuration;
actualSrc.current = initialActualSrc;
}
const appended = (0, exports.appendVideoFragment)({
actualSrc: actualSrc.current,
actualFrom: actualFromRef.current,
duration: actualDuration.current,
fps,
});
return appended;
};
exports.useAppendVideoFragment = useAppendVideoFragment;