mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-09 08:43:49 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a4fec9f6e | ||
|
|
8c8ce8a4a5 | ||
|
|
7ea8f6d751 | ||
|
|
8fb22633fe | ||
|
|
0480ecbd3a | ||
|
|
9547d36353 | ||
|
|
d8d22aa4eb | ||
|
|
50b281a9f8 | ||
|
|
409961c02b | ||
|
|
d8a6e09a85 | ||
|
|
2c7e8d85ca | ||
|
|
a9441aa9a9 | ||
|
|
403093c514 | ||
|
|
54e74bfa4b | ||
|
|
df76bae503 | ||
|
|
b617c5f720 | ||
|
|
a5df6c7b89 | ||
|
|
210d382113 | ||
|
|
a294d943e6 | ||
|
|
9a8ccf6f6c | ||
|
|
f34e4cd369 | ||
|
|
93e6de980d | ||
|
|
e6fe540cbc | ||
|
|
23e6901046 | ||
|
|
143ecea6c0 | ||
|
|
067081d5eb | ||
|
|
f55a2b4764 | ||
|
|
1b1c9a0299 | ||
|
|
2b2e80dc24 | ||
|
|
13d1e280e8 | ||
|
|
62287156d6 | ||
|
|
100852f266 | ||
|
|
f8f08a48e1 | ||
|
|
71dd34fc3c | ||
|
|
487ae3c69a | ||
|
|
0d5bf18864 | ||
|
|
fc67e436e3 | ||
|
|
735a6622a2 | ||
|
|
d51903edfe | ||
|
|
6cdaa76fbb | ||
|
|
8efe7e75db | ||
|
|
a892676453 | ||
|
|
00f020921b | ||
|
|
8071933f15 | ||
|
|
d97611453b | ||
|
|
5e59ae4a1c | ||
|
|
3b148f961a | ||
|
|
95d60805ed | ||
|
|
857956fb07 | ||
|
|
e9fc97e070 | ||
|
|
15db8a27d4 | ||
|
|
637d77b2cf | ||
|
|
b6bb382783 | ||
|
|
7bb9961156 | ||
|
|
776ae43f50 | ||
|
|
e533bab18a | ||
|
|
26f3a576f3 | ||
|
|
1f6457a50c | ||
|
|
f6aee7b414 | ||
|
|
0cb4665d8e | ||
|
|
525a03d220 | ||
|
|
808422f4f5 | ||
|
|
e6110a5b9b | ||
|
|
cd2ded8767 | ||
|
|
db91d07780 | ||
|
|
af57c431d3 | ||
|
|
049f24f2cb | ||
|
|
aa509cd62e | ||
|
|
60789841a8 | ||
|
|
b6d3e3269d | ||
|
|
cea3a40902 | ||
|
|
201a1b4066 | ||
|
|
882051daf2 | ||
|
|
91f96458fa | ||
|
|
9d87a3e580 | ||
|
|
040b0747be | ||
|
|
53923e72dc | ||
|
|
46b3ce39fb | ||
|
|
14ae14b565 | ||
|
|
70e3e98b53 | ||
|
|
6b0527b691 | ||
|
|
3e333636ec | ||
|
|
a583b9d168 | ||
|
|
29aaaf64bc | ||
|
|
5c45fd1f63 | ||
|
|
7232296217 | ||
|
|
30fc407c4c | ||
|
|
52fd8d0e19 | ||
|
|
a3e43987ed | ||
|
|
823ede1668 | ||
|
|
1703e70a16 | ||
|
|
df0932d49e | ||
|
|
64468b0e5b | ||
|
|
903e36430f | ||
|
|
dbb4150718 | ||
|
|
9d1f4a5f80 | ||
|
|
76ac4e7aba | ||
|
|
f0be3ef134 | ||
|
|
77fa426a9a | ||
|
|
b4cbf4c502 | ||
|
|
27bdd33d42 | ||
|
|
5972a5c906 | ||
|
|
da539cf495 | ||
|
|
987ae467ce | ||
|
|
2b5971d1ee | ||
|
|
d735f16ca5 | ||
|
|
9926004401 | ||
|
|
34628390b7 | ||
|
|
1e46df030f | ||
|
|
a6fd297573 | ||
|
|
447dd51e7b | ||
|
|
aebfede89a | ||
|
|
e0a1211140 | ||
|
|
aa8003e679 | ||
|
|
c74b6a44fb | ||
|
|
f21182a7b9 | ||
|
|
fb2dcba707 | ||
|
|
e25525a564 | ||
|
|
f356c05a9c | ||
|
|
4e1428fcef | ||
|
|
ca48f31032 | ||
|
|
b958dd84cc | ||
|
|
f72db4dfa2 | ||
|
|
e9534f57c6 | ||
|
|
31fdd363e3 | ||
|
|
14a55fc476 | ||
|
|
0fc3bb2b1d | ||
|
|
4f670bbe06 | ||
|
|
02f379d9c1 | ||
|
|
588495268c | ||
|
|
230778d887 | ||
|
|
32267f348a | ||
|
|
2aa0fd1433 | ||
|
|
bdc59306ed | ||
|
|
03c1c46f9a | ||
|
|
b4f76fc082 | ||
|
|
d55431dda5 | ||
|
|
6679b6b15d | ||
|
|
ad4dc659a5 | ||
|
|
95fbec86e8 |
@@ -0,0 +1,28 @@
|
||||
name: Build check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-check:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
# Building the docs also means building the core library
|
||||
- name: Build everything
|
||||
run: npm run docs:build
|
||||
@@ -27,7 +27,4 @@ jobs:
|
||||
run: npm run check
|
||||
|
||||
- name: Run ESLint
|
||||
run: npm run lint
|
||||
|
||||
- name: Run build
|
||||
run: npm run build
|
||||
run: npm run lint
|
||||
@@ -25,15 +25,6 @@ jobs:
|
||||
with:
|
||||
script: "core.setFailed('Non-prerelease releases must target the main branch (got: ${{ github.event.release.target_commitish }}).')"
|
||||
|
||||
- name: Merge main into release branch
|
||||
if: ${{ !github.event.release.prerelease }}
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git checkout release
|
||||
git merge origin/main --no-ff -m "Merge main into release for tag ${{ github.event.release.tag_name }}"
|
||||
git push origin release
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -60,8 +51,9 @@ jobs:
|
||||
- name: Run tests
|
||||
run: xvfb-run npm test
|
||||
|
||||
- name: Run build
|
||||
run: npm run build
|
||||
# Building the docs also builds the core library
|
||||
- name: Build everything
|
||||
run: npm run docs:build
|
||||
|
||||
- name: Upload build artifacts
|
||||
env:
|
||||
@@ -106,3 +98,12 @@ jobs:
|
||||
|
||||
- name: Publish workspace packages to npm
|
||||
run: npm publish --access public --workspaces ${{ github.event.release.prerelease && '--tag beta' || '' }}
|
||||
|
||||
- name: Merge main into release branch
|
||||
if: ${{ !github.event.release.prerelease }}
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git checkout release
|
||||
git merge origin/main --no-ff -m "Merge main into release for tag ${{ github.event.release.tag_name }}"
|
||||
git push origin release
|
||||
|
||||
@@ -26,6 +26,25 @@ Alternatively, directly include them using a script tag:
|
||||
|
||||
This will expose the global objects `Mediabunny` and `MediabunnyProres`. Use `mediabunny-prores.d.ts` to provide types for these globals. You can download the built distribution files from the [releases page](https://github.com/Vanilagy/mediabunny/releases).
|
||||
|
||||
## Setup
|
||||
|
||||
`@mediabunny/prores` can make use of shared-memory multithreading to achieve maximum performance. To enable this in browsers, your website must be cross-origin isolated by setting the following response headers:
|
||||
```
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
```
|
||||
|
||||
Alternatively, you can use:
|
||||
```
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: credentialless
|
||||
```
|
||||
which is generally more permissive but is not supported in Safari (of course).
|
||||
|
||||
---
|
||||
|
||||
If you cannot enable cross-origin isolation, `@mediabunny/prores` will fall back to a slower multithreading algorithm.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
|
||||
Generated
+12
-12
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "mediabunny",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mediabunny",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"license": "MPL-2.0",
|
||||
"workspaces": [
|
||||
".",
|
||||
@@ -10963,9 +10963,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/turbores": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/turbores/-/turbores-1.1.1.tgz",
|
||||
"integrity": "sha512-uC2bBqMgMzeE/K4/zeUJd3IwvDm9+0JtNXkiBuc7Sg1L8OaeAhk+VCgoiqDgDdwVaqF3/lztEjrSgt8k15XyYw==",
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/turbores/-/turbores-1.1.4.tgz",
|
||||
"integrity": "sha512-ZlWVTK+5m0KV0dytbOYozfJlNs5v7W7wWSBRVhbkY9mUjVA9bLHDvPH67bFBjUVTRDlU42dhClI6SZu8YTVs/A==",
|
||||
"license": "MPL-2.0",
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
@@ -12894,7 +12894,7 @@
|
||||
},
|
||||
"packages/aac-encoder": {
|
||||
"name": "@mediabunny/aac-encoder",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "^1.40.1"
|
||||
@@ -12909,7 +12909,7 @@
|
||||
},
|
||||
"packages/ac3": {
|
||||
"name": "@mediabunny/ac3",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "^1.40.1"
|
||||
@@ -12924,7 +12924,7 @@
|
||||
},
|
||||
"packages/flac-encoder": {
|
||||
"name": "@mediabunny/flac-encoder",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "^1.40.1"
|
||||
@@ -12939,7 +12939,7 @@
|
||||
},
|
||||
"packages/mp3-encoder": {
|
||||
"name": "@mediabunny/mp3-encoder",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "^1.40.1"
|
||||
@@ -12954,10 +12954,10 @@
|
||||
},
|
||||
"packages/prores": {
|
||||
"name": "@mediabunny/prores",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"turbores": "^1.1.1"
|
||||
"turbores": "^1.1.4"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
@@ -12969,7 +12969,7 @@
|
||||
},
|
||||
"packages/server": {
|
||||
"name": "@mediabunny/server",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@mediabunny/prores": "^1.50.0",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "mediabunny",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.",
|
||||
"type": "module",
|
||||
"workspaces": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@mediabunny/aac-encoder",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"description": "AAC encoder extension for Mediabunny, based on FFmpeg.",
|
||||
"main": "./dist/bundles/mediabunny-aac-encoder.mjs",
|
||||
"module": "./dist/bundles/mediabunny-aac-encoder.mjs",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@mediabunny/ac3",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"description": "AC-3 and E-AC-3 (Dolby Digital) decoder and encoder extension for Mediabunny, based on FFmpeg.",
|
||||
"main": "./dist/bundles/mediabunny-ac3.mjs",
|
||||
"module": "./dist/bundles/mediabunny-ac3.mjs",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@mediabunny/flac-encoder",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"description": "FLAC encoder extension for Mediabunny, based on libFLAC.",
|
||||
"main": "./dist/bundles/mediabunny-flac-encoder.mjs",
|
||||
"module": "./dist/bundles/mediabunny-flac-encoder.mjs",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@mediabunny/mp3-encoder",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"description": "MP3 encoder extension for Mediabunny, based on LAME.",
|
||||
"main": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
||||
"module": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
||||
|
||||
@@ -28,6 +28,25 @@ Alternatively, directly include them using a script tag:
|
||||
|
||||
This will expose the global objects `Mediabunny` and `MediabunnyProres`. Use `mediabunny-prores.d.ts` to provide types for these globals. You can download the built distribution files from the [releases page](https://github.com/Vanilagy/mediabunny/releases).
|
||||
|
||||
## Setup
|
||||
|
||||
`@mediabunny/prores` can make use of shared-memory multithreading to achieve maximum performance. To enable this in browsers, your website must be cross-origin isolated by setting the following response headers:
|
||||
```
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
```
|
||||
|
||||
Alternatively, you can use:
|
||||
```
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: credentialless
|
||||
```
|
||||
which is generally more permissive but is not supported in Safari (of course).
|
||||
|
||||
---
|
||||
|
||||
If you cannot enable cross-origin isolation, `@mediabunny/prores` will fall back to a slower multithreading algorithm.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@mediabunny/prores",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"description": "Apple ProRes decoder extension for Mediabunny, based on TurboRes.",
|
||||
"main": "./dist/bundles/mediabunny-prores.mjs",
|
||||
"module": "./dist/bundles/mediabunny-prores.mjs",
|
||||
@@ -19,10 +19,6 @@
|
||||
"src"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"browser": {
|
||||
"node:worker_threads": false,
|
||||
"node:os": false
|
||||
},
|
||||
"license": "MPL-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -38,7 +34,7 @@
|
||||
"url": "https://github.com/sponsors/Vanilagy"
|
||||
},
|
||||
"dependencies": {
|
||||
"turbores": "^1.1.1"
|
||||
"turbores": "^1.1.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mediabunny": "^1.49.0"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@mediabunny/server",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.50.0",
|
||||
"version": "1.50.3",
|
||||
"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",
|
||||
"module": "./dist/bundles/mediabunny-server.mjs",
|
||||
|
||||
@@ -134,8 +134,18 @@ const generateDocs = (entryFiles: string[], apiConfigFile: string, dry = false)
|
||||
if (aliasedDeclaration) {
|
||||
const sourceFile = aliasedDeclaration.getSourceFile();
|
||||
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
||||
if (moduleSymbol) {
|
||||
// If the aliased declaration lives in a module we've already visited (e.g. a
|
||||
// same-file `export type { Foo }` re-export of a local declaration), recursing
|
||||
// won't reach it, so add the alias symbol directly. Otherwise follow the reexport.
|
||||
if (moduleSymbol && !visited.has(moduleSymbol)) {
|
||||
symbols.push(...getAllExportedSymbols(moduleSymbol, visited));
|
||||
} else {
|
||||
// Push the aliased symbol (not the alias) so downstream sees the real
|
||||
// declaration and its JSDoc rather than the empty ExportSpecifier.
|
||||
const hasPublicTag = ts.getJSDocTags(aliasedDeclaration).some(tag => tag.tagName.text === 'public');
|
||||
if (hasPublicTag) {
|
||||
symbols.push(aliasedSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -1329,9 +1329,13 @@ export class Conversion {
|
||||
firstSample.close();
|
||||
await tempOutput.finalize();
|
||||
} catch (error) {
|
||||
Logging._info('Error when probing encoder support. Falling back to rerender path.', error);
|
||||
needsRerender = true;
|
||||
Logging._warn(
|
||||
'An error occurred when probing encoder support. Falling back to rerender path.', error,
|
||||
);
|
||||
void tempOutput.cancel();
|
||||
|
||||
needsRerender = true;
|
||||
encodingConfig.transform.force = true;
|
||||
}
|
||||
} else {
|
||||
await tempOutput.cancel();
|
||||
|
||||
@@ -46,6 +46,7 @@ import {
|
||||
Rotation,
|
||||
roundIfAlmostInteger,
|
||||
textDecoder,
|
||||
toDataView,
|
||||
TRANSFER_CHARACTERISTICS_MAP_INVERSE,
|
||||
UNDETERMINED_LANGUAGE,
|
||||
} from '../misc';
|
||||
@@ -141,6 +142,7 @@ type ClusterBlock = {
|
||||
data: Uint8Array;
|
||||
lacing: BlockLacing;
|
||||
decoded: boolean;
|
||||
postProcessed: boolean; // For codec-specific processing
|
||||
mainAdditional: Uint8Array | null;
|
||||
};
|
||||
|
||||
@@ -864,6 +866,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
data: frameData,
|
||||
lacing: BlockLacing.None,
|
||||
decoded: true,
|
||||
postProcessed: false,
|
||||
mainAdditional: originalBlock.mainAdditional,
|
||||
});
|
||||
}
|
||||
@@ -1502,6 +1505,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
data: blockData,
|
||||
lacing,
|
||||
decoded: !hasDecodingInstructions,
|
||||
postProcessed: false,
|
||||
mainAdditional: null,
|
||||
});
|
||||
}; break;
|
||||
@@ -1538,6 +1542,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
data: blockData,
|
||||
lacing,
|
||||
decoded: !hasDecodingInstructions,
|
||||
postProcessed: false,
|
||||
mainAdditional: null,
|
||||
};
|
||||
trackData.blocks.push(this.currentBlock);
|
||||
@@ -2194,6 +2199,35 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
||||
block.decoded = true;
|
||||
}
|
||||
|
||||
if (!block.postProcessed) {
|
||||
if (this.internalTrack.info?.codec === 'prores') {
|
||||
// For some reason, ProRes packets are stored in Matroska without the frame container atom. FFmpeg cites
|
||||
// the "Matroska spec" but the actual spec says nothing about this.
|
||||
|
||||
const hasFrameContainer = block.data.length >= 8
|
||||
&& block.data[4] === 105 // 'i'
|
||||
&& block.data[5] === 99 // 'c'
|
||||
&& block.data[6] === 112 // 'p'
|
||||
&& block.data[7] === 102; // 'f'
|
||||
|
||||
if (!hasFrameContainer) {
|
||||
// Wrap the frame in a frame container
|
||||
const newData = new Uint8Array(block.data.length + 8);
|
||||
const newDataView = toDataView(newData);
|
||||
|
||||
newDataView.setUint32(0, newData.length, false);
|
||||
newData[4] = 105; // 'i'
|
||||
newData[5] = 99; // 'c'
|
||||
newData[6] = 112; // 'p'
|
||||
newData[7] = 102; // 'f'
|
||||
newData.set(block.data, 8);
|
||||
block.data = newData;
|
||||
}
|
||||
}
|
||||
|
||||
block.postProcessed = true;
|
||||
}
|
||||
|
||||
const data = options.metadataOnly ? PLACEHOLDER_DATA : block.data;
|
||||
const timestamp = block.timestamp / this.internalTrack.segment.timestampFactor;
|
||||
const duration = block.duration / this.internalTrack.segment.timestampFactor;
|
||||
|
||||
@@ -897,6 +897,17 @@ export class MatroskaMuxer extends Muxer {
|
||||
try {
|
||||
const trackData = this.getVideoTrackData(track, packet, meta);
|
||||
|
||||
let packetData = packet.data;
|
||||
if (track.source._codec === 'prores') {
|
||||
if (packetData.byteLength < 8) {
|
||||
throw new Error('ProRes packet too small, expected at least 8 bytes.');
|
||||
}
|
||||
|
||||
// Trim off the frame container atom header. FFmpeg does this too and cites the "Matroska spec" as the
|
||||
// reason, despite the spec not saying anything about this.
|
||||
packetData = packetData.subarray(8);
|
||||
}
|
||||
|
||||
const isKeyFrame = packet.type === 'key';
|
||||
this.validateTimestamp(trackData.track, packet.timestamp, isKeyFrame);
|
||||
|
||||
@@ -913,7 +924,7 @@ export class MatroskaMuxer extends Muxer {
|
||||
? packet.sideData.alpha ?? null
|
||||
: null;
|
||||
|
||||
const videoChunk = this.createInternalChunk(packet.data, timestamp, duration, packet.type, additions);
|
||||
const videoChunk = this.createInternalChunk(packetData, timestamp, duration, packet.type, additions);
|
||||
if (track.source._codec === 'vp9') this.fixVP9ColorSpace(trackData, videoChunk);
|
||||
|
||||
trackData.chunkQueue.push(videoChunk);
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
setUint24,
|
||||
toUint8Array,
|
||||
UnthrottledTimerHandle,
|
||||
wait,
|
||||
} from './misc';
|
||||
import { Muxer } from './muxer';
|
||||
import { SubtitleParser } from './subtitles';
|
||||
@@ -878,6 +879,9 @@ class VideoEncoderWrapper {
|
||||
// These are wired in series, therefore they must also be flushed in series
|
||||
await this.encoder.flush();
|
||||
await this.alphaEncoder?.flush();
|
||||
|
||||
// Workaround for https://issues.chromium.org/issues/529852980 to give it time for errors to surface
|
||||
await wait(25);
|
||||
}
|
||||
|
||||
if (this.encoder.state !== 'closed') {
|
||||
|
||||
@@ -354,7 +354,7 @@ test('MPEG-TS seeking race condition test', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('MPEG-TS video key packets', { timeout: 10_000 }, async () => {
|
||||
test('MPEG-TS video key packets', { timeout: 30_000 }, async () => {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
using input = new Input({
|
||||
source: new FilePathSource(path.join(__dirname, '../public/trim-buck-bunny-ffmpeg.ts')),
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Output } from '../../src/output.js';
|
||||
import { MkvOutputFormat, MovOutputFormat } from '../../src/output-format.js';
|
||||
import { BufferTarget } from '../../src/target.js';
|
||||
import { Conversion } from '../../src/conversion.js';
|
||||
import { VideoSampleSink } from '../../src/media-sink.js';
|
||||
import { EncodedPacketSink, VideoSampleSink } from '../../src/media-sink.js';
|
||||
import { assert } from '../../src/misc.js';
|
||||
|
||||
const SAMPLE_URL = 'https://pub-1ee78aacb848486482b20a72b55b3121.r2.dev/turbores-sample.mov';
|
||||
@@ -88,6 +88,10 @@ test.concurrent('ProRes transmuxing into MKV', { timeout: 10_000 }, async () =>
|
||||
});
|
||||
await conversion.execute();
|
||||
|
||||
// No 'icpf' means the frame container atom headers were successfully stripped from the ProRes packets
|
||||
let str = new TextDecoder('ascii').decode(output.target.buffer!);
|
||||
expect(str.includes('icpf')).toBe(false);
|
||||
|
||||
using newInput = new Input({
|
||||
source: new BufferSource(output.target.buffer!),
|
||||
formats: ALL_FORMATS,
|
||||
@@ -100,6 +104,14 @@ test.concurrent('ProRes transmuxing into MKV', { timeout: 10_000 }, async () =>
|
||||
const decoderConfig = (await videoTrack.getDecoderConfig())!;
|
||||
expect(decoderConfig.codec).toBe('apch');
|
||||
expect(decoderConfig.description).toBeUndefined();
|
||||
|
||||
const sink = new EncodedPacketSink(videoTrack);
|
||||
const firstPacket = await sink.getFirstPacket();
|
||||
assert(firstPacket);
|
||||
|
||||
// The frame container atom headers are added back when reading out the packets
|
||||
str = new TextDecoder('ascii').decode(firstPacket.data);
|
||||
expect(str.includes('icpf')).toBe(true);
|
||||
});
|
||||
|
||||
test('Custom coder registration', { timeout: 10_000 }, async () => {
|
||||
|
||||
@@ -801,7 +801,7 @@ describe('Video', async () => {
|
||||
await conversionRoundtrip('av1');
|
||||
});
|
||||
|
||||
test('ProRes conversion roundtrip', { timeout: 20_000 }, async () => {
|
||||
test('ProRes conversion roundtrip', { timeout: 30_000 }, async () => {
|
||||
await conversionRoundtrip('prores');
|
||||
});
|
||||
|
||||
@@ -1061,7 +1061,7 @@ describe('Video', async () => {
|
||||
});
|
||||
|
||||
// https://github.com/Vanilagy/mediabunny/issues/392
|
||||
test('Memory doesn\'t leak', async () => {
|
||||
test('Memory doesn\'t leak', { timeout: 10_000 }, async () => {
|
||||
const encoder = new NodeAvVideoEncoder();
|
||||
// @ts-expect-error Readonly
|
||||
encoder.codec = 'avc';
|
||||
|
||||
Reference in New Issue
Block a user