init commit

This commit is contained in:
Carlos
2026-02-21 10:33:18 +01:00
parent c863a943ed
commit 9d955bf338
9512 changed files with 2015317 additions and 1305 deletions

View File

@@ -0,0 +1,2 @@
import type { Avc1Data } from './create-codec-specific-data';
export declare const createAvc1Data: ({ avccBox, pasp, width, height, horizontalResolution, verticalResolution, compressorName, depth, }: Avc1Data) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAvc1Data = void 0;
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
const createAvc1Data = ({ avccBox, pasp, width, height, horizontalResolution, verticalResolution, compressorName, depth, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('avc1'),
// reserved
new Uint8Array([0, 0, 0, 0, 0, 0]),
// data_reference_index
new Uint8Array([0, 1]),
// version
new Uint8Array([0, 0]),
// revisionLevel
new Uint8Array([0, 0]),
// vendor
new Uint8Array([0, 0, 0, 0]),
// temporalQuality
new Uint8Array([0, 0, 0, 0]),
// spatialQuality
new Uint8Array([0, 0, 0, 0]),
// width
(0, primitives_1.numberTo16BitUIntOrInt)(width),
// height
(0, primitives_1.numberTo16BitUIntOrInt)(height),
// horizontalResolution
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(horizontalResolution),
// verticalResolution
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(verticalResolution),
// dataSize
new Uint8Array([0, 0, 0, 0]),
// frame count per sample
(0, primitives_1.numberTo16BitUIntOrInt)(1),
// compressor name
(0, primitives_1.stringToPascalString)(compressorName),
// depth
(0, primitives_1.numberTo16BitUIntOrInt)(depth),
// colorTableId
(0, primitives_1.numberTo16BitUIntOrInt)(-1),
// avcc box
avccBox,
// pasp
pasp,
]));
};
exports.createAvc1Data = createAvc1Data;

View File

@@ -0,0 +1,33 @@
import type { MakeTrackAudio, MakeTrackVideo } from '../../make-track-info';
export type Avc1Data = {
pasp: Uint8Array;
avccBox: Uint8Array;
width: number;
height: number;
horizontalResolution: number;
verticalResolution: number;
compressorName: string;
depth: number;
type: 'avc1-data';
};
export type Hvc1Data = {
pasp: Uint8Array;
hvccBox: Uint8Array;
width: number;
height: number;
horizontalResolution: number;
verticalResolution: number;
compressorName: string;
depth: number;
type: 'hvc1-data';
};
export type Mp4aData = {
type: 'mp4a-data';
sampleRate: number;
channelCount: number;
maxBitrate: number;
avgBitrate: number;
codecPrivate: Uint8Array | null;
};
export type CodecSpecificData = Avc1Data | Mp4aData;
export declare const createCodecSpecificData: (track: MakeTrackAudio | MakeTrackVideo) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCodecSpecificData = void 0;
const create_avcc_1 = require("../trak/mdia/minf/stbl/stsd/create-avcc");
const create_hvcc_1 = require("../trak/mdia/minf/stbl/stsd/create-hvcc");
const create_pasp_1 = require("../trak/mdia/minf/stbl/stsd/create-pasp");
const avc1_1 = require("./avc1");
const hvc1_1 = require("./hvc1");
const mp4a_1 = require("./mp4a");
const createCodecSpecificData = (track) => {
if (track.type === 'video') {
if (track.codec === 'h264') {
// May not have it initially
if (!track.codecPrivate) {
return new Uint8Array([]);
}
return (0, avc1_1.createAvc1Data)({
avccBox: (0, create_avcc_1.createAvccBox)(track.codecPrivate),
compressorName: 'WebCodecs',
depth: 24,
horizontalResolution: 72,
verticalResolution: 72,
height: track.height,
width: track.width,
pasp: (0, create_pasp_1.createPasp)(1, 1),
type: 'avc1-data',
});
}
if (track.codec === 'h265') {
// May not have it initially
if (!track.codecPrivate) {
return new Uint8Array([]);
}
return (0, hvc1_1.createHvc1Data)({
hvccBox: (0, create_hvcc_1.createHvccBox)(track.codecPrivate),
compressorName: 'WebCodecs',
depth: 24,
horizontalResolution: 72,
verticalResolution: 72,
height: track.height,
width: track.width,
pasp: (0, create_pasp_1.createPasp)(1, 1),
type: 'hvc1-data',
});
}
throw new Error('Unsupported codec specific data ' + track.codec);
}
if (track.type === 'audio') {
return (0, mp4a_1.createMp4a)({
type: 'mp4a-data',
// TODO: Put in values based on real data,
// this seems to work though
avgBitrate: 128 * 1024,
maxBitrate: 128 * 1024,
channelCount: track.numberOfChannels,
sampleRate: track.sampleRate,
codecPrivate: track.codecPrivate,
});
}
throw new Error('Unsupported codec specific data ' + track);
};
exports.createCodecSpecificData = createCodecSpecificData;

View File

@@ -0,0 +1,2 @@
import type { Hvc1Data } from './create-codec-specific-data';
export declare const createHvc1Data: ({ compressorName, depth, height, horizontalResolution, hvccBox, pasp, verticalResolution, width, }: Hvc1Data) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createHvc1Data = void 0;
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
const createHvc1Data = ({ compressorName, depth, height, horizontalResolution, hvccBox, pasp, verticalResolution, width, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('hvc1'),
// reserved
new Uint8Array([0, 0, 0, 0, 0, 0]),
// data_reference_index
new Uint8Array([0, 1]),
// version
new Uint8Array([0, 0]),
// revisionLevel
new Uint8Array([0, 0]),
// vendor
new Uint8Array([0, 0, 0, 0]),
// temporalQuality
new Uint8Array([0, 0, 0, 0]),
// spatialQuality
new Uint8Array([0, 0, 0, 0]),
// width
(0, primitives_1.numberTo16BitUIntOrInt)(width),
// height
(0, primitives_1.numberTo16BitUIntOrInt)(height),
// horizontalResolution
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(horizontalResolution),
// verticalResolution
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(verticalResolution),
// dataSize
new Uint8Array([0, 0, 0, 0]),
// frame count per sample
(0, primitives_1.numberTo16BitUIntOrInt)(1),
// compressor name
(0, primitives_1.stringToPascalString)(compressorName),
// depth
(0, primitives_1.numberTo16BitUIntOrInt)(depth),
// colorTableId
(0, primitives_1.numberTo16BitUIntOrInt)(-1),
// hvcc box
hvccBox,
// pasp
pasp,
]));
};
exports.createHvc1Data = createHvc1Data;

View File

