mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-09 16:53:47 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
394eede178 | ||
|
|
6b5ae29252 | ||
|
|
656c7e70a8 | ||
|
|
3c4f4c27a3 | ||
|
|
166298df2c | ||
|
|
fdfab4660f | ||
|
|
1c4d1c70a8 | ||
|
|
018c2ca67b |
+1
-1
@@ -2,7 +2,7 @@ node_modules
|
|||||||
/dist
|
/dist
|
||||||
/dist-docs
|
/dist-docs
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/docs/.vitepress/cache
|
docs/.vitepress/cache
|
||||||
/docs/api
|
/docs/api
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const track = await input.getPrimaryVideoTrack();
|
const track = await input.getPrimaryVideoTrack();
|
||||||
console.log(await track.computeFrameRateMetrics());
|
console.log(await track.getDecoderConfig());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|||||||
Generated
+10
-10
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mediabunny",
|
"name": "mediabunny",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mediabunny",
|
"name": "mediabunny",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
".",
|
".",
|
||||||
@@ -12958,7 +12958,7 @@
|
|||||||
},
|
},
|
||||||
"packages/aac-encoder": {
|
"packages/aac-encoder": {
|
||||||
"name": "@mediabunny/aac-encoder",
|
"name": "@mediabunny/aac-encoder",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/emscripten": "^1.40.1"
|
"@types/emscripten": "^1.40.1"
|
||||||
@@ -12973,7 +12973,7 @@
|
|||||||
},
|
},
|
||||||
"packages/ac3": {
|
"packages/ac3": {
|
||||||
"name": "@mediabunny/ac3",
|
"name": "@mediabunny/ac3",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/emscripten": "^1.40.1"
|
"@types/emscripten": "^1.40.1"
|
||||||
@@ -12988,7 +12988,7 @@
|
|||||||
},
|
},
|
||||||
"packages/dts": {
|
"packages/dts": {
|
||||||
"name": "@mediabunny/dts",
|
"name": "@mediabunny/dts",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/emscripten": "^1.40.1"
|
"@types/emscripten": "^1.40.1"
|
||||||
@@ -13003,7 +13003,7 @@
|
|||||||
},
|
},
|
||||||
"packages/flac-encoder": {
|
"packages/flac-encoder": {
|
||||||
"name": "@mediabunny/flac-encoder",
|
"name": "@mediabunny/flac-encoder",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/emscripten": "^1.40.1"
|
"@types/emscripten": "^1.40.1"
|
||||||
@@ -13018,7 +13018,7 @@
|
|||||||
},
|
},
|
||||||
"packages/mp3-encoder": {
|
"packages/mp3-encoder": {
|
||||||
"name": "@mediabunny/mp3-encoder",
|
"name": "@mediabunny/mp3-encoder",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/emscripten": "^1.40.1"
|
"@types/emscripten": "^1.40.1"
|
||||||
@@ -13033,7 +13033,7 @@
|
|||||||
},
|
},
|
||||||
"packages/prores": {
|
"packages/prores": {
|
||||||
"name": "@mediabunny/prores",
|
"name": "@mediabunny/prores",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"turbores": "^1.2.2"
|
"turbores": "^1.2.2"
|
||||||
@@ -13048,10 +13048,10 @@
|
|||||||
},
|
},
|
||||||
"packages/server": {
|
"packages/server": {
|
||||||
"name": "@mediabunny/server",
|
"name": "@mediabunny/server",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mediabunny/prores": "^1.55.0",
|
"@mediabunny/prores": "^1.55.2",
|
||||||
"node-av": "^6.0.0"
|
"node-av": "^6.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mediabunny",
|
"name": "mediabunny",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.",
|
"description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@mediabunny/aac-encoder",
|
"name": "@mediabunny/aac-encoder",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "AAC encoder extension for Mediabunny, based on libavcodec.",
|
"description": "AAC encoder extension for Mediabunny, based on libavcodec.",
|
||||||
"main": "./dist/bundles/mediabunny-aac-encoder.mjs",
|
"main": "./dist/bundles/mediabunny-aac-encoder.mjs",
|
||||||
"module": "./dist/bundles/mediabunny-aac-encoder.mjs",
|
"module": "./dist/bundles/mediabunny-aac-encoder.mjs",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@mediabunny/ac3",
|
"name": "@mediabunny/ac3",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "AC-3 and E-AC-3 (Dolby Digital) decoder and encoder extension for Mediabunny, based on libavcodec.",
|
"description": "AC-3 and E-AC-3 (Dolby Digital) decoder and encoder extension for Mediabunny, based on libavcodec.",
|
||||||
"main": "./dist/bundles/mediabunny-ac3.mjs",
|
"main": "./dist/bundles/mediabunny-ac3.mjs",
|
||||||
"module": "./dist/bundles/mediabunny-ac3.mjs",
|
"module": "./dist/bundles/mediabunny-ac3.mjs",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@mediabunny/dts",
|
"name": "@mediabunny/dts",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "DTS decoder and encoder extension for Mediabunny, based on libavcodec.",
|
"description": "DTS decoder and encoder extension for Mediabunny, based on libavcodec.",
|
||||||
"main": "./dist/bundles/mediabunny-dts.mjs",
|
"main": "./dist/bundles/mediabunny-dts.mjs",
|
||||||
"module": "./dist/bundles/mediabunny-dts.mjs",
|
"module": "./dist/bundles/mediabunny-dts.mjs",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@mediabunny/flac-encoder",
|
"name": "@mediabunny/flac-encoder",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "FLAC encoder extension for Mediabunny, based on libFLAC.",
|
"description": "FLAC encoder extension for Mediabunny, based on libFLAC.",
|
||||||
"main": "./dist/bundles/mediabunny-flac-encoder.mjs",
|
"main": "./dist/bundles/mediabunny-flac-encoder.mjs",
|
||||||
"module": "./dist/bundles/mediabunny-flac-encoder.mjs",
|
"module": "./dist/bundles/mediabunny-flac-encoder.mjs",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@mediabunny/mp3-encoder",
|
"name": "@mediabunny/mp3-encoder",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "MP3 encoder extension for Mediabunny, based on LAME.",
|
"description": "MP3 encoder extension for Mediabunny, based on LAME.",
|
||||||
"main": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
"main": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
||||||
"module": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
"module": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@mediabunny/prores",
|
"name": "@mediabunny/prores",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "Apple ProRes decoder extension for Mediabunny, based on TurboRes.",
|
"description": "Apple ProRes decoder extension for Mediabunny, based on TurboRes.",
|
||||||
"main": "./dist/bundles/mediabunny-prores.mjs",
|
"main": "./dist/bundles/mediabunny-prores.mjs",
|
||||||
"module": "./dist/bundles/mediabunny-prores.mjs",
|
"module": "./dist/bundles/mediabunny-prores.mjs",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@mediabunny/server",
|
"name": "@mediabunny/server",
|
||||||
"author": "Vanilagy",
|
"author": "Vanilagy",
|
||||||
"version": "1.55.0",
|
"version": "1.55.2",
|
||||||
"description": "Adds full video and audio decoder and encoder support to Mediabunny for use in server-side environments (Node, Bun, Deno). Based on NodeAV.",
|
"description": "Adds full video and audio decoder and encoder support to Mediabunny for use in server-side environments (Node, Bun, Deno). Based on NodeAV.",
|
||||||
"main": "./dist/bundles/mediabunny-server.cjs",
|
"main": "./dist/bundles/mediabunny-server.cjs",
|
||||||
"module": "./dist/bundles/mediabunny-server.mjs",
|
"module": "./dist/bundles/mediabunny-server.mjs",
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-av": "^6.0.0",
|
"node-av": "^6.0.0",
|
||||||
"@mediabunny/prores": "^1.55.0"
|
"@mediabunny/prores": "^1.55.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"mediabunny": "^1.45.0"
|
"mediabunny": "^1.45.0"
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import {
|
|||||||
parseDtsSpecificBox,
|
parseDtsSpecificBox,
|
||||||
DTS_SPECIFIC_BOX_SIZE,
|
DTS_SPECIFIC_BOX_SIZE,
|
||||||
AC3_ACMOD_CHANNEL_COUNTS,
|
AC3_ACMOD_CHANNEL_COUNTS,
|
||||||
|
extractAvcDecoderConfigurationRecord,
|
||||||
|
extractHevcDecoderConfigurationRecord,
|
||||||
} from '../codec-data';
|
} from '../codec-data';
|
||||||
import { Demuxer } from '../demuxer';
|
import { Demuxer } from '../demuxer';
|
||||||
import { Input } from '../input';
|
import { Input } from '../input';
|
||||||
@@ -1390,6 +1392,11 @@ export class IsobmffDemuxer extends Demuxer {
|
|||||||
}
|
}
|
||||||
assert(track.info);
|
assert(track.info);
|
||||||
|
|
||||||
|
if (boxInfo.contentSize === 0) {
|
||||||
|
// avcC box is empty, let's treat this like an Annex B stream
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
track.info.codecDescription = readBytes(slice, boxInfo.contentSize);
|
track.info.codecDescription = readBytes(slice, boxInfo.contentSize);
|
||||||
}; break;
|
}; break;
|
||||||
|
|
||||||
@@ -1400,6 +1407,11 @@ export class IsobmffDemuxer extends Demuxer {
|
|||||||
}
|
}
|
||||||
assert(track.info);
|
assert(track.info);
|
||||||
|
|
||||||
|
if (boxInfo.contentSize === 0) {
|
||||||
|
// hvcC box is empty, let's treat this like an Annex B stream
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
track.info.codecDescription = readBytes(slice, boxInfo.contentSize);
|
track.info.codecDescription = readBytes(slice, boxInfo.contentSize);
|
||||||
}; break;
|
}; break;
|
||||||
|
|
||||||
@@ -3407,7 +3419,15 @@ class IsobmffVideoTrackBacking extends IsobmffTrackBacking implements InputVideo
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.decoderConfigPromise ??= (async (): Promise<VideoDecoderConfig> => {
|
return this.decoderConfigPromise ??= (async (): Promise<VideoDecoderConfig> => {
|
||||||
if (this.internalTrack.info.codec === 'vp9' && !this.internalTrack.info.vp9CodecInfo) {
|
if (this.internalTrack.info.codec === 'avc' && !this.internalTrack.info.codecDescription) {
|
||||||
|
const firstPacket = await this.getFirstPacket({});
|
||||||
|
this.internalTrack.info.avcCodecInfo
|
||||||
|
= firstPacket && extractAvcDecoderConfigurationRecord(firstPacket.data);
|
||||||
|
} else if (this.internalTrack.info.codec === 'hevc' && !this.internalTrack.info.codecDescription) {
|
||||||
|
const firstPacket = await this.getFirstPacket({});
|
||||||
|
this.internalTrack.info.hevcCodecInfo
|
||||||
|
= firstPacket && extractHevcDecoderConfigurationRecord(firstPacket.data);
|
||||||
|
} else if (this.internalTrack.info.codec === 'vp9' && !this.internalTrack.info.vp9CodecInfo) {
|
||||||
const firstPacket = await this.getFirstPacket({});
|
const firstPacket = await this.getFirstPacket({});
|
||||||
this.internalTrack.info.vp9CodecInfo = firstPacket && extractVp9CodecInfoFromPacket(firstPacket.data);
|
this.internalTrack.info.vp9CodecInfo = firstPacket && extractVp9CodecInfoFromPacket(firstPacket.data);
|
||||||
} else if (this.internalTrack.info.codec === 'av1' && !this.internalTrack.info.av1CodecInfo) {
|
} else if (this.internalTrack.info.codec === 'av1' && !this.internalTrack.info.av1CodecInfo) {
|
||||||
|
|||||||
+11
-2
@@ -38,6 +38,7 @@ import {
|
|||||||
isWebKit,
|
isWebKit,
|
||||||
last,
|
last,
|
||||||
mapAsyncGenerator,
|
mapAsyncGenerator,
|
||||||
|
missingWebCodecsClassMessage,
|
||||||
promiseWithResolvers,
|
promiseWithResolvers,
|
||||||
removeItem,
|
removeItem,
|
||||||
Rotation,
|
Rotation,
|
||||||
@@ -1691,8 +1692,12 @@ export class VideoSampleSink extends BaseMediaSampleSink<VideoSample> {
|
|||||||
onError: (error: unknown) => unknown,
|
onError: (error: unknown) => unknown,
|
||||||
) {
|
) {
|
||||||
if (!(await this._track.canDecode())) {
|
if (!(await this._track.canDecode())) {
|
||||||
|
if (typeof VideoDecoder === 'undefined') {
|
||||||
|
throw new Error(missingWebCodecsClassMessage('VideoDecoder'));
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'This video track cannot be decoded by this browser. Make sure to check decodability before using'
|
'This video track cannot be decoded in this environment. Make sure to check decodability before using'
|
||||||
+ ' a track.',
|
+ ' a track.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2426,8 +2431,12 @@ export class AudioSampleSink extends BaseMediaSampleSink<AudioSample> {
|
|||||||
onError: (error: unknown) => unknown,
|
onError: (error: unknown) => unknown,
|
||||||
) {
|
) {
|
||||||
if (!(await this._track.canDecode())) {
|
if (!(await this._track.canDecode())) {
|
||||||
|
if (typeof AudioDecoder === 'undefined') {
|
||||||
|
throw new Error(missingWebCodecsClassMessage('AudioDecoder'));
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'This audio track cannot be decoded by this browser. Make sure to check decodability before using'
|
'This audio track cannot be decoded in this environment. Make sure to check decodability before using'
|
||||||
+ ' a track.',
|
+ ' a track.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -29,6 +29,7 @@ import {
|
|||||||
clearIntervalUnthrottled,
|
clearIntervalUnthrottled,
|
||||||
floorToDivisor,
|
floorToDivisor,
|
||||||
last,
|
last,
|
||||||
|
missingWebCodecsClassMessage,
|
||||||
promiseWithResolvers,
|
promiseWithResolvers,
|
||||||
roundToDivisor,
|
roundToDivisor,
|
||||||
setInt24,
|
setInt24,
|
||||||
@@ -718,7 +719,7 @@ class VideoEncoderWrapper {
|
|||||||
|
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
if (typeof VideoEncoder === 'undefined') {
|
if (typeof VideoEncoder === 'undefined') {
|
||||||
throw new Error('VideoEncoder is not supported by this browser.');
|
throw new Error(missingWebCodecsClassMessage('VideoEncoder'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The candidates only differ in their rate control, so we describe them as one config with a
|
// The candidates only differ in their rate control, so we describe them as one config with a
|
||||||
@@ -731,7 +732,7 @@ class VideoEncoderWrapper {
|
|||||||
throw new Error(
|
throw new Error(
|
||||||
`This specific encoder configuration (${firstConfig.codec}, ${rateControls.join(' / ')},`
|
`This specific encoder configuration (${firstConfig.codec}, ${rateControls.join(' / ')},`
|
||||||
+ ` ${firstConfig.width}x${firstConfig.height}, hardware acceleration:`
|
+ ` ${firstConfig.width}x${firstConfig.height}, hardware acceleration:`
|
||||||
+ ` ${firstConfig.hardwareAcceleration ?? 'no-preference'}) is not supported by this browser.`
|
+ ` ${firstConfig.hardwareAcceleration ?? 'no-preference'}) is not supported in this environment.`
|
||||||
+ ` Consider using another codec or changing your video parameters.`,
|
+ ` Consider using another codec or changing your video parameters.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1694,8 +1695,8 @@ export class MediaStreamVideoTrackSource extends VideoSource {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'When no explicit frame rate is set, MediaStreamTrackProcessor is required; but it\'s not supported'
|
'When no explicit frame rate is set, MediaStreamTrackProcessor is required; but it\'s not available'
|
||||||
+ ' by this browser.',
|
+ ' in this environment.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2210,7 +2211,7 @@ class AudioEncoderWrapper {
|
|||||||
this.initPcmEncoder();
|
this.initPcmEncoder();
|
||||||
} else {
|
} else {
|
||||||
if (typeof AudioEncoder === 'undefined') {
|
if (typeof AudioEncoder === 'undefined') {
|
||||||
throw new Error('AudioEncoder is not supported by this browser.');
|
throw new Error(missingWebCodecsClassMessage('AudioEncoder'));
|
||||||
}
|
}
|
||||||
|
|
||||||
let supported: boolean;
|
let supported: boolean;
|
||||||
@@ -2226,7 +2227,8 @@ class AudioEncoderWrapper {
|
|||||||
throw new Error(
|
throw new Error(
|
||||||
`This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps,`
|
`This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps,`
|
||||||
+ ` ${encoderConfig.numberOfChannels} channels, ${encoderConfig.sampleRate} Hz) is not`
|
+ ` ${encoderConfig.numberOfChannels} channels, ${encoderConfig.sampleRate} Hz) is not`
|
||||||
+ ` supported by this browser. Consider using another codec or changing your audio parameters.`,
|
+ ` supported in this environment. Consider using another codec or changing your`
|
||||||
|
+ ` audio parameters.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
@@ -721,6 +721,16 @@ export const getChromiumVersion = () => {
|
|||||||
return chromiumVersionCache = Number(match[1]!);
|
return chromiumVersionCache = Number(match[1]!);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const missingWebCodecsClassMessage = (className: string) => {
|
||||||
|
if (typeof globalThis.isSecureContext !== 'undefined' && !globalThis.isSecureContext) {
|
||||||
|
// WebCodecs is not exposed in insecure contexts
|
||||||
|
return `${className} is not available in this environment; this may be because this page is running in an`
|
||||||
|
+ ` insecure context. Try serving your page over HTTPS or use localhost.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${className} is not available in this environment.`;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* T or a promise that resolves to T.
|
* T or a promise that resolves to T.
|
||||||
* @group Miscellaneous
|
* @group Miscellaneous
|
||||||
|
|||||||
+3
-3
@@ -155,7 +155,7 @@ export class EncodedPacket {
|
|||||||
throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
|
throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
|
||||||
}
|
}
|
||||||
if (typeof EncodedVideoChunk === 'undefined') {
|
if (typeof EncodedVideoChunk === 'undefined') {
|
||||||
throw new Error('Your browser does not support EncodedVideoChunk.');
|
throw new Error('EncodedVideoChunk is not available in this environment.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EncodedVideoChunk({
|
return new EncodedVideoChunk({
|
||||||
@@ -179,7 +179,7 @@ export class EncodedPacket {
|
|||||||
throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
|
throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
|
||||||
}
|
}
|
||||||
if (typeof EncodedVideoChunk === 'undefined') {
|
if (typeof EncodedVideoChunk === 'undefined') {
|
||||||
throw new Error('Your browser does not support EncodedVideoChunk.');
|
throw new Error('EncodedVideoChunk is not available in this environment.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EncodedVideoChunk({
|
return new EncodedVideoChunk({
|
||||||
@@ -198,7 +198,7 @@ export class EncodedPacket {
|
|||||||
throw new TypeError('Metadata-only packets cannot be converted to an audio chunk.');
|
throw new TypeError('Metadata-only packets cannot be converted to an audio chunk.');
|
||||||
}
|
}
|
||||||
if (typeof EncodedAudioChunk === 'undefined') {
|
if (typeof EncodedAudioChunk === 'undefined') {
|
||||||
throw new Error('Your browser does not support EncodedAudioChunk.');
|
throw new Error('EncodedAudioChunk is not available in this environment.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EncodedAudioChunk({
|
return new EncodedAudioChunk({
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ const convertVideo = async (quality: Quality, codec: VideoCodec, allowMissingQua
|
|||||||
trim: { start: 0, end: 2 },
|
trim: { start: 0, end: 2 },
|
||||||
video: { codec, quality },
|
video: { codec, quality },
|
||||||
audio: { discard: true },
|
audio: { discard: true },
|
||||||
|
showWarnings: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (allowMissingQuantizerSupport && !conversion.isValid) {
|
if (allowMissingQuantizerSupport && !conversion.isValid) {
|
||||||
|
|||||||
@@ -140,3 +140,23 @@ test('QuickTime nclc color information', async () => {
|
|||||||
});
|
});
|
||||||
expect(await track.hasHighDynamicRange()).toBe(true);
|
expect(await track.hasHighDynamicRange()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Annex B isn't supposed to exist in MP4, but some files have it anyway, with an empty avcC box
|
||||||
|
test('Annex B', async () => {
|
||||||
|
const filePath = path.join(__dirname, '..', 'public/annex-b.mp4');
|
||||||
|
using input = new Input({
|
||||||
|
source: new FilePathSource(filePath),
|
||||||
|
formats: ALL_FORMATS,
|
||||||
|
});
|
||||||
|
|
||||||
|
const track = await input.getPrimaryVideoTrack();
|
||||||
|
if (!track) throw new Error('No video track found');
|
||||||
|
|
||||||
|
const decoderConfig = (await track.getDecoderConfig())!;
|
||||||
|
expect(decoderConfig.codec).toBe('avc1.424028');
|
||||||
|
expect(decoderConfig.description).toBeUndefined();
|
||||||
|
|
||||||
|
const sink = new EncodedPacketSink(track);
|
||||||
|
const firstPacket = (await sink.getFirstPacket())!;
|
||||||
|
expect([...firstPacket.data.slice(0, 4)]).toEqual([0, 0, 0, 1]);
|
||||||
|
});
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user