init commit
This commit is contained in:
18
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/after-manifest-fetch.d.ts
generated
vendored
Normal file
18
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/after-manifest-fetch.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import type { MediaParserLogLevel } from '../../log';
|
||||
import type { MediaParserReaderInterface } from '../../readers/reader';
|
||||
import type { CanSkipTracksState } from '../../state/can-skip-tracks';
|
||||
import type { M3uState } from '../../state/m3u-state';
|
||||
import type { MediaParserOnAudioTrack } from '../../webcodec-sample-types';
|
||||
import type { SelectM3uAssociatedPlaylistsFn, SelectM3uStreamFn } from './select-stream';
|
||||
import type { M3uStructure } from './types';
|
||||
export declare const afterManifestFetch: ({ structure, m3uState, src, selectM3uStreamFn, logLevel, selectAssociatedPlaylistsFn, readerInterface, onAudioTrack, canSkipTracks, }: {
|
||||
structure: M3uStructure;
|
||||
m3uState: M3uState;
|
||||
src: string;
|
||||
selectM3uStreamFn: SelectM3uStreamFn;
|
||||
selectAssociatedPlaylistsFn: SelectM3uAssociatedPlaylistsFn;
|
||||
logLevel: MediaParserLogLevel;
|
||||
readerInterface: MediaParserReaderInterface;
|
||||
onAudioTrack: MediaParserOnAudioTrack | null;
|
||||
canSkipTracks: CanSkipTracksState;
|
||||
}) => Promise<void>;
|
||||
56
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/after-manifest-fetch.js
generated
vendored
Normal file
56
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/after-manifest-fetch.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.afterManifestFetch = void 0;
|
||||
const log_1 = require("../../log");
|
||||
const fetch_m3u8_stream_1 = require("./fetch-m3u8-stream");
|
||||
const get_streams_1 = require("./get-streams");
|
||||
const select_stream_1 = require("./select-stream");
|
||||
const afterManifestFetch = async ({ structure, m3uState, src, selectM3uStreamFn, logLevel, selectAssociatedPlaylistsFn, readerInterface, onAudioTrack, canSkipTracks, }) => {
|
||||
const independentSegments = (0, get_streams_1.isIndependentSegments)(structure);
|
||||
const streams = (0, get_streams_1.getM3uStreams)({ structure, originalSrc: src, readerInterface });
|
||||
// Handle single media playlists (not master playlists):
|
||||
// 1. If !independentSegments: Old-style single playlist without segment independence
|
||||
// 2. If streams === null: Single media playlist (has EXT-X-INDEPENDENT-SEGMENTS but no EXT-X-STREAM-INF)
|
||||
// Both cases should iterate over the current URL as the media playlist
|
||||
if (!independentSegments || streams === null) {
|
||||
if (!src) {
|
||||
throw new Error('No src');
|
||||
}
|
||||
m3uState.setSelectedMainPlaylist({
|
||||
type: 'initial-url',
|
||||
url: src,
|
||||
});
|
||||
return m3uState.setReadyToIterateOverM3u();
|
||||
}
|
||||
const selectedPlaylist = await (0, select_stream_1.selectStream)({ streams, fn: selectM3uStreamFn });
|
||||
if (!selectedPlaylist.dimensions) {
|
||||
throw new Error('Stream does not have a resolution');
|
||||
}
|
||||
m3uState.setSelectedMainPlaylist({
|
||||
type: 'selected-stream',
|
||||
stream: selectedPlaylist,
|
||||
});
|
||||
const skipAudioTracks = onAudioTrack === null && canSkipTracks.doFieldsNeedTracks() === false;
|
||||
const associatedPlaylists = await (0, select_stream_1.selectAssociatedPlaylists)({
|
||||
playlists: selectedPlaylist.associatedPlaylists,
|
||||
fn: selectAssociatedPlaylistsFn,
|
||||
skipAudioTracks,
|
||||
});
|
||||
m3uState.setAssociatedPlaylists(associatedPlaylists);
|
||||
const playlistUrls = [
|
||||
selectedPlaylist.src,
|
||||
...associatedPlaylists.map((p) => p.src),
|
||||
];
|
||||
const struc = await Promise.all(playlistUrls.map(async (url) => {
|
||||
log_1.Log.verbose(logLevel, `Fetching playlist ${url}`);
|
||||
const boxes = await (0, fetch_m3u8_stream_1.fetchM3u8Stream)({ url, readerInterface });
|
||||
return {
|
||||
type: 'm3u-playlist',
|
||||
boxes,
|
||||
src: url,
|
||||
};
|
||||
}));
|
||||
structure.boxes.push(...struc);
|
||||
m3uState.setReadyToIterateOverM3u();
|
||||
};
|
||||
exports.afterManifestFetch = afterManifestFetch;
|
||||
6
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/fetch-m3u8-stream.d.ts
generated
vendored
Normal file
6
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/fetch-m3u8-stream.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { MediaParserReaderInterface } from '../../readers/reader';
|
||||
import type { M3uBox } from './types';
|
||||
export declare const fetchM3u8Stream: ({ url, readerInterface, }: {
|
||||
url: string;
|
||||
readerInterface: MediaParserReaderInterface;
|
||||
}) => Promise<M3uBox[]>;
|
||||
14
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/fetch-m3u8-stream.js
generated
vendored
Normal file
14
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/fetch-m3u8-stream.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fetchM3u8Stream = void 0;
|
||||
const parse_m3u8_text_1 = require("./parse-m3u8-text");
|
||||
const fetchM3u8Stream = async ({ url, readerInterface, }) => {
|
||||
const text = await readerInterface.readWholeAsText(url);
|
||||
const lines = text.split('\n');
|
||||
const boxes = [];
|
||||
for (const line of lines) {
|
||||
(0, parse_m3u8_text_1.parseM3u8Text)(line.trim(), boxes);
|
||||
}
|
||||
return boxes;
|
||||
};
|
||||
exports.fetchM3u8Stream = fetchM3u8Stream;
|
||||
13
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/first-sample-in-m3u-chunk.d.ts
generated
vendored
Normal file
13
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/first-sample-in-m3u-chunk.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { MediaParserController } from '../../controller/media-parser-controller';
|
||||
import type { M3uState } from '../../state/m3u-state';
|
||||
import type { MediaParserOnVideoSample, MediaParserVideoSample } from '../../webcodec-sample-types';
|
||||
export declare const considerSeekBasedOnChunk: ({ sample, parentController, childController, callback, m3uState, playlistUrl, subtractChunks, chunkIndex, }: {
|
||||
sample: MediaParserVideoSample;
|
||||
callback: MediaParserOnVideoSample;
|
||||
parentController: MediaParserController;
|
||||
childController: MediaParserController;
|
||||
playlistUrl: string;
|
||||
m3uState: M3uState;
|
||||
subtractChunks: number;
|
||||
chunkIndex: number | null;
|
||||
}) => Promise<void>;
|
||||
26
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/first-sample-in-m3u-chunk.js
generated
vendored
Normal file
26
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/first-sample-in-m3u-chunk.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.considerSeekBasedOnChunk = void 0;
|
||||
const webcodecs_timescale_1 = require("../../webcodecs-timescale");
|
||||
const considerSeekBasedOnChunk = async ({ sample, parentController, childController, callback, m3uState, playlistUrl, subtractChunks, chunkIndex, }) => {
|
||||
const pendingSeek = m3uState.getSeekToSecondsToProcess(playlistUrl);
|
||||
// If there is not even a seek to consider, just call the callback
|
||||
if (pendingSeek === null) {
|
||||
await callback(sample);
|
||||
return;
|
||||
}
|
||||
const timestamp = Math.min(sample.decodingTimestamp / webcodecs_timescale_1.WEBCODECS_TIMESCALE, sample.timestamp / webcodecs_timescale_1.WEBCODECS_TIMESCALE);
|
||||
// Already too far, now we should go to the previous chunk
|
||||
if (timestamp > pendingSeek.targetTime &&
|
||||
chunkIndex !== null &&
|
||||
chunkIndex > 0) {
|
||||
m3uState.setNextSeekShouldSubtractChunks(playlistUrl, subtractChunks + 1);
|
||||
parentController.seek(pendingSeek.targetTime);
|
||||
return;
|
||||
}
|
||||
// We are good, we have not gone too far! Don't emit sample and seek and clear pending seek
|
||||
childController.seek(pendingSeek.targetTime);
|
||||
m3uState.setNextSeekShouldSubtractChunks(playlistUrl, 0);
|
||||
m3uState.setSeekToSecondsToProcess(playlistUrl, null);
|
||||
};
|
||||
exports.considerSeekBasedOnChunk = considerSeekBasedOnChunk;
|
||||
7
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-chunks.d.ts
generated
vendored
Normal file
7
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-chunks.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { M3uPlaylist } from './types';
|
||||
export type M3uChunk = {
|
||||
duration: number;
|
||||
url: string;
|
||||
isHeader: boolean;
|
||||
};
|
||||
export declare const getChunks: (playlist: M3uPlaylist) => M3uChunk[];
|
||||
24
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-chunks.js
generated
vendored
Normal file
24
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-chunks.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getChunks = void 0;
|
||||
const getChunks = (playlist) => {
|
||||
const chunks = [];
|
||||
for (let i = 0; i < playlist.boxes.length; i++) {
|
||||
const box = playlist.boxes[i];
|
||||
if (box.type === 'm3u-map') {
|
||||
chunks.push({ duration: 0, url: box.value, isHeader: true });
|
||||
continue;
|
||||
}
|
||||
if (box.type === 'm3u-extinf') {
|
||||
const nextBox = playlist.boxes[i + 1];
|
||||
i++;
|
||||
if (nextBox.type !== 'm3u-text-value') {
|
||||
throw new Error('Expected m3u-text-value');
|
||||
}
|
||||
chunks.push({ duration: box.value, url: nextBox.value, isHeader: false });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return chunks;
|
||||
};
|
||||
exports.getChunks = getChunks;
|
||||
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-duration-from-m3u.d.ts
generated
vendored
Normal file
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-duration-from-m3u.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { ParserState } from '../../state/parser-state';
|
||||
export declare const getDurationFromM3u: (state: ParserState) => number | null;
|
||||
14
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-duration-from-m3u.js
generated
vendored
Normal file
14
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-duration-from-m3u.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getDurationFromM3u = void 0;
|
||||
const get_playlist_1 = require("./get-playlist");
|
||||
const getDurationFromM3u = (state) => {
|
||||
const playlists = (0, get_playlist_1.getAllPlaylists)({
|
||||
structure: state.structure.getM3uStructure(),
|
||||
src: state.src,
|
||||
});
|
||||
return Math.max(...playlists.map((p) => {
|
||||
return (0, get_playlist_1.getDurationFromPlaylist)(p);
|
||||
}));
|
||||
};
|
||||
exports.getDurationFromM3u = getDurationFromM3u;
|
||||
8
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-playlist.d.ts
generated
vendored
Normal file
8
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-playlist.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { ParseMediaSrc } from '../../options';
|
||||
import type { M3uPlaylist, M3uStructure } from './types';
|
||||
export declare const getAllPlaylists: ({ structure, src, }: {
|
||||
structure: M3uStructure;
|
||||
src: ParseMediaSrc;
|
||||
}) => M3uPlaylist[];
|
||||
export declare const getPlaylist: (structure: M3uStructure, src: string) => M3uPlaylist;
|
||||
export declare const getDurationFromPlaylist: (playlist: M3uPlaylist) => number;
|
||||
47
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-playlist.js
generated
vendored
Normal file
47
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-playlist.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getDurationFromPlaylist = exports.getPlaylist = exports.getAllPlaylists = void 0;
|
||||
const get_streams_1 = require("./get-streams");
|
||||
const getAllPlaylists = ({ structure, src, }) => {
|
||||
const isIndependent = (0, get_streams_1.isIndependentSegments)(structure);
|
||||
if (!isIndependent) {
|
||||
return [
|
||||
{
|
||||
type: 'm3u-playlist',
|
||||
boxes: structure.boxes,
|
||||
src,
|
||||
},
|
||||
];
|
||||
}
|
||||
const playlists = structure.boxes.filter((box) => box.type === 'm3u-playlist');
|
||||
// If no playlists found, this might be a single media playlist (not a master playlist)
|
||||
// Create a synthetic playlist from the structure boxes
|
||||
if (playlists.length === 0) {
|
||||
return [
|
||||
{
|
||||
type: 'm3u-playlist',
|
||||
boxes: structure.boxes,
|
||||
src,
|
||||
},
|
||||
];
|
||||
}
|
||||
return playlists;
|
||||
};
|
||||
exports.getAllPlaylists = getAllPlaylists;
|
||||
const getPlaylist = (structure, src) => {
|
||||
const allPlaylists = (0, exports.getAllPlaylists)({ structure, src });
|
||||
const playlists = allPlaylists.find((box) => box.src === src);
|
||||
if (!playlists) {
|
||||
throw new Error(`Expected m3u-playlist with src ${src}`);
|
||||
}
|
||||
return playlists;
|
||||
};
|
||||
exports.getPlaylist = getPlaylist;
|
||||
const getDurationFromPlaylist = (playlist) => {
|
||||
const duration = playlist.boxes.filter((box) => box.type === 'm3u-extinf');
|
||||
if (duration.length === 0) {
|
||||
throw new Error('Expected duration in m3u playlist');
|
||||
}
|
||||
return duration.reduce((acc, d) => acc + d.value, 0);
|
||||
};
|
||||
exports.getDurationFromPlaylist = getDurationFromPlaylist;
|
||||
13
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-seeking-byte.d.ts
generated
vendored
Normal file
13
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-seeking-byte.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { MediaParserLogLevel } from '../../log';
|
||||
import type { M3uState } from '../../state/m3u-state';
|
||||
import type { SeekResolution } from '../../work-on-seek-request';
|
||||
export declare const clearM3uStateInPrepareForSeek: ({ m3uState, logLevel, }: {
|
||||
m3uState: M3uState;
|
||||
logLevel: MediaParserLogLevel;
|
||||
}) => void;
|
||||
export declare const getSeekingByteForM3u8: ({ time, currentPosition, m3uState, logLevel, }: {
|
||||
time: number;
|
||||
currentPosition: number;
|
||||
m3uState: M3uState;
|
||||
logLevel: MediaParserLogLevel;
|
||||
}) => SeekResolution;
|
||||
34
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-seeking-byte.js
generated
vendored
Normal file
34
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-seeking-byte.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getSeekingByteForM3u8 = exports.clearM3uStateInPrepareForSeek = void 0;
|
||||
const log_1 = require("../../log");
|
||||
const clearM3uStateInPrepareForSeek = ({ m3uState, logLevel, }) => {
|
||||
const selectedPlaylists = m3uState.getSelectedPlaylists();
|
||||
for (const playlistUrl of selectedPlaylists) {
|
||||
const streamRun = m3uState.getM3uStreamRun(playlistUrl);
|
||||
if (streamRun) {
|
||||
streamRun.abort();
|
||||
}
|
||||
log_1.Log.trace(logLevel, 'Clearing M3U stream run for', playlistUrl);
|
||||
m3uState.setM3uStreamRun(playlistUrl, null);
|
||||
}
|
||||
m3uState.clearAllChunksProcessed();
|
||||
m3uState.sampleSorter.clearSamples();
|
||||
};
|
||||
exports.clearM3uStateInPrepareForSeek = clearM3uStateInPrepareForSeek;
|
||||
const getSeekingByteForM3u8 = ({ time, currentPosition, m3uState, logLevel, }) => {
|
||||
(0, exports.clearM3uStateInPrepareForSeek)({ m3uState, logLevel });
|
||||
const selectedPlaylists = m3uState.getSelectedPlaylists();
|
||||
for (const playlistUrl of selectedPlaylists) {
|
||||
m3uState.setSeekToSecondsToProcess(playlistUrl, {
|
||||
targetTime: time,
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: 'do-seek',
|
||||
byte: currentPosition,
|
||||
// TODO: This will be imperfect when seeking in playMedia()
|
||||
timeInSeconds: time,
|
||||
};
|
||||
};
|
||||
exports.getSeekingByteForM3u8 = getSeekingByteForM3u8;
|
||||
32
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-streams.d.ts
generated
vendored
Normal file
32
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-streams.d.ts
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import type { MediaParserDimensions } from '../../get-dimensions';
|
||||
import type { ParseMediaSrc } from '../../options';
|
||||
import type { MediaParserStructureUnstable } from '../../parse-result';
|
||||
import type { MediaParserReaderInterface } from '../../readers/reader';
|
||||
import type { ParserState } from '../../state/parser-state';
|
||||
export type M3uAssociatedPlaylist = {
|
||||
groupId: string;
|
||||
language: string | null;
|
||||
name: string | null;
|
||||
autoselect: boolean;
|
||||
default: boolean;
|
||||
channels: number | null;
|
||||
src: string;
|
||||
id: number;
|
||||
isAudio: boolean;
|
||||
};
|
||||
export type M3uStream = {
|
||||
src: string;
|
||||
bandwidthInBitsPerSec: number | null;
|
||||
averageBandwidthInBitsPerSec: number | null;
|
||||
dimensions: MediaParserDimensions | null;
|
||||
codecs: string[] | null;
|
||||
id: number;
|
||||
associatedPlaylists: M3uAssociatedPlaylist[];
|
||||
};
|
||||
export declare const isIndependentSegments: (structure: MediaParserStructureUnstable | null) => boolean;
|
||||
export declare const getM3uStreams: ({ structure, originalSrc, readerInterface, }: {
|
||||
structure: MediaParserStructureUnstable | null;
|
||||
originalSrc: ParseMediaSrc;
|
||||
readerInterface: MediaParserReaderInterface;
|
||||
}) => M3uStream[] | null;
|
||||
export declare const m3uHasStreams: (state: ParserState) => boolean;
|
||||
84
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-streams.js
generated
vendored
Normal file
84
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/get-streams.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.m3uHasStreams = exports.getM3uStreams = exports.isIndependentSegments = void 0;
|
||||
const isIndependentSegments = (structure) => {
|
||||
if (structure === null || structure.type !== 'm3u') {
|
||||
return false;
|
||||
}
|
||||
return structure.boxes.some((box) => box.type === 'm3u-independent-segments' || box.type === 'm3u-stream-info');
|
||||
};
|
||||
exports.isIndependentSegments = isIndependentSegments;
|
||||
const getM3uStreams = ({ structure, originalSrc, readerInterface, }) => {
|
||||
if (structure === null || structure.type !== 'm3u') {
|
||||
return null;
|
||||
}
|
||||
const boxes = [];
|
||||
for (let i = 0; i < structure.boxes.length; i++) {
|
||||
const str = structure.boxes[i];
|
||||
if (str.type === 'm3u-stream-info') {
|
||||
const next = structure.boxes[i + 1];
|
||||
if (next.type !== 'm3u-text-value') {
|
||||
throw new Error('Expected m3u-text-value');
|
||||
}
|
||||
const associatedPlaylists = [];
|
||||
if (str.audio) {
|
||||
const match = structure.boxes.filter((box) => {
|
||||
return box.type === 'm3u-media-info' && box.groupId === str.audio;
|
||||
});
|
||||
for (const audioTrack of match) {
|
||||
associatedPlaylists.push({
|
||||
autoselect: audioTrack.autoselect,
|
||||
channels: audioTrack.channels,
|
||||
default: audioTrack.default,
|
||||
groupId: audioTrack.groupId,
|
||||
language: audioTrack.language,
|
||||
name: audioTrack.name,
|
||||
src: readerInterface.createAdjacentFileSource(audioTrack.uri, originalSrc),
|
||||
id: associatedPlaylists.length,
|
||||
isAudio: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
boxes.push({
|
||||
src: readerInterface.createAdjacentFileSource(next.value, originalSrc),
|
||||
averageBandwidthInBitsPerSec: str.averageBandwidthInBitsPerSec,
|
||||
bandwidthInBitsPerSec: str.bandwidthInBitsPerSec,
|
||||
codecs: str.codecs,
|
||||
dimensions: str.dimensions,
|
||||
associatedPlaylists,
|
||||
});
|
||||
}
|
||||
}
|
||||
// Maybe this is already a playlist
|
||||
if (boxes.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const sorted = boxes.slice().sort((a, b) => {
|
||||
var _a, _b, _c, _d;
|
||||
const aResolution = a.dimensions
|
||||
? a.dimensions.width * a.dimensions.height
|
||||
: 0;
|
||||
const bResolution = b.dimensions
|
||||
? b.dimensions.width * b.dimensions.height
|
||||
: 0;
|
||||
if (aResolution === bResolution) {
|
||||
const bandwidthA = (_b = (_a = a.averageBandwidthInBitsPerSec) !== null && _a !== void 0 ? _a : a.bandwidthInBitsPerSec) !== null && _b !== void 0 ? _b : 0;
|
||||
const bandwidthB = (_d = (_c = b.averageBandwidthInBitsPerSec) !== null && _c !== void 0 ? _c : b.bandwidthInBitsPerSec) !== null && _d !== void 0 ? _d : 0;
|
||||
return bandwidthB - bandwidthA;
|
||||
}
|
||||
return bResolution - aResolution;
|
||||
});
|
||||
return sorted.map((box, index) => ({ ...box, id: index }));
|
||||
};
|
||||
exports.getM3uStreams = getM3uStreams;
|
||||
const m3uHasStreams = (state) => {
|
||||
const structure = state.structure.getStructureOrNull();
|
||||
if (!structure) {
|
||||
return false;
|
||||
}
|
||||
if (structure.type !== 'm3u') {
|
||||
return true;
|
||||
}
|
||||
return state.m3u.hasFinishedManifest();
|
||||
};
|
||||
exports.m3uHasStreams = m3uHasStreams;
|
||||
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-directive.d.ts
generated
vendored
Normal file
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-directive.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { M3uBox } from './types';
|
||||
export declare const parseM3uDirective: (str: string) => M3uBox;
|
||||
129
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-directive.js
generated
vendored
Normal file
129
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-directive.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseM3uDirective = void 0;
|
||||
const parse_m3u_media_directive_1 = require("./parse-m3u-media-directive");
|
||||
const parse_stream_inf_1 = require("./parse-stream-inf");
|
||||
const parseM3uDirective = (str) => {
|
||||
const firstColon = str.indexOf(':');
|
||||
const directive = (firstColon === -1 ? str : str.slice(0, firstColon)).trim();
|
||||
const value = firstColon === -1 ? null : str.slice(firstColon + 1);
|
||||
if (directive === '#EXT-X-VERSION') {
|
||||
if (!value) {
|
||||
throw new Error('EXT-X-VERSION directive must have a value');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-version',
|
||||
version: value,
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-INDEPENDENT-SEGMENTS') {
|
||||
return {
|
||||
type: 'm3u-independent-segments',
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-MEDIA') {
|
||||
if (!value) {
|
||||
throw new Error('EXT-X-MEDIA directive must have a value');
|
||||
}
|
||||
const parsed = (0, parse_m3u_media_directive_1.parseM3uMediaDirective)(value);
|
||||
return parsed;
|
||||
}
|
||||
if (directive === '#EXT-X-TARGETDURATION') {
|
||||
if (!value) {
|
||||
throw new Error('EXT-X-TARGETDURATION directive must have a value');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-target-duration',
|
||||
duration: parseFloat(value),
|
||||
};
|
||||
}
|
||||
if (directive === '#EXTINF') {
|
||||
if (!value) {
|
||||
throw new Error('EXTINF has no value');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-extinf',
|
||||
value: parseFloat(value),
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-ENDLIST') {
|
||||
return {
|
||||
type: 'm3u-endlist',
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-PLAYLIST-TYPE') {
|
||||
if (!value) {
|
||||
throw new Error('#EXT-X-PLAYLIST-TYPE. directive must have a value');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-playlist-type',
|
||||
playlistType: value,
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-MEDIA-SEQUENCE') {
|
||||
if (!value) {
|
||||
throw new Error('#EXT-X-MEDIA-SEQUENCE directive must have a value');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-media-sequence',
|
||||
value: Number(value),
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-DISCONTINUITY-SEQUENCE') {
|
||||
if (!value) {
|
||||
throw new Error('#EXT-X-DISCONTINUITY-SEQUENCE directive must have a value');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-discontinuity-sequence',
|
||||
value: Number(value),
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-STREAM-INF') {
|
||||
if (!value) {
|
||||
throw new Error('EXT-X-STREAM-INF directive must have a value');
|
||||
}
|
||||
const res = (0, parse_stream_inf_1.parseStreamInf)(value);
|
||||
return res;
|
||||
}
|
||||
if (directive === '#EXT-X-I-FRAME-STREAM-INF') {
|
||||
return {
|
||||
type: 'm3u-i-frame-stream-info',
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-ALLOW-CACHE') {
|
||||
if (!value) {
|
||||
throw new Error('#EXT-X-ALLOW-CACHE directive must have a value');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-allow-cache',
|
||||
allowsCache: value === 'YES',
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-MAP') {
|
||||
if (!value) {
|
||||
throw new Error('#EXT-X-MAP directive must have a value');
|
||||
}
|
||||
const p = (0, parse_m3u_media_directive_1.parseM3uKeyValue)(value);
|
||||
if (!p.URI) {
|
||||
throw new Error('EXT-X-MAP directive must have a URI');
|
||||
}
|
||||
return {
|
||||
type: 'm3u-map',
|
||||
value: p.URI,
|
||||
};
|
||||
}
|
||||
if (directive === '#EXT-X-PROGRAM-DATE-TIME') {
|
||||
if (!value) {
|
||||
throw new Error('#EXT-X-PROGRAM-DATE-TIME directive must have a value');
|
||||
}
|
||||
// Store the raw ISO 8601 date-time string without validation.
|
||||
// This directive associates media segments with absolute dates but
|
||||
// doesn't affect parsing of tracks, dimensions, or other metadata.
|
||||
return {
|
||||
type: 'm3u-program-date-time',
|
||||
dateTime: value,
|
||||
};
|
||||
}
|
||||
throw new Error(`Unknown directive ${directive}. Value: ${value}`);
|
||||
};
|
||||
exports.parseM3uDirective = parseM3uDirective;
|
||||
8
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-manifest.d.ts
generated
vendored
Normal file
8
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-manifest.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { BufferIterator } from '../../iterator/buffer-iterator';
|
||||
import type { ParseResult } from '../../parse-result';
|
||||
import type { M3uStructure } from './types';
|
||||
export declare const parseM3uManifest: ({ iterator, structure, contentLength, }: {
|
||||
iterator: BufferIterator;
|
||||
structure: M3uStructure;
|
||||
contentLength: number;
|
||||
}) => Promise<ParseResult>;
|
||||
18
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-manifest.js
generated
vendored
Normal file
18
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-manifest.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseM3uManifest = void 0;
|
||||
const parse_m3u8_text_1 = require("./parse-m3u8-text");
|
||||
const parseM3uManifest = ({ iterator, structure, contentLength, }) => {
|
||||
const start = iterator.startCheckpoint();
|
||||
const line = iterator.readUntilLineEnd();
|
||||
if (iterator.counter.getOffset() > contentLength) {
|
||||
throw new Error('Unexpected end of file');
|
||||
}
|
||||
if (line === null) {
|
||||
start.returnToCheckpoint();
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
(0, parse_m3u8_text_1.parseM3u8Text)(line.trim(), structure.boxes);
|
||||
return Promise.resolve(null);
|
||||
};
|
||||
exports.parseM3uManifest = parseM3uManifest;
|
||||
3
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-media-directive.d.ts
generated
vendored
Normal file
3
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-media-directive.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { M3uMediaInfo } from './types';
|
||||
export declare const parseM3uKeyValue: (str: string) => Record<string, string>;
|
||||
export declare const parseM3uMediaDirective: (str: string) => M3uMediaInfo;
|
||||
37
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-media-directive.js
generated
vendored
Normal file
37
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u-media-directive.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseM3uMediaDirective = exports.parseM3uKeyValue = void 0;
|
||||
const parse_stream_inf_1 = require("./parse-stream-inf");
|
||||
const parseM3uKeyValue = (str) => {
|
||||
const quotes = (0, parse_stream_inf_1.splitRespectingQuotes)(str);
|
||||
const map = {};
|
||||
for (const quote of quotes) {
|
||||
const firstColon = quote.indexOf('=');
|
||||
const key = firstColon === -1 ? quote : quote.slice(0, firstColon);
|
||||
const value = firstColon === -1 ? null : quote.slice(firstColon + 1);
|
||||
if (value === null) {
|
||||
throw new Error('Value is null');
|
||||
}
|
||||
const actualValue = (value === null || value === void 0 ? void 0 : value.startsWith('"')) && (value === null || value === void 0 ? void 0 : value.endsWith('"'))
|
||||
? value.slice(1, -1)
|
||||
: value;
|
||||
map[key] = actualValue;
|
||||
}
|
||||
return map;
|
||||
};
|
||||
exports.parseM3uKeyValue = parseM3uKeyValue;
|
||||
const parseM3uMediaDirective = (str) => {
|
||||
const map = (0, exports.parseM3uKeyValue)(str);
|
||||
return {
|
||||
type: 'm3u-media-info',
|
||||
autoselect: map.AUTOSELECT === 'YES',
|
||||
channels: map.CHANNELS ? parseInt(map.CHANNELS, 10) : null,
|
||||
default: map.DEFAULT === 'YES',
|
||||
groupId: map['GROUP-ID'],
|
||||
language: map.LANGUAGE || null,
|
||||
name: map.NAME || null,
|
||||
uri: map.URI,
|
||||
mediaType: map.TYPE || null,
|
||||
};
|
||||
};
|
||||
exports.parseM3uMediaDirective = parseM3uMediaDirective;
|
||||
4
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u.d.ts
generated
vendored
Normal file
4
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { ParserState } from '../../state/parser-state';
|
||||
export declare const parseM3u: ({ state }: {
|
||||
state: ParserState;
|
||||
}) => Promise<import("../../parse-result").ParseResult>;
|
||||
54
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u.js
generated
vendored
Normal file
54
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseM3u = void 0;
|
||||
const after_manifest_fetch_1 = require("./after-manifest-fetch");
|
||||
const parse_m3u_manifest_1 = require("./parse-m3u-manifest");
|
||||
const run_over_m3u_1 = require("./run-over-m3u");
|
||||
const parseM3u = async ({ state }) => {
|
||||
const structure = state.structure.getM3uStructure();
|
||||
if (state.m3u.isReadyToIterateOverM3u()) {
|
||||
const selectedPlaylists = state.m3u.getSelectedPlaylists();
|
||||
const whichPlaylistToRunOver = state.m3u.sampleSorter.getNextStreamToRun(selectedPlaylists);
|
||||
await (0, run_over_m3u_1.runOverM3u)({
|
||||
state,
|
||||
structure,
|
||||
playlistUrl: whichPlaylistToRunOver,
|
||||
logLevel: state.logLevel,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
if (state.m3u.hasFinishedManifest()) {
|
||||
if (typeof state.src !== 'string' && !(state.src instanceof URL)) {
|
||||
throw new Error('Expected src to be a string');
|
||||
}
|
||||
state.mediaSection.addMediaSection({
|
||||
start: 0,
|
||||
// We do a pseudo-seek when seeking m3u, which will be the same byte
|
||||
// as we are currently in, which in most cases is the end of the file.
|
||||
size: state.contentLength + 1,
|
||||
});
|
||||
await (0, after_manifest_fetch_1.afterManifestFetch)({
|
||||
structure,
|
||||
m3uState: state.m3u,
|
||||
src: state.src.toString(),
|
||||
selectM3uStreamFn: state.selectM3uStreamFn,
|
||||
logLevel: state.logLevel,
|
||||
selectAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn,
|
||||
readerInterface: state.readerInterface,
|
||||
onAudioTrack: state.onAudioTrack,
|
||||
canSkipTracks: state.callbacks.canSkipTracksState,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
const box = await (0, parse_m3u_manifest_1.parseM3uManifest)({
|
||||
iterator: state.iterator,
|
||||
structure,
|
||||
contentLength: state.contentLength,
|
||||
});
|
||||
const isDoneNow = state.iterator.counter.getOffset() === state.contentLength;
|
||||
if (isDoneNow) {
|
||||
state.m3u.setHasFinishedManifest();
|
||||
}
|
||||
return box;
|
||||
};
|
||||
exports.parseM3u = parseM3u;
|
||||
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u8-text.d.ts
generated
vendored
Normal file
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u8-text.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { M3uBox } from './types';
|
||||
export declare const parseM3u8Text: (line: string, boxes: M3uBox[]) => void;
|
||||
23
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u8-text.js
generated
vendored
Normal file
23
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-m3u8-text.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseM3u8Text = void 0;
|
||||
const parse_directive_1 = require("./parse-directive");
|
||||
const parseM3u8Text = (line, boxes) => {
|
||||
if (line === '#EXTM3U') {
|
||||
boxes.push({
|
||||
type: 'm3u-header',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (line.startsWith('#')) {
|
||||
boxes.push((0, parse_directive_1.parseM3uDirective)(line));
|
||||
return;
|
||||
}
|
||||
if (line.trim()) {
|
||||
boxes.push({
|
||||
type: 'm3u-text-value',
|
||||
value: line,
|
||||
});
|
||||
}
|
||||
};
|
||||
exports.parseM3u8Text = parseM3u8Text;
|
||||
3
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-stream-inf.d.ts
generated
vendored
Normal file
3
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-stream-inf.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { M3uStreamInfo } from './types';
|
||||
export declare function splitRespectingQuotes(input: string): string[];
|
||||
export declare const parseStreamInf: (str: string) => M3uStreamInfo;
|
||||
62
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-stream-inf.js
generated
vendored
Normal file
62
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/parse-stream-inf.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseStreamInf = void 0;
|
||||
exports.splitRespectingQuotes = splitRespectingQuotes;
|
||||
function splitRespectingQuotes(input) {
|
||||
const result = [];
|
||||
let currentPart = '';
|
||||
let insideQuote = false;
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const char = input[i];
|
||||
// Toggle flag when encountering a quote character.
|
||||
if (char === '"') {
|
||||
insideQuote = !insideQuote;
|
||||
currentPart += char;
|
||||
}
|
||||
// If we encounter a comma and we are NOT inside a quoted substring
|
||||
else if (char === ',' && !insideQuote) {
|
||||
result.push(currentPart);
|
||||
currentPart = '';
|
||||
}
|
||||
else {
|
||||
currentPart += char;
|
||||
}
|
||||
}
|
||||
// Push the last token, if any.
|
||||
if (currentPart) {
|
||||
result.push(currentPart);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
const parseStreamInf = (str) => {
|
||||
const quotes = splitRespectingQuotes(str);
|
||||
const map = {};
|
||||
for (const quote of quotes) {
|
||||
const firstColon = quote.indexOf('=');
|
||||
const key = firstColon === -1 ? quote : quote.slice(0, firstColon);
|
||||
const value = firstColon === -1 ? null : quote.slice(firstColon + 1);
|
||||
if (value === null) {
|
||||
throw new Error('Value is null');
|
||||
}
|
||||
const actualValue = (value === null || value === void 0 ? void 0 : value.startsWith('"')) && (value === null || value === void 0 ? void 0 : value.endsWith('"'))
|
||||
? value.slice(1, -1)
|
||||
: value;
|
||||
map[key] = actualValue;
|
||||
}
|
||||
return {
|
||||
type: 'm3u-stream-info',
|
||||
averageBandwidthInBitsPerSec: map['AVERAGE-BANDWIDTH']
|
||||
? parseInt(map['AVERAGE-BANDWIDTH'], 10)
|
||||
: null,
|
||||
bandwidthInBitsPerSec: map.BANDWIDTH ? parseInt(map.BANDWIDTH, 10) : null,
|
||||
codecs: map.CODECS ? map.CODECS.split(',') : null,
|
||||
dimensions: map.RESOLUTION
|
||||
? {
|
||||
width: parseInt(map.RESOLUTION.split('x')[0], 10),
|
||||
height: parseInt(map.RESOLUTION.split('x')[1], 10),
|
||||
}
|
||||
: null,
|
||||
audio: map.AUDIO || null,
|
||||
};
|
||||
};
|
||||
exports.parseStreamInf = parseStreamInf;
|
||||
12
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/process-m3u-chunk.d.ts
generated
vendored
Normal file
12
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/process-m3u-chunk.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { ParserState } from '../../state/parser-state';
|
||||
import type { M3uStructure } from './types';
|
||||
export type PendingSeek = {
|
||||
pending: number | null;
|
||||
};
|
||||
export declare const processM3uChunk: ({ playlistUrl, state, structure, audioDone, videoDone, }: {
|
||||
playlistUrl: string;
|
||||
state: ParserState;
|
||||
structure: M3uStructure;
|
||||
audioDone: boolean;
|
||||
videoDone: boolean;
|
||||
}) => Promise<void>;
|
||||
274
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/process-m3u-chunk.js
generated
vendored
Normal file
274
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/process-m3u-chunk.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.processM3uChunk = void 0;
|
||||
const media_parser_controller_1 = require("../../controller/media-parser-controller");
|
||||
const forward_controller_pause_resume_abort_1 = require("../../forward-controller-pause-resume-abort");
|
||||
const parse_media_1 = require("../../parse-media");
|
||||
const register_track_1 = require("../../register-track");
|
||||
const with_resolvers_1 = require("../../with-resolvers");
|
||||
const first_sample_in_m3u_chunk_1 = require("./first-sample-in-m3u-chunk");
|
||||
const get_chunks_1 = require("./get-chunks");
|
||||
const get_playlist_1 = require("./get-playlist");
|
||||
const get_chunk_to_seek_to_1 = require("./seek/get-chunk-to-seek-to");
|
||||
const processM3uChunk = ({ playlistUrl, state, structure, audioDone, videoDone, }) => {
|
||||
const { promise, reject, resolve } = (0, with_resolvers_1.withResolvers)();
|
||||
const onGlobalAudioTrack = audioDone
|
||||
? null
|
||||
: async (track) => {
|
||||
const existingTracks = state.callbacks.tracks.getTracks();
|
||||
let { trackId } = track;
|
||||
while (existingTracks.find((t) => t.trackId === trackId)) {
|
||||
trackId++;
|
||||
}
|
||||
const onAudioSample = await (0, register_track_1.registerAudioTrack)({
|
||||
container: 'm3u8',
|
||||
track: {
|
||||
...track,
|
||||
trackId,
|
||||
},
|
||||
registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
|
||||
tracks: state.callbacks.tracks,
|
||||
logLevel: state.logLevel,
|
||||
onAudioTrack: state.onAudioTrack,
|
||||
});
|
||||
state.m3u.sampleSorter.addToStreamWithTrack(playlistUrl);
|
||||
if (onAudioSample === null) {
|
||||
return null;
|
||||
}
|
||||
state.m3u.sampleSorter.addAudioStreamToConsider(playlistUrl, onAudioSample);
|
||||
return async (sample) => {
|
||||
await state.m3u.sampleSorter.addAudioSample(playlistUrl, sample);
|
||||
};
|
||||
};
|
||||
const onGlobalVideoTrack = videoDone
|
||||
? null
|
||||
: async (track) => {
|
||||
const existingTracks = state.callbacks.tracks.getTracks();
|
||||
let { trackId } = track;
|
||||
while (existingTracks.find((t) => t.trackId === trackId)) {
|
||||
trackId++;
|
||||
}
|
||||
const onVideoSample = await (0, register_track_1.registerVideoTrack)({
|
||||
container: 'm3u8',
|
||||
track: {
|
||||
...track,
|
||||
trackId,
|
||||
},
|
||||
logLevel: state.logLevel,
|
||||
onVideoTrack: state.onVideoTrack,
|
||||
registerVideoSampleCallback: state.callbacks.registerVideoSampleCallback,
|
||||
tracks: state.callbacks.tracks,
|
||||
});
|
||||
state.m3u.sampleSorter.addToStreamWithTrack(playlistUrl);
|
||||
if (onVideoSample === null) {
|
||||
return null;
|
||||
}
|
||||
state.m3u.sampleSorter.addVideoStreamToConsider(playlistUrl, onVideoSample);
|
||||
return async (sample) => {
|
||||
await state.m3u.sampleSorter.addVideoSample(playlistUrl, sample);
|
||||
};
|
||||
};
|
||||
// This function will run through the whole playlist step by step, and pause itself
|
||||
// On the next run it will continue
|
||||
const pausableIterator = async () => {
|
||||
const playlist = (0, get_playlist_1.getPlaylist)(structure, playlistUrl);
|
||||
const chunks = (0, get_chunks_1.getChunks)(playlist);
|
||||
const seekToSecondsToProcess = state.m3u.getSeekToSecondsToProcess(playlistUrl);
|
||||
const chunksToSubtract = state.m3u.getNextSeekShouldSubtractChunks(playlistUrl);
|
||||
let chunkIndex = null;
|
||||
if (seekToSecondsToProcess !== null) {
|
||||
chunkIndex = Math.max(0, (0, get_chunk_to_seek_to_1.getChunkToSeekTo)({
|
||||
chunks,
|
||||
seekToSecondsToProcess: seekToSecondsToProcess.targetTime,
|
||||
}) - chunksToSubtract);
|
||||
}
|
||||
const currentPromise = {
|
||||
resolver: (() => undefined),
|
||||
rejector: reject,
|
||||
};
|
||||
const requiresHeaderToBeFetched = chunks[0].isHeader;
|
||||
for (const chunk of chunks) {
|
||||
const mp4HeaderSegment = state.m3u.getMp4HeaderSegment(playlistUrl);
|
||||
if (requiresHeaderToBeFetched && mp4HeaderSegment && chunk.isHeader) {
|
||||
continue;
|
||||
}
|
||||
if (chunkIndex !== null &&
|
||||
chunks.indexOf(chunk) < chunkIndex &&
|
||||
!chunk.isHeader) {
|
||||
continue;
|
||||
}
|
||||
currentPromise.resolver = (newRun) => {
|
||||
state.m3u.setM3uStreamRun(playlistUrl, newRun);
|
||||
resolve();
|
||||
};
|
||||
currentPromise.rejector = reject;
|
||||
const childController = (0, media_parser_controller_1.mediaParserController)();
|
||||
const forwarded = (0, forward_controller_pause_resume_abort_1.forwardMediaParserControllerPauseResume)({
|
||||
childController,
|
||||
parentController: state.controller,
|
||||
});
|
||||
const nextChunk = chunks[chunks.indexOf(chunk) + 1];
|
||||
if (nextChunk) {
|
||||
const nextChunkSource = state.readerInterface.createAdjacentFileSource(nextChunk.url, playlistUrl);
|
||||
state.readerInterface.preload({
|
||||
logLevel: state.logLevel,
|
||||
range: null,
|
||||
src: nextChunkSource,
|
||||
prefetchCache: state.prefetchCache,
|
||||
});
|
||||
}
|
||||
const makeContinuationFn = () => {
|
||||
return {
|
||||
continue() {
|
||||
const resolver = (0, with_resolvers_1.withResolvers)();
|
||||
currentPromise.resolver = resolver.resolve;
|
||||
currentPromise.rejector = resolver.reject;
|
||||
childController.resume();
|
||||
return resolver.promise;
|
||||
},
|
||||
abort() {
|
||||
childController.abort();
|
||||
},
|
||||
};
|
||||
};
|
||||
const isLastChunk = chunk === chunks[chunks.length - 1];
|
||||
await childController._internals.checkForAbortAndPause();
|
||||
const src = state.readerInterface.createAdjacentFileSource(chunk.url, playlistUrl);
|
||||
try {
|
||||
const data = await (0, parse_media_1.parseMedia)({
|
||||
src,
|
||||
acknowledgeRemotionLicense: true,
|
||||
logLevel: state.logLevel,
|
||||
controller: childController,
|
||||
progressIntervalInMs: 0,
|
||||
onParseProgress: () => {
|
||||
childController.pause();
|
||||
currentPromise.resolver(makeContinuationFn());
|
||||
},
|
||||
fields: chunk.isHeader ? { slowStructure: true } : undefined,
|
||||
onTracks: () => {
|
||||
if (!state.m3u.hasEmittedDoneWithTracks(playlistUrl)) {
|
||||
state.m3u.setHasEmittedDoneWithTracks(playlistUrl);
|
||||
const allDone = state.m3u.setTracksDone(playlistUrl);
|
||||
if (allDone) {
|
||||
state.callbacks.tracks.setIsDone(state.logLevel);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
onAudioTrack: onGlobalAudioTrack === null
|
||||
? null
|
||||
: async ({ track }) => {
|
||||
const callbackOrFalse = state.m3u.hasEmittedAudioTrack(playlistUrl);
|
||||
if (callbackOrFalse === false) {
|
||||
const callback = await onGlobalAudioTrack(track);
|
||||
if (!callback) {
|
||||
state.m3u.setHasEmittedAudioTrack(playlistUrl, null);
|
||||
return null;
|
||||
}
|
||||
state.m3u.setHasEmittedAudioTrack(playlistUrl, callback);
|
||||
return async (sample) => {
|
||||
await (0, first_sample_in_m3u_chunk_1.considerSeekBasedOnChunk)({
|
||||
sample,
|
||||
callback,
|
||||
parentController: state.controller,
|
||||
childController,
|
||||
m3uState: state.m3u,
|
||||
playlistUrl,
|
||||
subtractChunks: chunksToSubtract,
|
||||
chunkIndex,
|
||||
});
|
||||
};
|
||||
}
|
||||
if (callbackOrFalse === null) {
|
||||
return null;
|
||||
}
|
||||
return async (sample) => {
|
||||
await (0, first_sample_in_m3u_chunk_1.considerSeekBasedOnChunk)({
|
||||
sample,
|
||||
m3uState: state.m3u,
|
||||
playlistUrl,
|
||||
callback: callbackOrFalse,
|
||||
parentController: state.controller,
|
||||
childController,
|
||||
subtractChunks: chunksToSubtract,
|
||||
chunkIndex,
|
||||
});
|
||||
};
|
||||
},
|
||||
onVideoTrack: onGlobalVideoTrack === null
|
||||
? null
|
||||
: async ({ track }) => {
|
||||
const callbackOrFalse = state.m3u.hasEmittedVideoTrack(playlistUrl);
|
||||
if (callbackOrFalse === false) {
|
||||
const callback = await onGlobalVideoTrack({
|
||||
...track,
|
||||
m3uStreamFormat: chunk.isHeader || mp4HeaderSegment ? 'mp4' : 'ts',
|
||||
});
|
||||
if (!callback) {
|
||||
state.m3u.setHasEmittedVideoTrack(playlistUrl, null);
|
||||
return null;
|
||||
}
|
||||
state.m3u.setHasEmittedVideoTrack(playlistUrl, callback);
|
||||
return async (sample) => {
|
||||
await (0, first_sample_in_m3u_chunk_1.considerSeekBasedOnChunk)({
|
||||
sample,
|
||||
m3uState: state.m3u,
|
||||
playlistUrl,
|
||||
callback,
|
||||
parentController: state.controller,
|
||||
childController,
|
||||
subtractChunks: chunksToSubtract,
|
||||
chunkIndex,
|
||||
});
|
||||
};
|
||||
}
|
||||
if (callbackOrFalse === null) {
|
||||
return null;
|
||||
}
|
||||
return async (sample) => {
|
||||
await (0, first_sample_in_m3u_chunk_1.considerSeekBasedOnChunk)({
|
||||
sample,
|
||||
m3uState: state.m3u,
|
||||
playlistUrl,
|
||||
callback: callbackOrFalse,
|
||||
parentController: state.controller,
|
||||
childController,
|
||||
subtractChunks: chunksToSubtract,
|
||||
chunkIndex,
|
||||
});
|
||||
};
|
||||
},
|
||||
reader: state.readerInterface,
|
||||
makeSamplesStartAtZero: false,
|
||||
m3uPlaylistContext: {
|
||||
mp4HeaderSegment,
|
||||
isLastChunkInPlaylist: isLastChunk,
|
||||
},
|
||||
});
|
||||
if (chunk.isHeader) {
|
||||
if (data.slowStructure.type !== 'iso-base-media') {
|
||||
throw new Error('Expected an mp4 file');
|
||||
}
|
||||
state.m3u.setMp4HeaderSegment(playlistUrl, data.slowStructure);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
currentPromise.rejector(e);
|
||||
throw e;
|
||||
}
|
||||
forwarded.cleanup();
|
||||
if (!isLastChunk) {
|
||||
childController.pause();
|
||||
currentPromise.resolver(makeContinuationFn());
|
||||
}
|
||||
}
|
||||
currentPromise.resolver(null);
|
||||
};
|
||||
const run = pausableIterator();
|
||||
run.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
exports.processM3uChunk = processM3uChunk;
|
||||
9
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/run-over-m3u.d.ts
generated
vendored
Normal file
9
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/run-over-m3u.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { MediaParserLogLevel } from '../../log';
|
||||
import type { ParserState } from '../../state/parser-state';
|
||||
import type { M3uStructure } from './types';
|
||||
export declare const runOverM3u: ({ state, structure, playlistUrl, logLevel, }: {
|
||||
state: ParserState;
|
||||
structure: M3uStructure;
|
||||
playlistUrl: string;
|
||||
logLevel: MediaParserLogLevel;
|
||||
}) => Promise<void>;
|
||||
36
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/run-over-m3u.js
generated
vendored
Normal file
36
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/run-over-m3u.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runOverM3u = void 0;
|
||||
const log_1 = require("../../log");
|
||||
const process_m3u_chunk_1 = require("./process-m3u-chunk");
|
||||
const runOverM3u = async ({ state, structure, playlistUrl, logLevel, }) => {
|
||||
const tracksDone = state.m3u.getTrackDone(playlistUrl);
|
||||
const hasAudioStreamToConsider = state.m3u.sampleSorter.hasAudioStreamToConsider(playlistUrl);
|
||||
const hasVideoStreamToConsider = state.m3u.sampleSorter.hasVideoStreamToConsider(playlistUrl);
|
||||
const audioDone = !hasAudioStreamToConsider && tracksDone;
|
||||
const videoDone = !hasVideoStreamToConsider && tracksDone;
|
||||
const bothDone = audioDone && videoDone;
|
||||
if (bothDone) {
|
||||
state.m3u.setAllChunksProcessed(playlistUrl);
|
||||
return;
|
||||
}
|
||||
const existingRun = state.m3u.getM3uStreamRun(playlistUrl);
|
||||
if (existingRun) {
|
||||
log_1.Log.trace(logLevel, 'Existing M3U parsing process found for', playlistUrl);
|
||||
const run = await existingRun.continue();
|
||||
state.m3u.setM3uStreamRun(playlistUrl, run);
|
||||
if (!run) {
|
||||
state.m3u.setAllChunksProcessed(playlistUrl);
|
||||
}
|
||||
return;
|
||||
}
|
||||
log_1.Log.trace(logLevel, 'Starting new M3U parsing process for', playlistUrl);
|
||||
await (0, process_m3u_chunk_1.processM3uChunk)({
|
||||
playlistUrl,
|
||||
state,
|
||||
structure,
|
||||
audioDone,
|
||||
videoDone,
|
||||
});
|
||||
};
|
||||
exports.runOverM3u = runOverM3u;
|
||||
16
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/sample-sorter.d.ts
generated
vendored
Normal file
16
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/sample-sorter.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { MediaParserLogLevel } from '../../log';
|
||||
import type { MediaParserAudioSample, MediaParserOnAudioSample, MediaParserOnVideoSample, MediaParserVideoSample } from '../../webcodec-sample-types';
|
||||
export declare const sampleSorter: ({ logLevel, getAllChunksProcessedForPlaylist, }: {
|
||||
logLevel: MediaParserLogLevel;
|
||||
getAllChunksProcessedForPlaylist: (src: string) => boolean;
|
||||
}) => {
|
||||
clearSamples: () => void;
|
||||
addToStreamWithTrack: (src: string) => void;
|
||||
addVideoStreamToConsider: (src: string, callback: MediaParserOnVideoSample) => void;
|
||||
addAudioStreamToConsider: (src: string, callback: MediaParserOnAudioSample) => void;
|
||||
hasAudioStreamToConsider: (src: string) => boolean;
|
||||
hasVideoStreamToConsider: (src: string) => boolean;
|
||||
addAudioSample: (src: string, sample: MediaParserAudioSample) => Promise<void>;
|
||||
addVideoSample: (src: string, sample: MediaParserVideoSample) => Promise<void>;
|
||||
getNextStreamToRun: (streams: string[]) => string;
|
||||
};
|
||||
79
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/sample-sorter.js
generated
vendored
Normal file
79
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/sample-sorter.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.sampleSorter = void 0;
|
||||
const log_1 = require("../../log");
|
||||
const sampleSorter = ({ logLevel, getAllChunksProcessedForPlaylist, }) => {
|
||||
const streamsWithTracks = [];
|
||||
const audioCallbacks = {};
|
||||
const videoCallbacks = {};
|
||||
let latestSample = {};
|
||||
return {
|
||||
clearSamples: () => {
|
||||
latestSample = {};
|
||||
},
|
||||
addToStreamWithTrack: (src) => {
|
||||
streamsWithTracks.push(src);
|
||||
},
|
||||
addVideoStreamToConsider: (src, callback) => {
|
||||
videoCallbacks[src] = callback;
|
||||
},
|
||||
addAudioStreamToConsider: (src, callback) => {
|
||||
audioCallbacks[src] = callback;
|
||||
},
|
||||
hasAudioStreamToConsider: (src) => {
|
||||
return Boolean(audioCallbacks[src]);
|
||||
},
|
||||
hasVideoStreamToConsider: (src) => {
|
||||
return Boolean(videoCallbacks[src]);
|
||||
},
|
||||
addAudioSample: async (src, sample) => {
|
||||
const callback = audioCallbacks[src];
|
||||
if (!callback) {
|
||||
throw new Error('No callback found for audio sample');
|
||||
}
|
||||
latestSample[src] = sample.decodingTimestamp;
|
||||
await callback(sample);
|
||||
},
|
||||
addVideoSample: async (src, sample) => {
|
||||
const callback = videoCallbacks[src];
|
||||
if (!callback) {
|
||||
throw new Error('No callback found for video sample.');
|
||||
}
|
||||
latestSample[src] = sample.decodingTimestamp;
|
||||
await callback(sample);
|
||||
},
|
||||
getNextStreamToRun: (streams) => {
|
||||
var _a, _b, _c;
|
||||
for (const stream of streams) {
|
||||
if (getAllChunksProcessedForPlaylist(stream)) {
|
||||
continue;
|
||||
}
|
||||
// If a stream does not have a track yet, work on that
|
||||
if (!streamsWithTracks.includes(stream)) {
|
||||
log_1.Log.trace(logLevel, `Did not yet detect track of ${stream}, working on that`);
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
let smallestDts = Infinity;
|
||||
for (const stream of streams) {
|
||||
if (getAllChunksProcessedForPlaylist(stream)) {
|
||||
continue;
|
||||
}
|
||||
if (((_a = latestSample[stream]) !== null && _a !== void 0 ? _a : 0) < smallestDts) {
|
||||
smallestDts = (_b = latestSample[stream]) !== null && _b !== void 0 ? _b : 0;
|
||||
}
|
||||
}
|
||||
for (const stream of streams) {
|
||||
if (getAllChunksProcessedForPlaylist(stream)) {
|
||||
continue;
|
||||
}
|
||||
if (((_c = latestSample[stream]) !== null && _c !== void 0 ? _c : 0) === smallestDts) {
|
||||
log_1.Log.trace(logLevel, `Working on ${stream} because it has the smallest DTS`);
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
throw new Error('should be done with parsing now');
|
||||
},
|
||||
};
|
||||
};
|
||||
exports.sampleSorter = sampleSorter;
|
||||
5
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seek/get-chunk-to-seek-to.d.ts
generated
vendored
Normal file
5
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seek/get-chunk-to-seek-to.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { M3uChunk } from '../get-chunks';
|
||||
export declare const getChunkToSeekTo: ({ chunks, seekToSecondsToProcess, }: {
|
||||
chunks: M3uChunk[];
|
||||
seekToSecondsToProcess: number;
|
||||
}) => number;
|
||||
14
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seek/get-chunk-to-seek-to.js
generated
vendored
Normal file
14
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seek/get-chunk-to-seek-to.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getChunkToSeekTo = void 0;
|
||||
const getChunkToSeekTo = ({ chunks, seekToSecondsToProcess, }) => {
|
||||
let duration = 0;
|
||||
for (let i = 0; i < chunks.length; i++) {
|
||||
if (duration >= seekToSecondsToProcess) {
|
||||
return Math.max(0, i - 1);
|
||||
}
|
||||
duration += chunks[i].duration;
|
||||
}
|
||||
return Math.max(0, chunks.length - 1);
|
||||
};
|
||||
exports.getChunkToSeekTo = getChunkToSeekTo;
|
||||
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seeking-hints.d.ts
generated
vendored
Normal file
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seeking-hints.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { M3u8SeekingHints } from '../../seeking-hints';
|
||||
export declare const getSeekingHintsForM3u: () => M3u8SeekingHints;
|
||||
9
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seeking-hints.js
generated
vendored
Normal file
9
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/seeking-hints.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getSeekingHintsForM3u = void 0;
|
||||
const getSeekingHintsForM3u = () => {
|
||||
return {
|
||||
type: 'm3u8-seeking-hints',
|
||||
};
|
||||
};
|
||||
exports.getSeekingHintsForM3u = getSeekingHintsForM3u;
|
||||
20
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/select-stream.d.ts
generated
vendored
Normal file
20
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/select-stream.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { M3uAssociatedPlaylist, M3uStream } from './get-streams';
|
||||
export type SelectM3uStreamFnOptions = {
|
||||
streams: M3uStream[];
|
||||
};
|
||||
export type SelectM3uStreamFn = (options: SelectM3uStreamFnOptions) => number | Promise<number>;
|
||||
export type SelectM3uAssociatedPlaylistsFnOptions = {
|
||||
associatedPlaylists: M3uAssociatedPlaylist[];
|
||||
};
|
||||
export type SelectM3uAssociatedPlaylistsFn = (options: SelectM3uAssociatedPlaylistsFnOptions) => M3uAssociatedPlaylist[] | Promise<M3uAssociatedPlaylist[]>;
|
||||
export declare const selectAssociatedPlaylists: ({ playlists, fn, skipAudioTracks, }: {
|
||||
playlists: M3uAssociatedPlaylist[];
|
||||
fn: SelectM3uAssociatedPlaylistsFn;
|
||||
skipAudioTracks: boolean;
|
||||
}) => Promise<M3uAssociatedPlaylist[]>;
|
||||
export declare const defaultSelectM3uAssociatedPlaylists: SelectM3uAssociatedPlaylistsFn;
|
||||
export declare const selectStream: ({ streams, fn, }: {
|
||||
streams: M3uStream[];
|
||||
fn: SelectM3uStreamFn;
|
||||
}) => Promise<M3uStream>;
|
||||
export declare const defaultSelectM3uStreamFn: SelectM3uStreamFn;
|
||||
47
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/select-stream.js
generated
vendored
Normal file
47
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/select-stream.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.defaultSelectM3uStreamFn = exports.selectStream = exports.defaultSelectM3uAssociatedPlaylists = exports.selectAssociatedPlaylists = void 0;
|
||||
const selectAssociatedPlaylists = async ({ playlists, fn, skipAudioTracks, }) => {
|
||||
if (playlists.length < 1) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
const streams = await fn({ associatedPlaylists: playlists });
|
||||
if (!Array.isArray(streams)) {
|
||||
throw new Error('Expected an array of associated playlists');
|
||||
}
|
||||
const selectedStreams = [];
|
||||
for (const stream of streams) {
|
||||
if (stream.isAudio && skipAudioTracks) {
|
||||
continue;
|
||||
}
|
||||
if (!playlists.find((playlist) => playlist.src === stream.src)) {
|
||||
throw new Error(`The associated playlist ${JSON.stringify(streams)} cannot be selected because it was not in the list of selectable playlists`);
|
||||
}
|
||||
selectedStreams.push(stream);
|
||||
}
|
||||
return selectedStreams;
|
||||
};
|
||||
exports.selectAssociatedPlaylists = selectAssociatedPlaylists;
|
||||
const defaultSelectM3uAssociatedPlaylists = ({ associatedPlaylists }) => {
|
||||
if (associatedPlaylists.length === 1) {
|
||||
return associatedPlaylists;
|
||||
}
|
||||
return associatedPlaylists.filter((playlist) => playlist.default);
|
||||
};
|
||||
exports.defaultSelectM3uAssociatedPlaylists = defaultSelectM3uAssociatedPlaylists;
|
||||
const selectStream = async ({ streams, fn, }) => {
|
||||
if (streams.length < 1) {
|
||||
throw new Error('No streams found');
|
||||
}
|
||||
const selectedStreamId = await fn({ streams });
|
||||
const selectedStream = streams.find((stream) => stream.id === selectedStreamId);
|
||||
if (!selectedStream) {
|
||||
throw new Error(`No stream with the id ${selectedStreamId} found`);
|
||||
}
|
||||
return Promise.resolve(selectedStream);
|
||||
};
|
||||
exports.selectStream = selectStream;
|
||||
const defaultSelectM3uStreamFn = ({ streams }) => {
|
||||
return Promise.resolve(streams[0].id);
|
||||
};
|
||||
exports.defaultSelectM3uStreamFn = defaultSelectM3uStreamFn;
|
||||
88
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/types.d.ts
generated
vendored
Normal file
88
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
import type { ParseMediaSrc } from '../../options';
|
||||
export type M3uHeader = {
|
||||
type: 'm3u-header';
|
||||
};
|
||||
export type M3uVersion = {
|
||||
type: 'm3u-version';
|
||||
version: string;
|
||||
};
|
||||
export type M3uIndependentSegments = {
|
||||
type: 'm3u-independent-segments';
|
||||
};
|
||||
export type M3uMedia = {
|
||||
type: 'm3u-media';
|
||||
};
|
||||
export type M3uTargetDuration = {
|
||||
type: 'm3u-target-duration';
|
||||
duration: number;
|
||||
};
|
||||
export type M3uPlaylistType = {
|
||||
type: 'm3u-playlist-type';
|
||||
playlistType: string;
|
||||
};
|
||||
export type M3uPlaylist = {
|
||||
type: 'm3u-playlist';
|
||||
boxes: M3uBox[];
|
||||
src: ParseMediaSrc;
|
||||
};
|
||||
export type M3uExtInf = {
|
||||
type: 'm3u-extinf';
|
||||
value: number;
|
||||
};
|
||||
export type M3uEndList = {
|
||||
type: 'm3u-endlist';
|
||||
};
|
||||
export type M3uMediaSequence = {
|
||||
type: 'm3u-media-sequence';
|
||||
value: number;
|
||||
};
|
||||
export type M3uDiscontinuitySequence = {
|
||||
type: 'm3u-discontinuity-sequence';
|
||||
value: number;
|
||||
};
|
||||
export type M3uIFrameStreamInfo = {
|
||||
type: 'm3u-i-frame-stream-info';
|
||||
};
|
||||
export type M3uMap = {
|
||||
type: 'm3u-map';
|
||||
value: string;
|
||||
};
|
||||
export type M3uStreamInfo = {
|
||||
type: 'm3u-stream-info';
|
||||
bandwidthInBitsPerSec: number | null;
|
||||
averageBandwidthInBitsPerSec: number | null;
|
||||
codecs: string[] | null;
|
||||
dimensions: {
|
||||
width: number;
|
||||
height: number;
|
||||
} | null;
|
||||
audio: string | null;
|
||||
};
|
||||
export type M3uMediaInfo = {
|
||||
type: 'm3u-media-info';
|
||||
groupId: string;
|
||||
language: string | null;
|
||||
name: string | null;
|
||||
autoselect: boolean;
|
||||
default: boolean;
|
||||
channels: number | null;
|
||||
uri: string;
|
||||
mediaType: string | null;
|
||||
};
|
||||
export type M3uTextValue = {
|
||||
type: 'm3u-text-value';
|
||||
value: string;
|
||||
};
|
||||
export type M3uAllowCache = {
|
||||
type: 'm3u-allow-cache';
|
||||
allowsCache: boolean;
|
||||
};
|
||||
export type M3uProgramDateTime = {
|
||||
type: 'm3u-program-date-time';
|
||||
dateTime: string;
|
||||
};
|
||||
export type M3uBox = M3uHeader | M3uPlaylist | M3uVersion | M3uIndependentSegments | M3uStreamInfo | M3uTargetDuration | M3uPlaylistType | M3uExtInf | M3uMedia | M3uMediaInfo | M3uEndList | M3uMediaSequence | M3uDiscontinuitySequence | M3uMap | M3uIFrameStreamInfo | M3uTextValue | M3uAllowCache | M3uProgramDateTime;
|
||||
export type M3uStructure = {
|
||||
type: 'm3u';
|
||||
boxes: M3uBox[];
|
||||
};
|
||||
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/types.js
generated
vendored
Normal file
2
remotion/node_modules/@remotion/media-parser/dist/containers/m3u/types.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
Reference in New Issue
Block a user