@@ -0,0 +1,2 @@
import type { Mp4aData } from './create-codec-specific-data';
export declare const createMp4a: ({ sampleRate, channelCount, avgBitrate, maxBitrate, codecPrivate, }: Mp4aData) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMp4a = void 0;
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
const createMp4a = ({ sampleRate, channelCount, avgBitrate, maxBitrate, codecPrivate, }) => {
if (!codecPrivate) {
throw new Error('Need codecPrivate for mp4a');
}
const esdsAtom = (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('esds'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// tag = 'ES_DescrTag'
new Uint8Array([3]),
(0, primitives_1.addLeading128Size)((0, matroska_utils_1.combineUint8Arrays)([
// ES_ID
(0, primitives_1.numberTo16BitUIntOrInt)(2),
// streamDependenceFlag, URL_Flag, OCRstreamFlag
new Uint8Array([0]),
// DecoderConfigDescrTag
new Uint8Array([4]),
(0, primitives_1.addLeading128Size)((0, matroska_utils_1.combineUint8Arrays)([
// objectTypeIndication
new Uint8Array([0x40]),
// streamType, upStream
new Uint8Array([21]),
// reserved
new Uint8Array([0, 0, 0]),
// maxBitrate
(0, primitives_1.numberTo32BitUIntOrInt)(maxBitrate),
// avgBitrate
(0, primitives_1.numberTo32BitUIntOrInt)(avgBitrate),
// DecoderSpecificInfoTag
new Uint8Array([5]),
// see create-aac-codecprivate.ts
(0, primitives_1.addLeading128Size)(codecPrivate),
])),
// SLConfigDescrTag
new Uint8Array([6]),
(0, primitives_1.addLeading128Size)(new Uint8Array([2])),
])),
]));
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('mp4a'),
// reserved
new Uint8Array([0, 0, 0, 0, 0, 0]),
// data_reference_index
(0, primitives_1.numberTo16BitUIntOrInt)(1),
// version
(0, primitives_1.numberTo16BitUIntOrInt)(0),
// revision level
(0, primitives_1.numberTo16BitUIntOrInt)(0),
// vendor
new Uint8Array([0, 0, 0, 0]),
// channelCount
(0, primitives_1.numberTo16BitUIntOrInt)(channelCount),
// sampleSize
(0, primitives_1.numberTo16BitUIntOrInt)(16),
// compressionId
(0, primitives_1.numberTo16BitUIntOrInt)(0),
// packet size
(0, primitives_1.numberTo16BitUIntOrInt)(0),
// sample rate
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(sampleRate),
// esds atom
esdsAtom,
]));
};
exports.createMp4a = createMp4a;

View File

@@ -0,0 +1,6 @@
export declare const createColr: ({ fullRange, matrixIndex, primaries, transferFunction, }: {
fullRange: boolean;
matrixIndex: number;
primaries: number;
transferFunction: number;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createColr = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
// TODO: Not used in creation of MP4 yet
const createColr = ({ fullRange, matrixIndex, primaries, transferFunction, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('colr'),
// colour_type
(0, primitives_1.stringsToUint8Array)('nclx'),
// primaries
// 1 = 'ITU-R BT.7090
new Uint8Array([0, primaries]),
// transfer_function
// 1 = 'ITU-R BT.7090
new Uint8Array([0, transferFunction]),
// matrix_index
// 1 = 'ITU-R BT.7090
new Uint8Array([0, matrixIndex]),
// full_range_flag
new Uint8Array([fullRange ? 1 : 0]),
]));
};
exports.createColr = createColr;

View File

@@ -0,0 +1,10 @@
export declare const createFtyp: ({ majorBrand, minorBrand, compatibleBrands, }: {
majorBrand: string;
minorBrand: number;
compatibleBrands: string[];
}) => Uint8Array<ArrayBufferLike>;
export declare const createIsoBaseMediaFtyp: ({ majorBrand, minorBrand, compatibleBrands, }: {
majorBrand: string;
minorBrand: number;
compatibleBrands: string[];
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createIsoBaseMediaFtyp = exports.createFtyp = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createFtyp = ({ majorBrand, minorBrand, compatibleBrands, }) => {
const type = (0, primitives_1.stringsToUint8Array)('ftyp');
const majorBrandArr = (0, primitives_1.stringsToUint8Array)(majorBrand);
const minorBrandArr = (0, primitives_1.numberTo32BitUIntOrInt)(minorBrand);
const compatibleBrandsArr = (0, matroska_utils_1.combineUint8Arrays)(compatibleBrands.map((b) => (0, primitives_1.stringsToUint8Array)(b)));
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
type,
majorBrandArr,
minorBrandArr,
compatibleBrandsArr,
]));
};
exports.createFtyp = createFtyp;
const createIsoBaseMediaFtyp = ({ majorBrand, minorBrand, compatibleBrands, }) => {
return (0, exports.createFtyp)({ compatibleBrands, majorBrand, minorBrand });
};
exports.createIsoBaseMediaFtyp = createIsoBaseMediaFtyp;

View File

@@ -0,0 +1 @@
export declare const createIlst: (items: Uint8Array[]) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createIlst = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createIlst = (items) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// name
(0, primitives_1.stringsToUint8Array)('ilst'),
// items
...items,
]));
};
exports.createIlst = createIlst;

View File

@@ -0,0 +1,2 @@
import type { MediaFn, MediaFnGeneratorInput } from '../media-fn';
export declare const createIsoBaseMedia: ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, expectedDurationInSeconds, expectedFrameRate, }: MediaFnGeneratorInput) => Promise<MediaFn>;

View File

