mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 19:03:46 +02:00
Add FilePathTarget
This commit is contained in:
@@ -290,7 +290,7 @@ By default, data will be emitted by the `StreamTarget` as soon as it is availabl
|
|||||||
new StreamTarget(writable, {
|
new StreamTarget(writable, {
|
||||||
chunked: true,
|
chunked: true,
|
||||||
chunkSize: 2 ** 20, // Optional; defaults to 16 MiB
|
chunkSize: 2 ** 20, // Optional; defaults to 16 MiB
|
||||||
}),
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Applying backpressure
|
#### Applying backpressure
|
||||||
@@ -329,6 +329,33 @@ const output = new Output({
|
|||||||
await output.finalize(); // Will automatically close the writable stream
|
await output.finalize(); // Will automatically close the writable stream
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `FilePathTarget`
|
||||||
|
|
||||||
|
This target writes to a file at the specified path. It is intended for server-side usage in Node, Bun, or Deno, and offers a simpler API than `StreamTarget` when you just want to write directly to a file path.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Output, FilePathTarget } from 'mediabunny';
|
||||||
|
|
||||||
|
const output = new Output({
|
||||||
|
target: new FilePathTarget('/path/to/output.mp4'),
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
await output.finalize(); // Will automatically close the file handle
|
||||||
|
```
|
||||||
|
|
||||||
|
The internally held file handle will be closed when `finalize` or `cancel` are called on the `Output`.
|
||||||
|
|
||||||
|
Writing is chunked by default, for performance. Like `StreamTarget`, you can configure chunked mode options:
|
||||||
|
```ts
|
||||||
|
new FilePathTarget('/path/to/output.mp4', {
|
||||||
|
chunked: false, // Disable chunking (slower)
|
||||||
|
chunkSize: 2 ** 20, // Optional; defaults to 16 MiB
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### `NullTarget`
|
### `NullTarget`
|
||||||
|
|
||||||
This target simply discards all data that is passed into it. It is useful for when you need an `Output` but extract data from it differently, for example through output format-specific callbacks or encoder events.
|
This target simply discards all data that is passed into it. It is useful for when you need an `Output` but extract data from it differently, for example through output format-specific callbacks or encoder events.
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ export {
|
|||||||
export {
|
export {
|
||||||
Target,
|
Target,
|
||||||
BufferTarget,
|
BufferTarget,
|
||||||
|
FilePathTarget,
|
||||||
|
FilePathTargetOptions,
|
||||||
NullTarget,
|
NullTarget,
|
||||||
StreamTarget,
|
StreamTarget,
|
||||||
StreamTargetOptions,
|
StreamTargetOptions,
|
||||||
|
|||||||
@@ -6,8 +6,15 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { FileHandle } from 'node:fs/promises';
|
||||||
import { BufferTargetWriter, NullTargetWriter, StreamTargetWriter, Writer } from './writer';
|
import { BufferTargetWriter, NullTargetWriter, StreamTargetWriter, Writer } from './writer';
|
||||||
import { Output } from './output';
|
import { Output } from './output';
|
||||||
|
import * as nodeAlias from './node';
|
||||||
|
import { assert } from './misc';
|
||||||
|
|
||||||
|
const node = typeof nodeAlias !== 'undefined'
|
||||||
|
? nodeAlias // Aliasing it prevents some bundler warnings
|
||||||
|
: undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for targets, specifying where output files are written.
|
* Base class for targets, specifying where output files are written.
|
||||||
@@ -121,6 +128,68 @@ export class StreamTarget extends Target {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for {@link FilePathTarget}.
|
||||||
|
* @group Output targets
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type FilePathTargetOptions = StreamTargetOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A target that writes to a file at the specified path. Intended for server-side usage in Node, Bun, or Deno.
|
||||||
|
*
|
||||||
|
* Writing is chunked by default. The internally held file handle will be closed when `.finalize()` or `.cancel()` are
|
||||||
|
* called on the corresponding {@link Output}.
|
||||||
|
* @group Output targets
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export class FilePathTarget extends Target {
|
||||||
|
/** @internal */
|
||||||
|
_streamTarget: StreamTarget;
|
||||||
|
/** @internal */
|
||||||
|
_fileHandle: FileHandle | null = null;
|
||||||
|
|
||||||
|
/** Creates a new {@link FilePathTarget} that writes to the file at the specified file path. */
|
||||||
|
constructor(filePath: string, options: FilePathTargetOptions = {}) {
|
||||||
|
if (typeof filePath !== 'string') {
|
||||||
|
throw new TypeError('filePath must be a string.');
|
||||||
|
}
|
||||||
|
if (!options || typeof options !== 'object') {
|
||||||
|
throw new TypeError('options must be an object.');
|
||||||
|
}
|
||||||
|
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Let's back this target with a StreamTarget, makes the implementation very simple
|
||||||
|
const writable = new WritableStream<StreamTargetChunk>({
|
||||||
|
start: async () => {
|
||||||
|
this._fileHandle = await node.fs.open(filePath, 'w');
|
||||||
|
},
|
||||||
|
write: async (chunk) => {
|
||||||
|
assert(this._fileHandle);
|
||||||
|
await this._fileHandle.write(chunk.data, 0, chunk.data.byteLength, chunk.position);
|
||||||
|
},
|
||||||
|
close: async () => {
|
||||||
|
if (this._fileHandle) {
|
||||||
|
await this._fileHandle.close();
|
||||||
|
this._fileHandle = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this._streamTarget = new StreamTarget(writable, {
|
||||||
|
chunked: true,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
this._streamTarget._output = this._output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
_createWriter(): Writer {
|
||||||
|
return this._streamTarget._createWriter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This target just discards all incoming data. It is useful for when you need an {@link Output} but extract data from
|
* This target just discards all incoming data. It is useful for when you need an {@link Output} but extract data from
|
||||||
* it differently, for example through format-specific callbacks (`onMoof`, `onMdat`, ...) or encoder events.
|
* it differently, for example through format-specific callbacks (`onMoof`, `onMdat`, ...) or encoder events.
|
||||||
|
|||||||
Reference in New Issue
Block a user