Compare commits

...
6 Commits
Author SHA1 Message Date
Vanilagy 149a2b4571 Bump patch 2026-05-19 22:34:52 +02:00
Vanilagy 0c455236da Add first encoded packet key frame check (fixes #365) 2026-05-19 16:15:17 +02:00
Vanilagy 41fb9657cb Add sponsor 2026-05-19 15:20:03 +02:00
Vanilagy d77ddf033b Bump patch 2026-05-14 14:39:16 +02:00
David P.andGitHub b9f48ca9ef Merge pull request #381 from Sturlen/fix/id3-metadata-parser-offset
Fix ID3v2 metadata parser
2026-05-14 14:03:44 +02:00
Sturlen aa38385cae fix(id3v2reader): use correct header size in readU24 2026-05-14 13:54:51 +02:00
10 changed files with 38 additions and 20 deletions
+1
View File
@@ -148,6 +148,7 @@ const sponsors = {
{ image: 'https://avatars.githubusercontent.com/u/13042781', name: 'Anshul Bansal', url: 'https://github.com/akbansa' }, { image: 'https://avatars.githubusercontent.com/u/13042781', name: 'Anshul Bansal', url: 'https://github.com/akbansa' },
{ image: 'https://avatars.githubusercontent.com/u/43105172', name: 'zhmou', url: 'https://github.com/zhmou' }, { image: 'https://avatars.githubusercontent.com/u/43105172', name: 'zhmou', url: 'https://github.com/zhmou' },
{ image: 'https://avatars.githubusercontent.com/u/695166', name: 'Takenori Nakagawa', url: 'https://github.com/ww24' }, { image: 'https://avatars.githubusercontent.com/u/695166', name: 'Takenori Nakagawa', url: 'https://github.com/ww24' },
{ image: 'https://avatars.githubusercontent.com/u/43607012', name: 'Sturlen', url: 'https://github.com/Sturlen' },
], ],
}; };
</script> </script>
+7 -7
View File
@@ -1,12 +1,12 @@
{ {
"name": "mediabunny", "name": "mediabunny",
"version": "1.45.1", "version": "1.45.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "mediabunny", "name": "mediabunny",
"version": "1.45.1", "version": "1.45.3",
"license": "MPL-2.0", "license": "MPL-2.0",
"workspaces": [ "workspaces": [
".", ".",
@@ -12806,7 +12806,7 @@
}, },
"packages/aac-encoder": { "packages/aac-encoder": {
"name": "@mediabunny/aac-encoder", "name": "@mediabunny/aac-encoder",
"version": "1.45.1", "version": "1.45.3",
"license": "MPL-2.0", "license": "MPL-2.0",
"devDependencies": { "devDependencies": {
"@types/emscripten": "^1.40.1" "@types/emscripten": "^1.40.1"
@@ -12821,7 +12821,7 @@
}, },
"packages/ac3": { "packages/ac3": {
"name": "@mediabunny/ac3", "name": "@mediabunny/ac3",
"version": "1.45.1", "version": "1.45.3",
"license": "MPL-2.0", "license": "MPL-2.0",
"devDependencies": { "devDependencies": {
"@types/emscripten": "^1.40.1" "@types/emscripten": "^1.40.1"
@@ -12836,7 +12836,7 @@
}, },
"packages/flac-encoder": { "packages/flac-encoder": {
"name": "@mediabunny/flac-encoder", "name": "@mediabunny/flac-encoder",
"version": "1.45.1", "version": "1.45.3",
"license": "MPL-2.0", "license": "MPL-2.0",
"devDependencies": { "devDependencies": {
"@types/emscripten": "^1.40.1" "@types/emscripten": "^1.40.1"
@@ -12851,7 +12851,7 @@
}, },
"packages/mp3-encoder": { "packages/mp3-encoder": {
"name": "@mediabunny/mp3-encoder", "name": "@mediabunny/mp3-encoder",
"version": "1.45.1", "version": "1.45.3",
"license": "MPL-2.0", "license": "MPL-2.0",
"devDependencies": { "devDependencies": {
"@types/emscripten": "^1.40.1" "@types/emscripten": "^1.40.1"
@@ -12866,7 +12866,7 @@
}, },
"packages/server": { "packages/server": {
"name": "@mediabunny/server", "name": "@mediabunny/server",
"version": "1.45.1", "version": "1.45.3",
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"node-av": "^5.2.4" "node-av": "^5.2.4"
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "mediabunny", "name": "mediabunny",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.45.1", "version": "1.45.3",
"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 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@mediabunny/aac-encoder", "name": "@mediabunny/aac-encoder",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.45.1", "version": "1.45.3",
"description": "AAC encoder extension for Mediabunny, based on FFmpeg.", "description": "AAC encoder extension for Mediabunny, based on FFmpeg.",
"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 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@mediabunny/ac3", "name": "@mediabunny/ac3",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.45.1", "version": "1.45.3",
"description": "AC-3 and E-AC-3 (Dolby Digital) decoder and encoder extension for Mediabunny, based on FFmpeg.", "description": "AC-3 and E-AC-3 (Dolby Digital) decoder and encoder extension for Mediabunny, based on FFmpeg.",
"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 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@mediabunny/flac-encoder", "name": "@mediabunny/flac-encoder",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.45.1", "version": "1.45.3",
"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 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@mediabunny/mp3-encoder", "name": "@mediabunny/mp3-encoder",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.45.1", "version": "1.45.3",
"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 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@mediabunny/server", "name": "@mediabunny/server",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.45.1", "version": "1.45.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.", "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",
+1 -1
View File
@@ -488,7 +488,7 @@ export class Id3V2Reader {
readU24() { readU24() {
const high = this.view.getUint16(this.pos, false); const high = this.view.getUint16(this.pos, false);
const low = this.view.getUint8(this.pos + 1); const low = this.view.getUint8(this.pos + 2);
this.pos += 3; this.pos += 3;
return high * 0x100 + low; return high * 0x100 + low;
} }
+23 -6
View File
@@ -46,7 +46,7 @@ import {
customVideoEncoders, customVideoEncoders,
customAudioEncoders, customAudioEncoders,
} from './custom-coder'; } from './custom-coder';
import { EncodedPacket, EncodedPacketSideData } from './packet'; import { EncodedPacket, EncodedPacketSideData, PacketType } from './packet';
import { import {
AudioSample, AudioSample,
audioSampleToInterleavedFormat, audioSampleToInterleavedFormat,
@@ -63,6 +63,7 @@ import {
VideoEncodingConfig, VideoEncodingConfig,
} from './encode'; } from './encode';
import { AudioResampler } from './resample'; import { AudioResampler } from './resample';
import { determineVideoPacketType } from './codec-data';
/** /**
* Base class for media sources. Media sources are used to add media samples to an output file. * Base class for media sources. Media sources are used to add media samples to an output file.
@@ -224,6 +225,7 @@ class VideoEncoderWrapper {
private encoder: VideoEncoder | null = null; private encoder: VideoEncoder | null = null;
private muxer: Muxer | null = null; private muxer: Muxer | null = null;
private lastMultipleOfKeyFrameInterval = -1; private lastMultipleOfKeyFrameInterval = -1;
private emittedEncoderPackets = 0;
// Tracks the input dimensions of the first frame // Tracks the input dimensions of the first frame
private codedWidth: number | null = null; private codedWidth: number | null = null;
@@ -694,6 +696,7 @@ class VideoEncoderWrapper {
let packet = EncodedPacket.fromEncodedChunk(colorChunk, sideData); let packet = EncodedPacket.fromEncodedChunk(colorChunk, sideData);
// See if there's a relevant timing entry to refine the packet's timing data
const preciseTimingIndex = binarySearchLessOrEqual( const preciseTimingIndex = binarySearchLessOrEqual(
this.preciseTimings, this.preciseTimings,
colorChunk.timestamp, colorChunk.timestamp,
@@ -703,12 +706,24 @@ class VideoEncoderWrapper {
? this.preciseTimings[preciseTimingIndex] ? this.preciseTimings[preciseTimingIndex]
: null; : null;
// If there's a relevant timing entry, refine the packet's timing data to get better accuracy than let actualType: PacketType | null = null;
// microseconds if (this.emittedEncoderPackets === 0 && packet.type === 'delta' && meta?.decoderConfig) {
if (entry && entry.microsecondTimestamp === colorChunk.timestamp) { // https://github.com/Vanilagy/mediabunny/issues/365
// We expect the first packet to be a key packet. If it's not, let's actually verify that it's
// not by getting the actual type.
actualType = determineVideoPacketType(
this.encodingConfig.codec,
meta.decoderConfig,
packet.data,
);
}
// Define the packet
if ((entry && entry.microsecondTimestamp === colorChunk.timestamp) || actualType !== null) {
packet = packet.clone({ packet = packet.clone({
timestamp: entry.timestampIsValid ? entry.timestamp : undefined, timestamp: entry?.timestampIsValid ? entry.timestamp : undefined,
duration: entry.durationIsValid ? entry.duration : undefined, duration: entry?.durationIsValid ? entry.duration : undefined,
type: actualType ?? undefined,
}); });
} }
@@ -720,6 +735,8 @@ class VideoEncoderWrapper {
.catch((error) => { .catch((error) => {
this.error ??= error; this.error ??= error;
}); });
this.emittedEncoderPackets++;
}; };
const stack = new Error('Encoding error').stack; const stack = new Error('Encoding error').stack;