@@ -0,0 +1,191 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createIsoBaseMedia = void 0;
const media_parser_1 = require("@remotion/media-parser");
const matroska_utils_1 = require("../matroska/matroska-utils");
const create_ftyp_1 = require("./create-ftyp");
const mp4_header_1 = require("./mp4-header");
const primitives_1 = require("./primitives");
const CONTAINER_TIMESCALE = 1000;
const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, expectedDurationInSeconds, expectedFrameRate, }) => {
const header = (0, create_ftyp_1.createIsoBaseMediaFtyp)({
compatibleBrands: ['isom', 'iso2', 'avc1', 'mp42'],
majorBrand: 'isom',
minorBrand: 512,
});
const w = await writer.createContent({
filename,
mimeType: 'video/mp4',
logLevel,
});
await w.write(header);
let globalDurationInUnits = 0;
const lowestTrackTimestamps = {};
const trackDurations = {};
const currentTracks = [];
const samplePositions = [];
const sampleChunkIndices = [];
const moovOffset = w.getWrittenByteCount();
const getPaddedMoovAtom = () => {
return (0, mp4_header_1.createPaddedMoovAtom)({
durationInUnits: globalDurationInUnits,
trackInfo: currentTracks.map((track) => {
return {
track,
durationInUnits: trackDurations[track.trackNumber] ?? 0,
samplePositions: samplePositions[track.trackNumber] ?? [],
timescale: track.timescale,
};
}),
timescale: CONTAINER_TIMESCALE,
expectedDurationInSeconds,
logLevel,
expectedFrameRate,
});
};
await w.write(getPaddedMoovAtom());
let mdatSize = 8;
const mdatSizeOffset = w.getWrittenByteCount();
await w.write((0, matroska_utils_1.combineUint8Arrays)([
// size
(0, primitives_1.numberTo32BitUIntOrInt)(mdatSize),
// type
(0, primitives_1.stringsToUint8Array)('mdat'),
]));
const updateMdatSize = async () => {
await w.updateDataAt(mdatSizeOffset, (0, primitives_1.numberTo32BitUIntOrInt)(mdatSize));
onBytesProgress(w.getWrittenByteCount());
};
const operationProm = { current: Promise.resolve() };
const updateMoov = async () => {
await w.updateDataAt(moovOffset, getPaddedMoovAtom());
onBytesProgress(w.getWrittenByteCount());
};
const addCodecPrivateToTrack = ({ trackNumber, codecPrivate, }) => {
currentTracks.forEach((track) => {
if (track.trackNumber === trackNumber) {
track.codecPrivate = codecPrivate;
}
});
};
let lastChunkWasVideo = false;
const addSample = async ({ chunk, trackNumber, isVideo, codecPrivate, }) => {
const position = w.getWrittenByteCount();
await w.write(chunk.data);
mdatSize += chunk.data.length;
onBytesProgress(w.getWrittenByteCount());
progressTracker.setPossibleLowestTimestamp(Math.min(chunk.timestamp, chunk.decodingTimestamp ?? Infinity));
progressTracker.updateTrackProgress(trackNumber, chunk.timestamp);
if (codecPrivate) {
addCodecPrivateToTrack({ trackNumber, codecPrivate });
}
const currentTrack = currentTracks.find((t) => t.trackNumber === trackNumber);
if (!currentTrack) {
throw new Error(`Tried to add sample to track ${trackNumber}, but it doesn't exist`);
}
if (!lowestTrackTimestamps[trackNumber] ||
chunk.timestamp < lowestTrackTimestamps[trackNumber]) {
lowestTrackTimestamps[trackNumber] = chunk.timestamp;
}
if (typeof lowestTrackTimestamps[trackNumber] !== 'number') {
throw new Error(`Tried to add sample to track ${trackNumber}, but it has no timestamp`);
}
const newDurationInMicroSeconds = chunk.timestamp +
(chunk.duration ?? 0) -
lowestTrackTimestamps[trackNumber];
const newDurationInTrackTimeUnits = Math.round(newDurationInMicroSeconds / (1000000 / currentTrack.timescale));
trackDurations[trackNumber] = newDurationInTrackTimeUnits;
// webcodecs returns frame duration in microseconds
const newDurationInMilliseconds = Math.round((newDurationInMicroSeconds / 1000000) * CONTAINER_TIMESCALE);
if (newDurationInMilliseconds > globalDurationInUnits) {
globalDurationInUnits = newDurationInMilliseconds;
onMillisecondsProgress(newDurationInMilliseconds);
}
if (!samplePositions[trackNumber]) {
samplePositions[trackNumber] = [];
}
if (typeof sampleChunkIndices[trackNumber] === 'undefined') {
sampleChunkIndices[trackNumber] = 0;
}
// For video, make a new chunk if it's a keyframe
if (isVideo && chunk.type === 'key') {
sampleChunkIndices[trackNumber]++;
} // For audio, make a new chunk every 22 samples, that's how bbb.mp4 is encoded
else if (!isVideo && samplePositions[trackNumber].length % 22 === 0) {
sampleChunkIndices[trackNumber]++;
}
// Need to create a new chunk if the last chunk was a different type
else if (lastChunkWasVideo !== isVideo) {
sampleChunkIndices[trackNumber]++;
}
// media parser and EncodedVideoChunk returns timestamps in microseconds
// need to normalize the timestamps to milliseconds
const samplePositionToAdd = {
isKeyframe: chunk.type === 'key',
offset: position,
chunk: sampleChunkIndices[trackNumber],
timestamp: Math.round((chunk.timestamp / 1000000) * currentTrack.timescale),
decodingTimestamp: Math.round((chunk.decodingTimestamp / 1000000) * currentTrack.timescale),
duration: Math.round(((chunk.duration ?? 0) / 1000000) * currentTrack.timescale),
size: chunk.data.length,
bigEndian: false,
chunkSize: null,
};
lastChunkWasVideo = isVideo;
samplePositions[trackNumber].push(samplePositionToAdd);
};
const addTrack = (track) => {
const trackNumber = currentTracks.length + 1;
currentTracks.push({ ...track, trackNumber });
progressTracker.registerTrack(trackNumber);
return Promise.resolve({ trackNumber });
};
const waitForFinishPromises = [];
return {
getBlob: () => {
return w.getBlob();
},
remove: async () => {
await w.remove();
},
addSample: ({ chunk, trackNumber, isVideo, codecPrivate }) => {
operationProm.current = operationProm.current.then(() => {
return addSample({
chunk,
trackNumber,
isVideo,
codecPrivate,
});
});
return operationProm.current;
},
addTrack: (track) => {
operationProm.current = operationProm.current.then(() => addTrack(track));
return operationProm.current;
},
updateTrackSampleRate: ({ sampleRate, trackNumber }) => {
currentTracks.forEach((track) => {
if (track.trackNumber === trackNumber) {
if (track.type !== 'audio') {
throw new Error(`Tried to update sample rate of track ${trackNumber}, but it's not an audio track`);
}
track.sampleRate = sampleRate;
}
});
},
addWaitForFinishPromise: (promise) => {
waitForFinishPromises.push(promise);
},
async waitForFinish() {
media_parser_1.MediaParserInternals.Log.verbose(logLevel, 'All write operations queued. Waiting for finish...');
await Promise.all(waitForFinishPromises.map((p) => p()));
media_parser_1.MediaParserInternals.Log.verbose(logLevel, 'Cleanup tasks executed');
await operationProm.current;
await updateMoov();
await updateMdatSize();
media_parser_1.MediaParserInternals.Log.verbose(logLevel, 'All write operations done. Waiting for finish...');
await w.finish();
},
};
};
exports.createIsoBaseMedia = createIsoBaseMedia;

View File

@@ -0,0 +1,5 @@
export declare const createMdia: ({ mdhd, hdlr, minf, }: {
mdhd: Uint8Array;
hdlr: Uint8Array;
minf: Uint8Array;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMdia = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createMdia = ({ mdhd, hdlr, minf, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('mdia'),
// mdhd
mdhd,
// hdlr
hdlr,
// minf
minf,
]));
};
exports.createMdia = createMdia;

View File

@@ -0,0 +1,5 @@
export declare const createMoov: ({ mvhd, traks, udta, }: {
mvhd: Uint8Array;
traks: Uint8Array[];
udta: Uint8Array;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMoov = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createMoov = ({ mvhd, traks, udta, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('moov'),
// moov atom
mvhd,
// traks
...traks,
// udta
udta,
]));
};
exports.createMoov = createMoov;

View File

@@ -0,0 +1,10 @@
export declare const createMvhd: ({ timescale, durationInUnits, rate, volume, nextTrackId, matrix, creationTime, modificationTime, }: {
timescale: number;
durationInUnits: number;
rate: number;
volume: number;
nextTrackId: number;
matrix: number[];
creationTime: number | null;
modificationTime: number | null;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMvhd = void 0;
const from_unix_timestamp_1 = require("../../from-unix-timestamp");
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createMvhd = ({ timescale, durationInUnits, rate, volume, nextTrackId, matrix, creationTime, modificationTime, }) => {
if (matrix.length !== 9) {
throw new Error('Matrix must be 9 elements long');
}
const content = (0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('mvhd'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// creation time
creationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(creationTime)),
// modification time
modificationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(modificationTime)),
// timescale
(0, primitives_1.numberTo32BitUIntOrInt)(timescale),
// duration in units, 32bit for version 0
(0, primitives_1.numberTo32BitUIntOrInt)(durationInUnits),
// rate
(0, primitives_1.floatTo16Point1632Bit)(rate),
// volume
(0, primitives_1.floatTo16Point16_16Bit)(volume),
// reserved
new Uint8Array([0, 0]),
// reserved
new Uint8Array([0, 0, 0, 0]),
// reserved
new Uint8Array([0, 0, 0, 0]),
(0, primitives_1.serializeMatrix)(matrix),
// predefined
(0, matroska_utils_1.combineUint8Arrays)(new Array(6).fill(new Uint8Array([0, 0, 0, 0]))),
// next track id
(0, primitives_1.numberTo32BitUIntOrInt)(nextTrackId),
]);
return (0, primitives_1.addSize)(content);
};
exports.createMvhd = createMvhd;

View File

@@ -0,0 +1,4 @@
export declare const createTrak: ({ tkhd, mdia, }: {
tkhd: Uint8Array;
mdia: Uint8Array;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTrak = void 0;
const truthy_1 = require("../../truthy");
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createTrak = ({ tkhd, mdia, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// name
(0, primitives_1.stringsToUint8Array)('trak'),
// tkhd
tkhd,
// mdia
mdia,
].filter(truthy_1.truthy)));
};
exports.createTrak = createTrak;

View File

