mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-30 20:33:55 +02:00
Merge main into release for tag v1.29.1
This commit is contained in:
Generated
+6
-6
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "mediabunny",
|
||||
"version": "1.29.0",
|
||||
"version": "1.29.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mediabunny",
|
||||
"version": "1.29.0",
|
||||
"version": "1.29.1",
|
||||
"license": "MPL-2.0",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
@@ -7739,9 +7739,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mediabunny": {
|
||||
"version": "1.28.0",
|
||||
"resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.28.0.tgz",
|
||||
"integrity": "sha512-D63nzvBRIBSUsRgaIfFugWCy2iOV5T/C6nHn2fW0aWqyRuSGzWsVMXzlNi3iCKieoA/WECYJg8oVGtUukpy3XQ==",
|
||||
"version": "1.29.0",
|
||||
"resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.29.0.tgz",
|
||||
"integrity": "sha512-18B8w/rhO/ph/AFsIXvzZg8RaSQZ+ZYfJ99MZlTjDmlgCT58jV3azrnWQ/OSquYDi8q0xmn64mnfTEHgww3+zw==",
|
||||
"license": "MPL-2.0",
|
||||
"peer": true,
|
||||
"workspaces": [
|
||||
@@ -12065,7 +12065,7 @@
|
||||
},
|
||||
"packages/mp3-encoder": {
|
||||
"name": "@mediabunny/mp3-encoder",
|
||||
"version": "1.29.0",
|
||||
"version": "1.29.1",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "^1.40.1"
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "mediabunny",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.29.0",
|
||||
"version": "1.29.1",
|
||||
"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/mp3-encoder",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.29.0",
|
||||
"version": "1.29.1",
|
||||
"description": "MP3 encoder extension for Mediabunny, based on LAME.",
|
||||
"main": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
||||
"module": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
||||
|
||||
@@ -46,6 +46,7 @@ import { DEFAULT_TRACK_DISPOSITION, MetadataTags } from '../metadata';
|
||||
import {
|
||||
assert,
|
||||
AsyncMutex,
|
||||
binarySearchExact,
|
||||
binarySearchLessOrEqual,
|
||||
Bitstream,
|
||||
COLOR_PRIMARIES_MAP_INVERSE,
|
||||
@@ -118,6 +119,7 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
tracks: InputTrack[] = [];
|
||||
packetOffset = 0;
|
||||
packetStride = -1;
|
||||
sectionEndPositions: number[] = [];
|
||||
|
||||
constructor(input: Input) {
|
||||
super(input);
|
||||
@@ -157,7 +159,11 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
let hasProgramMap = false;
|
||||
|
||||
while (true) {
|
||||
const section = await this.readSection(currentPos, true);
|
||||
const section = await this.readSection(
|
||||
currentPos,
|
||||
true,
|
||||
!hasProgramMap, // Expect contiguous sections as long as we don't have the PMT
|
||||
);
|
||||
if (!section) {
|
||||
break;
|
||||
}
|
||||
@@ -447,13 +453,13 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
return buildMpegTsMimeType(codecStrings);
|
||||
}
|
||||
|
||||
async readSection(startPos: number, full: boolean): Promise<Section | null> {
|
||||
async readSection(startPos: number, full: boolean, contiguous = false): Promise<Section | null> {
|
||||
let endPos = startPos;
|
||||
let currentPos = startPos;
|
||||
const chunks: Uint8Array[] = [];
|
||||
let chunksByteLength = 0;
|
||||
|
||||
let firstPacket: TsPacket | null = null;
|
||||
let mustAddSectionEnd = true;
|
||||
|
||||
while (true) {
|
||||
const packet = await this.readPacket(currentPos);
|
||||
@@ -471,7 +477,11 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
firstPacket = packet;
|
||||
} else {
|
||||
if (packet.pid !== firstPacket.pid) {
|
||||
continue; // Ignore this packet
|
||||
if (contiguous) {
|
||||
break; // End of section
|
||||
} else {
|
||||
continue; // Ignore this packet
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.payloadUnitStartIndicator === 1) {
|
||||
@@ -501,8 +511,21 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
|
||||
// 64 is just "a bit of data", enough for the PES packet header
|
||||
if (!full && chunksByteLength >= 64) {
|
||||
mustAddSectionEnd = false; // Not the actual section end
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if we already know this is a section end
|
||||
const isKnownSectionEnd = binarySearchExact(this.sectionEndPositions, endPos, x => x) !== -1;
|
||||
if (isKnownSectionEnd) {
|
||||
mustAddSectionEnd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mustAddSectionEnd) {
|
||||
const index = binarySearchLessOrEqual(this.sectionEndPositions, endPos, x => x);
|
||||
this.sectionEndPositions.splice(index + 1, 0, endPos);
|
||||
}
|
||||
|
||||
if (!firstPacket) {
|
||||
@@ -1303,6 +1326,10 @@ class MpegTsVideoTrackBacking extends MpegTsTrackBacking implements InputVideoTr
|
||||
const codec = this.elementaryStream.info.codec;
|
||||
const CHUNK_SIZE = 1024;
|
||||
|
||||
if (codec !== 'avc' && codec !== 'hevc') {
|
||||
throw new Error('Unhandled.');
|
||||
}
|
||||
|
||||
let packetStartPos: number | null = null;
|
||||
|
||||
while (true) {
|
||||
@@ -1522,7 +1549,7 @@ class MpegTsAudioTrackBacking extends MpegTsTrackBacking implements InputAudioTr
|
||||
context.seekTo(possibleHeaderStartPos + 1);
|
||||
}
|
||||
} else {
|
||||
throw new Error('Unreachable');
|
||||
throw new Error('Unhandled.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ test('ADTS muxer with raw AAC input', async () => {
|
||||
expect(count).toBe(237);
|
||||
});
|
||||
|
||||
test('ADTS muxer with ADTS input (passthrough)', async () => {
|
||||
test('ADTS muxer with ADTS input (passthrough)', { timeout: 10_000 }, async () => {
|
||||
using input = new Input({
|
||||
source: new FilePathSource(path.join(__dirname, '../public/sample3.aac')),
|
||||
formats: ALL_FORMATS,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { expect, test } from 'vitest';
|
||||
import { Input } from '../../src/input.js';
|
||||
import { FilePathSource, ReadableStreamSource, UrlSource } from '../../src/source.js';
|
||||
import { FilePathSource, ReadableStreamSource, StreamSource, UrlSource } from '../../src/source.js';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { Readable } from 'node:stream';
|
||||
@@ -241,11 +241,11 @@ test('MPEG-TS video seeking', async () => {
|
||||
expect(allPackets).toHaveLength(298);
|
||||
|
||||
for (const packet of allPackets) {
|
||||
const seekedPacked = await sink.getPacket(packet.timestamp);
|
||||
assert(seekedPacked);
|
||||
expect(seekedPacked.timestamp).toBe(packet.timestamp); // The correct timestamp was retrieved for this packet
|
||||
expect(seekedPacked.duration).toBe(packet.duration); // The correct duration was retrieved for this packet
|
||||
expect(seekedPacked.sequenceNumber).toBe(packet.sequenceNumber);
|
||||
const seekedPacket = await sink.getPacket(packet.timestamp);
|
||||
assert(seekedPacket);
|
||||
expect(seekedPacket.timestamp).toBe(packet.timestamp); // The correct timestamp was retrieved for this packet
|
||||
expect(seekedPacket.duration).toBe(packet.duration); // The correct duration was retrieved for this packet
|
||||
expect(seekedPacket.sequenceNumber).toBe(packet.sequenceNumber);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -573,3 +573,27 @@ test('MPEG-TS with MP3 audio', async () => {
|
||||
|
||||
expect(count).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('MPEG-TS partial reading', async () => {
|
||||
const fullPath = path.join(__dirname, '../public/193039199_mp4_h264_aac_fhd_7.ts');
|
||||
const buffer = await fs.promises.readFile(fullPath);
|
||||
let maxEnd = 0;
|
||||
|
||||
using input = new Input({
|
||||
source: new StreamSource({
|
||||
getSize: () => {
|
||||
return buffer.byteLength;
|
||||
},
|
||||
read: (start, end) => {
|
||||
maxEnd = Math.max(maxEnd, end);
|
||||
return buffer.subarray(start, end);
|
||||
},
|
||||
}),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
|
||||
await input.getTracks();
|
||||
|
||||
// Not much of the file has been read since we only requested metadata
|
||||
expect(maxEnd).toBeLessThanOrEqual(86480);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user