Skip to content

Commit

Permalink
strf
Browse files Browse the repository at this point in the history
  • Loading branch information
JonnyBurger committed Nov 24, 2024
1 parent ee23c05 commit ecb1e3e
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 7 deletions.
5 changes: 5 additions & 0 deletions packages/media-parser/src/boxes/riff/parse-riff-box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {parseFmtBox} from './parse-fmt-box';
import {parseListBox} from './parse-list-box';
import {parseStrh} from './parse-strh';
import type {RiffBox, RiffRegularBox} from './riff-box';
import {parseStrf} from './strf';

export const parseRiffBox = ({
iterator,
Expand Down Expand Up @@ -32,6 +33,10 @@ export const parseRiffBox = ({
return parseStrh({iterator, size});
}

if (id === 'strf') {
return parseStrf({iterator, size, boxes});
}

iterator.discard(size);

const box: RiffRegularBox = {
Expand Down
30 changes: 29 additions & 1 deletion packages/media-parser/src/boxes/riff/riff-box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,32 @@ export type StrhBox = {
language: number;
};

export type StrfBoxVideo = {
type: 'strf-box-video';
biSize: number;
width: number;
height: number;
planes: number;
bitCount: number;
compression: string;
sizeImage: number;
xPelsPerMeter: number;
yPelsPerMeter: number;
clrUsed: number;
clrImportant: number;
};

export type StrfBoxAudio = {
type: 'strf-box-audio';
formatTag: number;
numberOfChannels: number;
sampleRate: number;
avgBytesPerSecond: number;
blockAlign: number;
bitsPerSample: number;
cbSize: number;
};

export type RiffHeader = {
type: 'riff-header';
fileSize: number;
Expand All @@ -63,4 +89,6 @@ export type RiffBox =
| RiffHeader
| ListBox
| AvihBox
| StrhBox;
| StrhBox
| StrfBoxVideo
| StrfBoxAudio;
95 changes: 95 additions & 0 deletions packages/media-parser/src/boxes/riff/strf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type {BufferIterator} from '../../buffer-iterator';
import type {RiffBox} from './riff-box';

const parseStrfAudio = ({
iterator,
size,
}: {
iterator: BufferIterator;
size: number;
}): RiffBox => {
const box = iterator.startBox(size);
const formatTag = iterator.getUint16Le();
const numberOfChannels = iterator.getUint16Le();
const samplesPerSec = iterator.getUint32Le();
const avgBytesPerSec = iterator.getUint32Le();
const blockAlign = iterator.getUint16Le();
const bitsPerSample = iterator.getUint16Le();
const cbSize = iterator.getUint16Le();

box.expectNoMoreBytes();

return {
type: 'strf-box-audio',
avgBytesPerSecond: avgBytesPerSec,
bitsPerSample,
blockAlign,
cbSize,
formatTag,
numberOfChannels,
sampleRate: samplesPerSec,
};
};

const parseStrfVideo = ({
iterator,
size,
}: {
iterator: BufferIterator;
size: number;
}): RiffBox => {
const box = iterator.startBox(size);
const biSize = iterator.getUint32Le();
const width = iterator.getInt32Le();
const height = iterator.getInt32Le();
const planes = iterator.getUint16Le();
const bitCount = iterator.getUint16Le();
const compression = iterator.getByteString(4);
const sizeImage = iterator.getUint32Le();
const xPelsPerMeter = iterator.getInt32Le();
const yPelsPerMeter = iterator.getInt32Le();
const clrUsed = iterator.getUint32Le();
const clrImportant = iterator.getUint32Le();

box.expectNoMoreBytes();

return {
type: 'strf-box-video',
biSize,
bitCount,
clrImportant,
clrUsed,
compression,
height,
planes,
sizeImage,
width,
xPelsPerMeter,
yPelsPerMeter,
};
};

export const parseStrf = ({
iterator,
size,
boxes,
}: {
iterator: BufferIterator;
size: number;
boxes: RiffBox[];
}): RiffBox => {
const strh = boxes.find((b) => b.type === 'strh-box');
if (!strh) {
throw new Error('strh box not found');
}

if (strh.fccType === 'vids') {
return parseStrfVideo({iterator, size});
}

if (strh.fccType === 'auds') {
return parseStrfAudio({iterator, size});
}

throw new Error(`Unsupported fccType: ${strh.fccType}`);
};
26 changes: 20 additions & 6 deletions packages/media-parser/src/test/parse-avi-file.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,18 @@ test('AVI file', async () => {
language: 0,
},
{
id: 'strf',
size: 40,
type: 'riff-box',
biSize: 40,
bitCount: 24,
clrImportant: 0,
clrUsed: 0,
compression: 'H264',
height: 270,
planes: 1,
sizeImage: 388800,
type: 'strf-box-video',
width: 480,
xPelsPerMeter: 0,
yPelsPerMeter: 0,
},
{
id: 'JUNK',
Expand Down Expand Up @@ -88,9 +97,14 @@ test('AVI file', async () => {
language: 0,
},
{
id: 'strf',
size: 18,
type: 'riff-box',
avgBytesPerSecond: 17454,
bitsPerSample: 16,
blockAlign: 1536,
cbSize: 0,
formatTag: 255,
numberOfChannels: 2,
sampleRate: 48000,
type: 'strf-box-audio',
},
{
id: 'JUNK',
Expand Down

0 comments on commit ecb1e3e

Please sign in to comment.