@@ -0,0 +1 @@
export declare const createUdta: (children: Uint8Array) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createUdta = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createUdta = (children) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('udta'),
// children
children,
]));
};
exports.createUdta = createUdta;

View File

@@ -0,0 +1 @@
export declare const createUrlAtom: () => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createUrlAtom = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const primitives_1 = require("./primitives");
const createUrlAtom = () => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('url '),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 1]),
]));
};
exports.createUrlAtom = createUrlAtom;

View File

@@ -0,0 +1,3 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const exampleVideoSamplePositions: MediaParserInternalTypes['SamplePosition'][];
export declare const exampleAudioSamplePositions: MediaParserInternalTypes['SamplePosition'][];

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
export declare const calculateAReasonableMp4HeaderLength: ({ expectedDurationInSeconds, expectedFrameRate, }: {
expectedDurationInSeconds: number | null;
expectedFrameRate: number | null;
}) => number;

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateAReasonableMp4HeaderLength = void 0;
const calculateAReasonableMp4HeaderLength = ({ expectedDurationInSeconds, expectedFrameRate, }) => {
if (expectedDurationInSeconds === null) {
return 2048000;
}
/**
* we had a video that was 1 hour 40 minutes long and the header ended up being 3.7MB. the header approximately grows linearly to the video length in seconds, but we should reserve enough, like at least 50KB in any case.
* it's better to be safe than to fail, so let's add a 30% safety margin
*/
// This was however with 30fps, and there can also be 60fps videos, so let's
// estimate even more conservatively and estimate 60fps
const assumedFrameRate = expectedFrameRate ?? 60;
const frameRateMultiplier = assumedFrameRate / 30;
// 1h40m = 6000 seconds resulted in 3.7MB header
// So bytes per second = 3.7MB / 6000 = ~616 bytes/second
const bytesPerSecond = (3.7 * 1024 * 1024) / 6000;
// Add 20% safety margin and multiply by frame rate multiplier
const bytesWithSafetyMargin = bytesPerSecond * 1.2 * frameRateMultiplier;
// Calculate based on duration, with minimum 50KB
const calculatedBytes = Math.max(50 * 1024, Math.ceil(expectedDurationInSeconds * bytesWithSafetyMargin));
return calculatedBytes;
};
exports.calculateAReasonableMp4HeaderLength = calculateAReasonableMp4HeaderLength;

View File

@@ -0,0 +1 @@
export declare const createCmt: (comment: string) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCmt = void 0;
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
const createCmt = (comment) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// ©cmt
new Uint8Array([0xa9, 0x63, 0x6d, 0x74]),
(0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// data
(0, primitives_1.stringsToUint8Array)('data'),
// type indicator
new Uint8Array([0, 0]),
// well-known type
new Uint8Array([0, 1]),
// country indicator
new Uint8Array([0, 0]),
// language indicator
new Uint8Array([0, 0]),
// value
(0, primitives_1.stringsToUint8Array)(comment),
])),
]));
};
exports.createCmt = createCmt;

View File

@@ -0,0 +1 @@
export declare const createToo: (value: string) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createToo = void 0;
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
const createToo = (value) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type: ©too
new Uint8Array([0xa9, 0x74, 0x6f, 0x6f]),
// data
(0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// data
new Uint8Array([0x64, 0x61, 0x74, 0x61]),
// type indicator
new Uint8Array([0, 0]),
// well-known type
new Uint8Array([0, 1]),
// country indicator
new Uint8Array([0, 0]),
// language indicator
new Uint8Array([0, 0]),
// value
(0, primitives_1.stringsToUint8Array)(value),
])),
]));
};
exports.createToo = createToo;

View File

@@ -0,0 +1,6 @@
export declare const createMdhd: ({ creationTime, modificationTime, timescale, duration, }: {
creationTime: number | null;
modificationTime: number | null;
timescale: number;
duration: number;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMdhd = void 0;
const from_unix_timestamp_1 = require("../../../from-unix-timestamp");
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
const createMdhd = ({ creationTime, modificationTime, timescale, duration, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('mdhd'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// creation time
creationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(creationTime)),
// modification time
modificationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(modificationTime)),
// timescale
(0, primitives_1.numberTo32BitUIntOrInt)(timescale),
// duration
(0, primitives_1.numberTo32BitUIntOrInt)(Math.round((duration / 1000) * timescale)),
// language: unspecified
new Uint8Array([0x55, 0xc4]),
// quality
new Uint8Array([0, 0]),
]));
};
exports.createMdhd = createMdhd;

View File

