mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-03 05:43:50 +02:00
Fix file compression example, add processedTime parameter to onProgress for Conversion API
This commit is contained in:
@@ -62,31 +62,41 @@ const compressFile = async (resource: File | string) => {
|
|||||||
currentConversion = await Conversion.init({
|
currentConversion = await Conversion.init({
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
video: track => ({
|
tracks: 'primary', // Keep only one track per type
|
||||||
|
video: {
|
||||||
width: 320, // Height will be deduced automatically to retain aspect ratio
|
width: 320, // Height will be deduced automatically to retain aspect ratio
|
||||||
bitrate: QUALITY_VERY_LOW,
|
bitrate: QUALITY_VERY_LOW,
|
||||||
discard: track.number > 1, // Keep only the first video track
|
},
|
||||||
}),
|
audio: {
|
||||||
audio: track => ({
|
bitrate: QUALITY_VERY_LOW,
|
||||||
bitrate: 32e3,
|
},
|
||||||
discard: track.number > 1, // Keep only the first audio track
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!currentConversion.isValid) {
|
||||||
|
console.info(currentConversion.discardedTracks);
|
||||||
|
throw new Error('Conversion is invalid and cannot be executed; see the console for more.');
|
||||||
|
}
|
||||||
|
|
||||||
// Keep track of progress
|
// Keep track of progress
|
||||||
let progress = 0;
|
let progress = 0;
|
||||||
currentConversion.onProgress = newProgress => progress = newProgress;
|
let processedTime = 0;
|
||||||
|
let startTime: number | null = null;
|
||||||
|
|
||||||
const fileDuration = (await input.computeDuration()) - (await input.getFirstTimestamp());
|
currentConversion.onProgress = (newProgress, newProcessedTime) => {
|
||||||
const startTime = performance.now();
|
progress = newProgress;
|
||||||
|
processedTime = newProcessedTime;
|
||||||
|
startTime ??= performance.now();
|
||||||
|
};
|
||||||
|
|
||||||
const updateProgress = () => {
|
const updateProgress = () => {
|
||||||
progressBar.style.width = `${progress * 100}%`;
|
progressBar.style.width = `${progress * 100}%`;
|
||||||
|
|
||||||
const now = performance.now();
|
if (startTime !== null) {
|
||||||
const elapsedSeconds = (now - startTime) / 1000;
|
const now = performance.now();
|
||||||
const factor = fileDuration / (elapsedSeconds / progress);
|
const elapsedSeconds = (now - startTime) / 1000;
|
||||||
speedometer.textContent = `Speed: ~${factor.toPrecision(3)}x real time`;
|
const factor = processedTime / elapsedSeconds;
|
||||||
|
speedometer.textContent = `Speed: ~${factor.toPrecision(3)}x real time`;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the progress indicator regularly
|
// Update the progress indicator regularly
|
||||||
|
|||||||
+48
-37
@@ -563,13 +563,15 @@ export class Conversion {
|
|||||||
_canceled = false;
|
_canceled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback that is fired whenever the conversion progresses. Returns a number between 0 and 1, indicating the
|
* A callback that is fired whenever the conversion progresses. Gets passed as first argument a number between
|
||||||
* completion of the conversion. Note that a progress of 1 doesn't necessarily mean the conversion is complete;
|
* 0 and 1, indicating the completion of the conversion. Note that a progress of 1 doesn't necessarily mean the
|
||||||
* the conversion is complete once `execute()` resolves.
|
* conversion is complete; the conversion is complete once `execute()` resolves.
|
||||||
|
*
|
||||||
|
* As second argument, this callback receives the input time in seconds that has been processed.
|
||||||
*
|
*
|
||||||
* In order for progress to be computed, this property must be set before `execute` is called.
|
* In order for progress to be computed, this property must be set before `execute` is called.
|
||||||
*/
|
*/
|
||||||
onProgress?: (progress: number) => unknown = undefined;
|
onProgress?: (progress: number, processedTime: number) => unknown = undefined;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_computeProgress = false;
|
_computeProgress = false;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@@ -929,7 +931,11 @@ export class Conversion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isValid) {
|
if (!this.isValid) {
|
||||||
warnElements.push('\n\n' + this._getInvalidityExplanation().join(''));
|
if (warnElements.length > 0) {
|
||||||
|
warnElements.push('\n\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
warnElements.push(this._getInvalidityExplanation().join(''));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warnElements.length > 0) {
|
if (warnElements.length > 0) {
|
||||||
@@ -949,7 +955,7 @@ export class Conversion {
|
|||||||
} else {
|
} else {
|
||||||
const encodabilityIsTheProblem = this.discardedTracks.every(x =>
|
const encodabilityIsTheProblem = this.discardedTracks.every(x =>
|
||||||
x.reason === 'discarded_by_user' || x.reason === 'no_encodable_target_codec',
|
x.reason === 'discarded_by_user' || x.reason === 'no_encodable_target_codec',
|
||||||
);
|
) && this.discardedTracks.some(x => x.reason === 'no_encodable_target_codec');
|
||||||
|
|
||||||
elements.push(
|
elements.push(
|
||||||
'Due to discarded tracks, this conversion cannot be executed.',
|
'Due to discarded tracks, this conversion cannot be executed.',
|
||||||
@@ -1054,7 +1060,7 @@ export class Conversion {
|
|||||||
this._maxTimestamps.set(id, 0);
|
this._maxTimestamps.set(id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onProgress?.(0);
|
this.onProgress?.(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.output.start();
|
await this.output.start();
|
||||||
@@ -1078,7 +1084,8 @@ export class Conversion {
|
|||||||
await this.output.finalize();
|
await this.output.finalize();
|
||||||
|
|
||||||
if (this._computeProgress) {
|
if (this._computeProgress) {
|
||||||
this.onProgress?.(1);
|
const minTimestamp = Math.min(...this._maxTimestamps.values());
|
||||||
|
this.onProgress?.(1, minTimestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1547,21 +1554,23 @@ export class Conversion {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const finalSample of finalSamples) {
|
try {
|
||||||
if (this._canceled) {
|
for (const finalSample of finalSamples) {
|
||||||
break;
|
if (this._canceled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await source.add(finalSample);
|
||||||
|
|
||||||
|
if (this._synchronizer.shouldWait(outputTrackId, finalSample.timestamp)) {
|
||||||
|
await this._synchronizer.wait(finalSample.timestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
await source.add(finalSample);
|
for (const finalSample of finalSamples) {
|
||||||
|
if (finalSample !== sample) {
|
||||||
if (this._synchronizer.shouldWait(outputTrackId, finalSample.timestamp)) {
|
finalSample.close();
|
||||||
await this._synchronizer.wait(finalSample.timestamp);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const finalSample of finalSamples) {
|
|
||||||
if (finalSample !== sample) {
|
|
||||||
finalSample.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1801,21 +1810,23 @@ export class Conversion {
|
|||||||
finalSamples = processed;
|
finalSamples = processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const finalSample of finalSamples) {
|
try {
|
||||||
if (this._canceled) {
|
for (const finalSample of finalSamples) {
|
||||||
break;
|
if (this._canceled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await source.add(finalSample);
|
||||||
|
|
||||||
|
if (this._synchronizer.shouldWait(outputTrackId, finalSample.timestamp)) {
|
||||||
|
await this._synchronizer.wait(finalSample.timestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
await source.add(finalSample);
|
for (const finalSample of finalSamples) {
|
||||||
|
if (finalSample !== sample) {
|
||||||
if (this._synchronizer.shouldWait(outputTrackId, finalSample.timestamp)) {
|
finalSample.close();
|
||||||
await this._synchronizer.wait(finalSample.timestamp);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const finalSample of finalSamples) {
|
|
||||||
if (finalSample !== sample) {
|
|
||||||
finalSample.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1890,7 +1901,7 @@ export class Conversion {
|
|||||||
|
|
||||||
if (newProgress !== this._lastProgress) {
|
if (newProgress !== this._lastProgress) {
|
||||||
this._lastProgress = newProgress;
|
this._lastProgress = newProgress;
|
||||||
this.onProgress?.(newProgress);
|
this.onProgress?.(newProgress, minTimestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user