mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 02:43:48 +02:00
Remove createInputFrom, changed meaning of PathedSource, add CustomPathedSource
This commit is contained in:
@@ -630,9 +630,12 @@ await conversion.execute();
|
||||
## Reading HLS playlists
|
||||
|
||||
```ts
|
||||
import { createInputFrom, HLS_FORMATS, desc } from 'mediabunny';
|
||||
import { Input, UrlSource, HLS_FORMATS, desc } from 'mediabunny';
|
||||
|
||||
const input = createInputFrom('https://example.com/master.m3u8', HLS_FORMATS);
|
||||
const input = new Input({
|
||||
source: new UrlSource('https://example.com/master.m3u8'),
|
||||
formats: HLS_FORMATS,
|
||||
});
|
||||
|
||||
// Get all tracks
|
||||
const tracks = await input.getTracks();
|
||||
|
||||
@@ -8,30 +8,17 @@ Mediabunny exposes HLS playlists as if they were a single giant input file. Like
|
||||
|
||||
## HLS inputs
|
||||
|
||||
HLS playlists (master & media) are read through the same `Input` interface as all other media files in Mediabunny. The difference is that HLS uses multiple files, meaning a `PathedSource` is required:
|
||||
HLS playlists (master & media) are read through the same `Input` interface as all other media files in Mediabunny. HLS must read multiple files, meaning any [`PathedSource`](../api/PathedSource) is required:
|
||||
```ts
|
||||
import { Input, PathedSource, HLS_FORMATS } from 'mediabunny';
|
||||
import { Input, UrlSource, HLS_FORMATS } from 'mediabunny';
|
||||
|
||||
const input = new Input({
|
||||
source: new PathedSource(
|
||||
'https://example.com/master.m3u8', // The path to the entry file
|
||||
({ path }) => new UrlSource(path),
|
||||
),
|
||||
source: new UrlSource('https://example.com/master.m3u8'),
|
||||
formats: HLS_FORMATS, // HLS_FORMATS includes HLS as well as the commonly-used segment formats
|
||||
});
|
||||
```
|
||||
|
||||
The `PathedSource` requires that you return a [`Source`](../api/Source) for every file (identified by a [path](../api/FilePath)) that Mediabunny wants to read.
|
||||
|
||||
Since this pattern is common and kind of cumbersome to write, there exists a shortcut:
|
||||
```ts
|
||||
// From a URL:
|
||||
const input = createInputFrom('https://example.com/master.m3u8', HLS_FORMATS);
|
||||
// From a file (server-side environment):
|
||||
const input = createInputFrom('/path/to/master.m3u8', HLS_FORMATS);
|
||||
```
|
||||
|
||||
However, the `PathedSource` variant is still useful for custom sources; maybe your HLS files don't reside behind a URL but you have them in memory, or in IndexedDB. In this case, there's no way around `PathedSource`, since you'll need to supply your own "path to data" function.
|
||||
You can supply any custom "path to data" resolution logic by using [`CustomPathedSource`](../api/CustomPathedSource).
|
||||
|
||||
## Reading tracks
|
||||
|
||||
|
||||
@@ -40,17 +40,6 @@ Reading operations will throw an error if the file format could not be recognize
|
||||
Simply creating an instance of `Input` will perform zero reads and is practically free. The file will only be read once data is requested.
|
||||
:::
|
||||
|
||||
For convenience, `createInputFrom` automatically constructs an `Input` along with the matching source for a given value:
|
||||
|
||||
```ts
|
||||
import { createInputFrom, ALL_FORMATS } from 'mediabunny';
|
||||
|
||||
const input = createInputFrom(file, ALL_FORMATS);
|
||||
const input = createInputFrom(arrayBuffer, ALL_FORMATS);
|
||||
const input = createInputFrom('https://example.com/video.mp4', ALL_FORMATS);
|
||||
const input = createInputFrom('./video.mp4', ALL_FORMATS); // Uses the file system server-side, fetch client-side
|
||||
```
|
||||
|
||||
## Reading file metadata
|
||||
|
||||
With our instance of `Input` created, you can now start reading file-level metadata.
|
||||
@@ -832,20 +821,34 @@ recorder.start(1000);
|
||||
setTimeout(() => recorder.stop(), 10_000); // Stop recording after 10s
|
||||
```
|
||||
|
||||
## Pathed (multi-file) sources
|
||||
### `PathedSource`
|
||||
|
||||
Some media formats reference more than one file. For example, an [HLS](./input-formats) stream consists of a master playlist that points to one or more media playlists, each of which in turn references many media segment files. To read this kind of multi-file media, Mediabunny needs a way to resolve those file paths into [input sources](#input-sources). You can do this using `PathedSource`.
|
||||
Some media formats reference more than one file. For example, an HLS stream consists of a master playlist that points to one or more media playlists, each of which in turn references many media segment files. To read this kind of multi-file media, Mediabunny needs a way to resolve a source for each file path.
|
||||
|
||||
This can be done with `PathedSource`. A `PathedSource` wraps a *root path* (the entry file of the media) together with a callback that produces a `Source` for each requested file path. It is an abstract class, so you can't use it directly, but it provides the necessary interface to read multi-file media. It is implemented by:
|
||||
- [`UrlSource`](#urlsource)
|
||||
- [`FilePathSource`](#filepathsource)
|
||||
- [`CustomPathedSource`](#custompathedsource)
|
||||
|
||||
### `CustomPathedSource`
|
||||
|
||||
Allows you to implement a user-defined [`PathedSource`](#pathedsource) to provide an arbitrary "file path to data" mapping function. Useful when your data is stored in a custom structure, for example OPFS:
|
||||
|
||||
A `PathedSource` wraps a *root path* (the entry file of the media) together with a callback that produces a `Source` for each requested file path:
|
||||
```ts
|
||||
import { Input, HLS, PathedSource, UrlSource } from 'mediabunny';
|
||||
import { Input, CustomPathedSource, BlobSource } from 'mediabunny';
|
||||
|
||||
const root = await navigator.storage.getDirectory();
|
||||
|
||||
const input = new Input({
|
||||
formats: [HLS],
|
||||
source: new PathedSource(
|
||||
'https://example.com/stream/master.m3u8',
|
||||
({ path, isRoot }) => new UrlSource(path),
|
||||
source: new CustomPathedSource(
|
||||
'master.m3u8',
|
||||
async ({ path }) => {
|
||||
const handle = await root.getFileHandle(path);
|
||||
const file = await handle.getFile();
|
||||
return new BlobSource(file);
|
||||
},
|
||||
),
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
@@ -857,12 +860,17 @@ type SourceRequest = {
|
||||
};
|
||||
```
|
||||
|
||||
You can return either a `Source` or a [`SourceRef`](../api/SourceRef). The kind of `Source` you create inside the callback is up to you - use `UrlSource` for streams served over HTTP, `FilePathSource` for files on disk, `BufferSource` for files in memory, or any other source type (or mix of them) that fits.
|
||||
|
||||
## Init inputs
|
||||
|
||||
Some file formats contain track initialization info in a *separate* file; CMAF is one example. To supply these to Mediabunny, load the initialization file as a separate `Input` and then pass it as an `initInput`:
|
||||
```ts
|
||||
const initInput = createInputFrom('init.mp4', ALL_FORMATS);
|
||||
const input = createInputFrom('data.mp4', ALL_FORMATS, { initInput });
|
||||
const initInput = new Input({
|
||||
source: new FilePathSource('init.mp4'),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
const input = new Input({
|
||||
source: new FilePathSource('data.mp4'),
|
||||
formats: ALL_FORMATS,
|
||||
initInput,
|
||||
});
|
||||
```
|
||||
Reference in New Issue
Block a user