@@ -0,0 +1,10 @@
import type { MediaParserLogLevel } from '@remotion/media-parser';
import type { IsoBaseMediaTrackData } from './serialize-track';
export declare const createPaddedMoovAtom: ({ durationInUnits, trackInfo, timescale, expectedDurationInSeconds, logLevel, expectedFrameRate, }: {
durationInUnits: number;
trackInfo: IsoBaseMediaTrackData[];
timescale: number;
expectedDurationInSeconds: number | null;
logLevel: MediaParserLogLevel;
expectedFrameRate: number | null;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPaddedMoovAtom = void 0;
const media_parser_1 = require("@remotion/media-parser");
const log_1 = require("../../log");
const create_ilst_1 = require("./create-ilst");
const create_moov_1 = require("./create-moov");
const create_mvhd_1 = require("./create-mvhd");
const create_udta_1 = require("./create-udta");
const header_length_1 = require("./header-length");
const create_cmt_1 = require("./ilst/create-cmt");
const create_too_1 = require("./ilst/create-too");
const primitives_1 = require("./primitives");
const serialize_track_1 = require("./serialize-track");
const create_meta_1 = require("./udta/create-meta");
const create_hdlr_1 = require("./udta/meta/create-hdlr");
const createPaddedMoovAtom = ({ durationInUnits, trackInfo, timescale, expectedDurationInSeconds, logLevel, expectedFrameRate, }) => {
const headerLength = (0, header_length_1.calculateAReasonableMp4HeaderLength)({
expectedDurationInSeconds,
expectedFrameRate,
});
if (expectedDurationInSeconds !== null) {
log_1.Log.verbose(logLevel, `Expecting duration of the video to be ${expectedDurationInSeconds} seconds, allocating ${headerLength} bytes for the MP4 header.`);
}
else {
log_1.Log.verbose(logLevel, `No duration was provided, allocating ${headerLength} bytes for the MP4 header.`);
}
return (0, primitives_1.padIsoBaseMediaBytes)((0, create_moov_1.createMoov)({
mvhd: (0, create_mvhd_1.createMvhd)({
timescale,
durationInUnits,
matrix: primitives_1.IDENTITY_MATRIX,
nextTrackId: trackInfo
.map((t) => t.track.trackNumber)
.reduce((a, b) => Math.max(a, b), 0) + 1,
rate: 1,
volume: 1,
creationTime: Date.now(),
modificationTime: Date.now(),
}),
traks: trackInfo.map((track) => {
return (0, serialize_track_1.serializeTrack)({
timescale,
track: track.track,
durationInUnits,
samplePositions: track.samplePositions,
});
}),
udta: (0, create_udta_1.createUdta)((0, create_meta_1.createMeta)({
hdlr: (0, create_hdlr_1.createHdlr)('mdir'),
ilst: (0, create_ilst_1.createIlst)([
(0, create_too_1.createToo)('WebCodecs'),
(0, create_cmt_1.createCmt)(`Made with @remotion/webcodecs ${media_parser_1.VERSION}`),
]),
})),
}), headerLength);
};
exports.createPaddedMoovAtom = createPaddedMoovAtom;

View File

@@ -0,0 +1,27 @@
export declare const stringsToUint8Array: (str: string) => Uint8Array<ArrayBuffer>;
export declare const numberTo32BitUIntOrInt: (num: number) => Uint8Array<ArrayBuffer>;
export declare const numberTo64BitUIntOrInt: (num: number | bigint) => Uint8Array<ArrayBuffer>;
export declare const numberTo32BitUIntOrIntLeading128: (num: number) => Uint8Array<ArrayBuffer>;
export declare const numberTo16BitUIntOrInt: (num: number) => Uint8Array<ArrayBuffer>;
export declare const setFixedPointSignedOrUnsigned1616Number: (num: number) => Uint8Array<ArrayBuffer>;
export declare const setFixedPointSigned230Number: (num: number) => Uint8Array<ArrayBuffer>;
export declare const addSize: (arr: Uint8Array) => Uint8Array<ArrayBufferLike>;
export declare const addLeading128Size: (arr: Uint8Array) => Uint8Array<ArrayBufferLike>;
export declare const floatTo16Point1632Bit: (number: number) => Uint8Array<ArrayBuffer>;
export declare const floatTo16Point16_16Bit: (number: number) => Uint8Array<ArrayBuffer>;
export declare const serializeMatrix: (matrix: number[]) => Uint8Array<ArrayBufferLike>;
export declare const stringToPascalString: (str: string) => Uint8Array<ArrayBuffer>;
export declare const padIsoBaseMediaBytes: (data: Uint8Array, totalLength: number) => Uint8Array<ArrayBufferLike>;
type ThreeDMatrix = [
number,
number,
number,
number,
number,
number,
number,
number,
number
];
export declare const IDENTITY_MATRIX: ThreeDMatrix;
export {};

View File

@@ -0,0 +1,147 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IDENTITY_MATRIX = exports.padIsoBaseMediaBytes = exports.stringToPascalString = exports.serializeMatrix = exports.floatTo16Point16_16Bit = exports.floatTo16Point1632Bit = exports.addLeading128Size = exports.addSize = exports.setFixedPointSigned230Number = exports.setFixedPointSignedOrUnsigned1616Number = exports.numberTo16BitUIntOrInt = exports.numberTo32BitUIntOrIntLeading128 = exports.numberTo64BitUIntOrInt = exports.numberTo32BitUIntOrInt = exports.stringsToUint8Array = void 0;
const matroska_utils_1 = require("../matroska/matroska-utils");
const stringsToUint8Array = (str) => {
return new TextEncoder().encode(str);
};
exports.stringsToUint8Array = stringsToUint8Array;
const numberTo32BitUIntOrInt = (num) => {
return new Uint8Array([
(num >> 24) & 0xff,
(num >> 16) & 0xff,
(num >> 8) & 0xff,
num & 0xff,
]);
};
exports.numberTo32BitUIntOrInt = numberTo32BitUIntOrInt;
const numberTo64BitUIntOrInt = (num) => {
const bigNum = BigInt(num);
return new Uint8Array([
Number((bigNum >> 56n) & 0xffn),
Number((bigNum >> 48n) & 0xffn),
Number((bigNum >> 40n) & 0xffn),
Number((bigNum >> 32n) & 0xffn),
Number((bigNum >> 24n) & 0xffn),
Number((bigNum >> 16n) & 0xffn),
Number((bigNum >> 8n) & 0xffn),
Number(bigNum & 0xffn),
]);
};
exports.numberTo64BitUIntOrInt = numberTo64BitUIntOrInt;
const numberTo32BitUIntOrIntLeading128 = (num) => {
const arr = [
(num >> 24) & 0xff,
(num >> 16) & 0xff,
(num >> 8) & 0xff,
num & 0xff,
];
for (const i in arr) {
if (arr[i] === 0) {
arr[i] = 128;
}
else {
break;
}
}
return new Uint8Array(arr);
};
exports.numberTo32BitUIntOrIntLeading128 = numberTo32BitUIntOrIntLeading128;
const numberTo16BitUIntOrInt = (num) => {
return new Uint8Array([(num >> 8) & 0xff, num & 0xff]);
};
exports.numberTo16BitUIntOrInt = numberTo16BitUIntOrInt;
const setFixedPointSignedOrUnsigned1616Number = (num) => {
const val = Math.round(num * 2 ** 16);
return (0, exports.numberTo32BitUIntOrInt)(val);
};
exports.setFixedPointSignedOrUnsigned1616Number = setFixedPointSignedOrUnsigned1616Number;
const setFixedPointSigned230Number = (num) => {
const val = Math.round(num * 2 ** 30);
return (0, exports.numberTo32BitUIntOrInt)(val);
};
exports.setFixedPointSigned230Number = setFixedPointSigned230Number;
const addSize = (arr) => {
return (0, matroska_utils_1.combineUint8Arrays)([(0, exports.numberTo32BitUIntOrInt)(arr.length + 4), arr]);
};
exports.addSize = addSize;
const addLeading128Size = (arr) => {
return (0, matroska_utils_1.combineUint8Arrays)([
(0, exports.numberTo32BitUIntOrIntLeading128)(arr.length),
arr,
]);
};
exports.addLeading128Size = addLeading128Size;
const floatTo16Point1632Bit = (number) => {
// Ensure the number has exactly 2 decimal places
const fixedNumber = Number(number.toFixed(2));
// Create a new Uint8Array of 4 bytes
const result = new Uint8Array(4);
// Extract digits
const tens = Math.floor(fixedNumber / 10);
const ones = Math.floor(fixedNumber % 10);
const tenths = Math.floor((fixedNumber * 10) % 10);
const hundredths = Math.floor((fixedNumber * 100) % 10);
// Assign to array
result[0] = tens;
result[1] = ones;
result[2] = tenths;
result[3] = hundredths;
return result;
};
exports.floatTo16Point1632Bit = floatTo16Point1632Bit;
const floatTo16Point16_16Bit = (number) => {
// Ensure the number has exactly 2 decimal places
const fixedNumber = Number(number.toFixed(2));
// Create a new Uint8Array of 4 bytes
const result = new Uint8Array(2);
// Extract digits
const ones = Math.floor(fixedNumber % 10);
const tenths = Math.floor((fixedNumber * 10) % 10);
// Assign to array
result[0] = ones;
result[1] = tenths;
return result;
};
exports.floatTo16Point16_16Bit = floatTo16Point16_16Bit;
const serializeMatrix = (matrix) => {
return (0, matroska_utils_1.combineUint8Arrays)([
(0, exports.setFixedPointSignedOrUnsigned1616Number)(matrix[0]),
(0, exports.setFixedPointSignedOrUnsigned1616Number)(matrix[1]),
(0, exports.setFixedPointSigned230Number)(matrix[2]),
(0, exports.setFixedPointSignedOrUnsigned1616Number)(matrix[3]),
(0, exports.setFixedPointSignedOrUnsigned1616Number)(matrix[4]),
(0, exports.setFixedPointSigned230Number)(matrix[5]),
(0, exports.setFixedPointSignedOrUnsigned1616Number)(matrix[6]),
(0, exports.setFixedPointSignedOrUnsigned1616Number)(matrix[7]),
(0, exports.setFixedPointSigned230Number)(matrix[8]),
]);
};
exports.serializeMatrix = serializeMatrix;
const stringToPascalString = (str) => {
// Create a fixed 32-byte Uint8Array
const buffer = new Uint8Array(32);
// Convert the string characters to bytes
for (let i = 0; i < Math.min(str.length, 32); i++) {
buffer[i] = str.charCodeAt(i);
}
return buffer;
};
exports.stringToPascalString = stringToPascalString;
const padIsoBaseMediaBytes = (data, totalLength) => {
if (data.length - 8 > totalLength) {
throw new Error(`Data is longer than the total length: ${data.length - 8} > ${totalLength}. Set the 'expectedDurationInSeconds' value to avoid this problem: https://www.remotion.dev/docs/webcodecs/convert-media#expecteddurationinseconds`);
}
if (data.length - 8 === totalLength) {
return data;
}
return (0, matroska_utils_1.combineUint8Arrays)([
data,
(0, exports.addSize)((0, matroska_utils_1.combineUint8Arrays)([
(0, exports.stringsToUint8Array)('free'),
new Uint8Array(totalLength - (data.length - 8)),
])),
]);
};
exports.padIsoBaseMediaBytes = padIsoBaseMediaBytes;
exports.IDENTITY_MATRIX = [1, 0, 0, 0, 1, 0, 0, 0, 1];

View File

@@ -0,0 +1,9 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
import type { MakeTrackAudio, MakeTrackVideo } from '../make-track-info';
export type IsoBaseMediaTrackData = {
track: MakeTrackVideo | MakeTrackAudio;
durationInUnits: number;
samplePositions: MediaParserInternalTypes['SamplePosition'][];
timescale: number;
};
export declare const serializeTrack: ({ track, durationInUnits, samplePositions, timescale, }: IsoBaseMediaTrackData) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.serializeTrack = void 0;
const create_codec_specific_data_1 = require("./codec-specific/create-codec-specific-data");
const create_mdia_1 = require("./create-mdia");
const create_trak_1 = require("./create-trak");
const create_mdhd_1 = require("./mdia/create-mdhd");
const primitives_1 = require("./primitives");
const create_tkhd_1 = require("./trak/create-tkhd");
const create_minf_1 = require("./trak/mdia/create-minf");
const create_smhd_1 = require("./trak/mdia/minf/create-smhd");
const create_stbl_1 = require("./trak/mdia/minf/create-stbl");
const create_vmhd_1 = require("./trak/mdia/minf/create-vmhd");
const create_hdlr_1 = require("./udta/meta/create-hdlr");
const serializeTrack = ({ track, durationInUnits, samplePositions, timescale, }) => {
if (track.codec !== 'h264' &&
track.codec !== 'h265' &&
track.codec !== 'aac') {
throw new Error('Currently only H.264 and AAC is supported');
}
return (0, create_trak_1.createTrak)({
tkhd: track.codec === 'aac'
? (0, create_tkhd_1.createTkhdForAudio)({
creationTime: Date.now(),
flags: create_tkhd_1.TKHD_FLAGS.TRACK_ENABLED | create_tkhd_1.TKHD_FLAGS.TRACK_IN_MOVIE,
modificationTime: Date.now(),
duration: durationInUnits,
trackId: track.trackNumber,
volume: 1,
timescale,
})
: track.type === 'video'
? (0, create_tkhd_1.createTkhdForVideo)({
creationTime: Date.now(),
modificationTime: Date.now(),
duration: durationInUnits,
flags: create_tkhd_1.TKHD_FLAGS.TRACK_ENABLED | create_tkhd_1.TKHD_FLAGS.TRACK_IN_MOVIE,
height: track.height,
width: track.width,
matrix: primitives_1.IDENTITY_MATRIX,
trackId: track.trackNumber,
volume: 0,
timescale,
})
: new Uint8Array((0, primitives_1.stringsToUint8Array)('wrong')),
mdia: (0, create_mdia_1.createMdia)({
mdhd: (0, create_mdhd_1.createMdhd)({
creationTime: null,
modificationTime: null,
duration: durationInUnits,
timescale: track.timescale,
}),
hdlr: track.type === 'video' ? (0, create_hdlr_1.createHdlr)('video') : (0, create_hdlr_1.createHdlr)('audio'),
minf: (0, create_minf_1.createMinf)({
stblAtom: (0, create_stbl_1.createStbl)({
samplePositions,
isVideo: track.type === 'video',
codecSpecificData: (0, create_codec_specific_data_1.createCodecSpecificData)(track),
}),
vmhdAtom: track.type === 'audio' ? (0, create_smhd_1.createSmhd)() : (0, create_vmhd_1.createVmhd)(),
}),
}),
});
};
exports.serializeTrack = serializeTrack;

View File

@@ -0,0 +1,27 @@
export declare const TKHD_FLAGS: {
TRACK_ENABLED: number;
TRACK_IN_MOVIE: number;
TRACK_IN_PREVIEW: number;
TRACK_IN_POSTER: number;
};
export declare const createTkhdForAudio: ({ creationTime, modificationTime, flags, trackId, duration, volume, timescale, }: {
creationTime: number | null;
modificationTime: number | null;
flags: number;
trackId: number;
duration: number;
volume: number;
timescale: number;
}) => Uint8Array<ArrayBufferLike>;
export declare const createTkhdForVideo: ({ creationTime, modificationTime, duration, trackId, volume, matrix, width, height, flags, timescale, }: {
creationTime: number | null;
modificationTime: number | null;
trackId: number;
duration: number;
volume: number;
matrix: number[];
width: number;
height: number;
flags: number;
timescale: number;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTkhdForVideo = exports.createTkhdForAudio = exports.TKHD_FLAGS = void 0;
const from_unix_timestamp_1 = require("../../../from-unix-timestamp");
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
exports.TKHD_FLAGS = {
TRACK_ENABLED: 0x000001,
TRACK_IN_MOVIE: 0x000002,
TRACK_IN_PREVIEW: 0x000004,
TRACK_IN_POSTER: 0x000008,
};
const createTkhdForAudio = ({ creationTime, modificationTime, flags, trackId, duration, volume, timescale, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// name
(0, primitives_1.stringsToUint8Array)('tkhd'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, flags]),
// creation time
creationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(creationTime)),
// modification time
modificationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(modificationTime)),
// trackId
(0, primitives_1.numberTo32BitUIntOrInt)(trackId),
// reserved
new Uint8Array([0, 0, 0, 0]),
// duration
(0, primitives_1.numberTo32BitUIntOrInt)(Math.round((duration / 1000) * timescale)),
// reserved
new Uint8Array([0, 0, 0, 0]),
new Uint8Array([0, 0, 0, 0]),
// layer
new Uint8Array([0, 0]),
// alternate group, 1 = 'sound'
new Uint8Array([0, 1]),
// volume
(0, primitives_1.floatTo16Point16_16Bit)(volume),
// reserved
new Uint8Array([0, 0]),
// matrix
(0, primitives_1.serializeMatrix)(primitives_1.IDENTITY_MATRIX),
// width
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(0),
// height
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(0),
]));
};
exports.createTkhdForAudio = createTkhdForAudio;
const createTkhdForVideo = ({ creationTime, modificationTime, duration, trackId, volume, matrix, width, height, flags, timescale, }) => {
const content = (0, matroska_utils_1.combineUint8Arrays)([
// name
(0, primitives_1.stringsToUint8Array)('tkhd'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, flags]),
// creation time
creationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(creationTime)),
// modification time
modificationTime === null
? (0, primitives_1.numberTo32BitUIntOrInt)(0)
: (0, primitives_1.numberTo32BitUIntOrInt)((0, from_unix_timestamp_1.fromUnixTimestamp)(modificationTime)),
// trackId
(0, primitives_1.numberTo32BitUIntOrInt)(trackId),
// reserved
new Uint8Array([0, 0, 0, 0]),
// duration
(0, primitives_1.numberTo32BitUIntOrInt)((duration / 1000) * timescale),
// reserved
new Uint8Array([0, 0, 0, 0]),
new Uint8Array([0, 0, 0, 0]),
// layer
new Uint8Array([0, 0]),
// alternate group, 0 = 'video'
new Uint8Array([0, 0]),
// volume
(0, primitives_1.floatTo16Point16_16Bit)(volume),
// reserved
new Uint8Array([0, 0]),
// matrix
(0, primitives_1.serializeMatrix)(matrix),
// width
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(width),
// height
(0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(height),
]);
return (0, primitives_1.addSize)(content);
};
exports.createTkhdForVideo = createTkhdForVideo;

View File

@@ -0,0 +1,4 @@
export declare const createMinf: ({ vmhdAtom, stblAtom, }: {
vmhdAtom: Uint8Array;
stblAtom: Uint8Array;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMinf = void 0;
const matroska_utils_1 = require("../../../matroska/matroska-utils");
const primitives_1 = require("../../primitives");
const create_dinf_1 = require("./minf/create-dinf");
const createMinf = ({ vmhdAtom, stblAtom, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('minf'),
// vmhd
vmhdAtom,
// dinf
(0, create_dinf_1.createDinf)(),
// stbl
stblAtom,
]));
};
exports.createMinf = createMinf;

View File

@@ -0,0 +1 @@
export declare const createDinf: () => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createDinf = void 0;
const matroska_utils_1 = require("../../../../matroska/matroska-utils");
const primitives_1 = require("../../../primitives");
const createDinf = () => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.stringsToUint8Array)('dinf'),
(0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.stringsToUint8Array)('dref'),
new Uint8Array([0]), // version
new Uint8Array([0, 0, 0]), // flags
new Uint8Array([0, 0, 0, 1]), // entry count
(0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.stringsToUint8Array)('url '),
new Uint8Array([0]), // version
new Uint8Array([0, 0, 1]), // flags
])),
])),
]));
};
exports.createDinf = createDinf;

View File

@@ -0,0 +1 @@
export declare const createSmhd: () => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSmhd = void 0;
const matroska_utils_1 = require("../../../../matroska/matroska-utils");
const primitives_1 = require("../../../primitives");
const createSmhd = () => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('smhd'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// balance
new Uint8Array([0, 0]),
// reserved
new Uint8Array([0, 0]),
]));
};
exports.createSmhd = createSmhd;

View File

@@ -0,0 +1,6 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const createStbl: ({ samplePositions, codecSpecificData, isVideo, }: {
samplePositions: MediaParserInternalTypes["SamplePosition"][];
codecSpecificData: Uint8Array;
isVideo: boolean;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStbl = void 0;
const truthy_1 = require("../../../../../truthy");
const matroska_utils_1 = require("../../../../matroska/matroska-utils");
const primitives_1 = require("../../../primitives");
const create_ctts_1 = require("./stbl/create-ctts");
const create_stco_1 = require("./stbl/create-stco");
const create_stsc_1 = require("./stbl/create-stsc");
const create_stss_1 = require("./stbl/create-stss");
const create_stsz_1 = require("./stbl/create-stsz");
const create_stts_1 = require("./stbl/create-stts");
const create_avc1_1 = require("./stbl/stsd/create-avc1");
const createStbl = ({ samplePositions, codecSpecificData, isVideo, }) => {
// For stts:
// https://developer.apple.com/documentation/quicktime-file-format/time-to-sample_atom
// The sample entries are ordered by time stamps; therefore, the deltas are all nonnegative.
// For the other tables, there doesn't seem to be a requirement for them to be sorted
// -> ordering the sample positions by dts
const sorted = samplePositions
.slice()
.sort((a, b) => a.decodingTimestamp - b.decodingTimestamp);
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.stringsToUint8Array)('stbl'),
(0, create_avc1_1.createStsdData)(codecSpecificData),
(0, create_stts_1.createSttsAtom)(sorted),
isVideo ? (0, create_stss_1.createStss)(samplePositions) : null,
(0, create_ctts_1.createCttsBox)(samplePositions),
(0, create_stsc_1.createStsc)(samplePositions),
(0, create_stsz_1.createStsz)(samplePositions),
(0, create_stco_1.createStcoAtom)(samplePositions),
isVideo
? null
: new Uint8Array([
0x00, 0x00, 0x00, 0x1a, 0x73, 0x67, 0x70, 0x64, 0x01, 0x00, 0x00,
0x00, 0x72, 0x6f, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1c, 0x73, 0x62, 0x67,
0x70, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6f, 0x6c, 0x6c, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x0a, 0x19, 0x00, 0x00, 0x00, 0x01,
]),
].filter(truthy_1.truthy)));
};
exports.createStbl = createStbl;

View File

@@ -0,0 +1 @@
export declare const createVmhd: () => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createVmhd = void 0;
const matroska_utils_1 = require("../../../../matroska/matroska-utils");
const primitives_1 = require("../../../primitives");
const createVmhd = () => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('vmhd'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 1]),
// graphics mode, 0 = copy
new Uint8Array([0, 0]),
// opcolor
new Uint8Array([0, 0, 0, 0, 0, 0]),
]));
};
exports.createVmhd = createVmhd;

View File

@@ -0,0 +1,2 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const createCttsBox: (samplePositions: MediaParserInternalTypes["SamplePosition"][]) => Uint8Array<ArrayBufferLike> | null;

View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCttsBox = void 0;
const matroska_utils_1 = require("../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../primitives");
const makeEntry = (entry) => {
return (0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.numberTo32BitUIntOrInt)(entry.sampleCount),
(0, primitives_1.numberTo32BitUIntOrInt)(entry.sampleOffset),
]);
};
const createCttsBox = (samplePositions) => {
const offsets = samplePositions.map((s) => s.timestamp - s.decodingTimestamp);
const entries = [];
let lastOffset = null;
for (const offset of offsets) {
if (lastOffset === offset) {
entries[entries.length - 1].sampleCount++;
}
else {
entries.push({
sampleCount: 1,
sampleOffset: offset,
});
}
lastOffset = offset;
}
const needsCtts = entries.length > 0 && entries.some((e) => e.sampleOffset !== 0);
if (!needsCtts) {
return null;
}
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('ctts'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// entry count
(0, primitives_1.numberTo32BitUIntOrInt)(entries.length),
// entries
...entries.map((e) => makeEntry(e)),
]));
};
exports.createCttsBox = createCttsBox;

View File

@@ -0,0 +1,2 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const createStcoAtom: (samplePositions: MediaParserInternalTypes["SamplePosition"][]) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStcoAtom = void 0;
const matroska_utils_1 = require("../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../primitives");
const createStcoAtom = (samplePositions) => {
const chunkOffsets = [];
let lastChunk;
let needs64Bit = false;
for (const sample of samplePositions) {
if (lastChunk !== sample.chunk) {
chunkOffsets.push(sample.offset);
}
if (sample.offset > 2 ** 32) {
needs64Bit = true;
}
lastChunk = sample.chunk;
}
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)(needs64Bit ? 'co64' : 'stco'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// number of entries
(0, primitives_1.numberTo32BitUIntOrInt)(chunkOffsets.length),
// chunk offsets
(0, matroska_utils_1.combineUint8Arrays)(chunkOffsets.map((offset) => needs64Bit
? (0, primitives_1.numberTo64BitUIntOrInt)(offset)
: (0, primitives_1.numberTo32BitUIntOrInt)(offset))),
]));
};
exports.createStcoAtom = createStcoAtom;

View File

@@ -0,0 +1,2 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const createStsc: (samplePositions: MediaParserInternalTypes["SamplePosition"][]) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStsc = void 0;
const matroska_utils_1 = require("../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../primitives");
const createEntry = (entry) => {
return (0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.numberTo32BitUIntOrInt)(entry.firstChunk),
(0, primitives_1.numberTo32BitUIntOrInt)(entry.samplesPerChunk),
(0, primitives_1.numberTo32BitUIntOrInt)(entry.sampleDescriptionIndex),
]);
};
const createStsc = (samplePositions) => {
const entries = [];
const deduplicateLastEntry = () => {
const lastEntry = entries[entries.length - 1];
const secondToLastEntry = entries[entries.length - 2];
if (lastEntry &&
secondToLastEntry &&
lastEntry.samplesPerChunk === secondToLastEntry.samplesPerChunk &&
lastEntry.sampleDescriptionIndex ===
secondToLastEntry.sampleDescriptionIndex) {
const lastIndex = entries.length - 1;
entries.length = lastIndex;
}
};
let lastChunk;
for (const samplePosition of samplePositions) {
if (samplePosition.chunk === lastChunk) {
entries[entries.length - 1].samplesPerChunk++;
}
else {
deduplicateLastEntry();
entries.push({
firstChunk: samplePosition.chunk,
samplesPerChunk: 1,
sampleDescriptionIndex: 1,
});
lastChunk = samplePosition.chunk;
}
}
deduplicateLastEntry();
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('stsc'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// entry count
(0, primitives_1.numberTo32BitUIntOrInt)(entries.length),
// entries
...entries.map((e) => createEntry(e)),
]));
};
exports.createStsc = createStsc;

View File

@@ -0,0 +1,2 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const createStss: (samplePositions: MediaParserInternalTypes["SamplePosition"][]) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStss = void 0;
const matroska_utils_1 = require("../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../primitives");
const createStss = (samplePositions) => {
const samples = samplePositions
.map((sample, i) => [sample.isKeyframe, i])
.filter((s) => s[0])
.map((s) => s[1] + 1);
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('stss'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// entry count
(0, primitives_1.numberTo32BitUIntOrInt)(samples.length),
...samples.map((sample) => (0, primitives_1.numberTo32BitUIntOrInt)(sample)),
]));
};
exports.createStss = createStss;

View File

@@ -0,0 +1,2 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const createStsz: (samplePositions: MediaParserInternalTypes["SamplePosition"][]) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStsz = void 0;
const matroska_utils_1 = require("../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../primitives");
const createStsz = (samplePositions) => {
const sampleSizes = samplePositions.map((samplePosition) => samplePosition.size);
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('stsz'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// sample size
// Possible optimization for the future: If all sizes are the same, we don't have to list them all out
// https://developer.apple.com/documentation/quicktime-file-format/sample_size_atom
(0, primitives_1.numberTo32BitUIntOrInt)(0),
// number of entries
(0, primitives_1.numberTo32BitUIntOrInt)(sampleSizes.length),
// sample sizes
...sampleSizes.map((size) => (0, primitives_1.numberTo32BitUIntOrInt)(size)),
]));
};
exports.createStsz = createStsz;

View File

@@ -0,0 +1,2 @@
import type { MediaParserInternalTypes } from '@remotion/media-parser';
export declare const createSttsAtom: (samplePositions: MediaParserInternalTypes["SamplePosition"][]) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSttsAtom = void 0;
const matroska_utils_1 = require("../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../primitives");
const makeEntry = (entry) => {
if (entry.sampleOffset < 0) {
throw new Error('negative sample offset in stts ' + entry.sampleOffset);
}
return (0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.numberTo32BitUIntOrInt)(entry.sampleCount),
(0, primitives_1.numberTo32BitUIntOrInt)(entry.sampleOffset),
]);
};
const createSttsAtom = (samplePositions) => {
let lastDuration = null;
const durations = samplePositions.map((_, i, a) => {
// TODO: Why does 0 appear here?
if (a[i].duration === undefined || a[i].duration === 0) {
if (a[i + 1] === undefined) {
return (a[i].decodingTimestamp -
(a[i - 1]?.decodingTimestamp ?? a[i].decodingTimestamp));
}
return a[i + 1].decodingTimestamp - a[i].decodingTimestamp;
}
return a[i].duration;
});
const entries = [];
for (const duration of durations) {
if (duration === lastDuration) {
entries[entries.length - 1].sampleCount++;
}
else {
entries.push({
sampleCount: 1,
sampleOffset: duration,
});
}
lastDuration = duration;
}
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('stts'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// entry count
(0, primitives_1.numberTo32BitUIntOrInt)(entries.length),
// entries
...entries.map((e) => makeEntry(e)),
]));
};
exports.createSttsAtom = createSttsAtom;

View File

@@ -0,0 +1 @@
export declare const createStsdData: (codecSpecificData: Uint8Array) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStsdData = void 0;
const matroska_utils_1 = require("../../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../../primitives");
const createStsdData = (codecSpecificData) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('stsd'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// entry count
new Uint8Array([0, 0, 0, 1]),
// entry
codecSpecificData,
]));
};
exports.createStsdData = createStsdData;

View File

@@ -0,0 +1 @@
export declare const createAvccBox: (privateData: Uint8Array | null) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAvccBox = void 0;
const matroska_utils_1 = require("../../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../../primitives");
const createAvccBox = (privateData) => {
if (!privateData) {
throw new Error('privateData is required');
}
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('avcC'),
privateData,
]));
};
exports.createAvccBox = createAvccBox;

View File

@@ -0,0 +1 @@
export declare const createHvccBox: (privateData: Uint8Array | null) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createHvccBox = void 0;
const matroska_utils_1 = require("../../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../../primitives");
const createHvccBox = (privateData) => {
if (!privateData) {
throw new Error('privateData is required');
}
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('hvcC'),
privateData,
]));
};
exports.createHvccBox = createHvccBox;

View File

@@ -0,0 +1 @@
export declare const createPasp: (x: number, y: number) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPasp = void 0;
const matroska_utils_1 = require("../../../../../../matroska/matroska-utils");
const primitives_1 = require("../../../../../primitives");
const createPasp = (x, y) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
(0, primitives_1.stringsToUint8Array)('pasp'),
(0, primitives_1.numberTo32BitUIntOrInt)(x),
(0, primitives_1.numberTo32BitUIntOrInt)(y),
]));
};
exports.createPasp = createPasp;

View File

@@ -0,0 +1,4 @@
export declare const createMeta: ({ hdlr, ilst, }: {
hdlr: Uint8Array;
ilst: Uint8Array;
}) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMeta = void 0;
const matroska_utils_1 = require("../../matroska/matroska-utils");
const primitives_1 = require("../primitives");
const createMeta = ({ hdlr, ilst, }) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('meta'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// hdlr
hdlr,
// ilst
ilst,
]));
};
exports.createMeta = createMeta;

View File

@@ -0,0 +1 @@
export declare const createHdlr: (type: "video" | "audio" | "mdir") => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createHdlr = void 0;
const matroska_utils_1 = require("../../../matroska/matroska-utils");
const primitives_1 = require("../../primitives");
const createHdlr = (type) => {
return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
// type
(0, primitives_1.stringsToUint8Array)('hdlr'),
// version
new Uint8Array([0]),
// flags
new Uint8Array([0, 0, 0]),
// pre_defined
new Uint8Array([0, 0, 0, 0]),
// handler_type
(0, primitives_1.stringsToUint8Array)(type === 'mdir' ? 'mdir' : type === 'video' ? 'vide' : 'soun'),
// reserved
type === 'mdir'
? (0, primitives_1.numberTo32BitUIntOrInt)(1634758764)
: new Uint8Array([0, 0, 0, 0]),
new Uint8Array([0, 0, 0, 0]),
new Uint8Array([0, 0, 0, 0]),
// name
(0, primitives_1.stringsToUint8Array)(type === 'mdir'
? '\0'
: type === 'video'
? 'VideoHandler\0'
: 'SoundHandler\0'),
]));
};
exports.createHdlr = createHdlr;