Skip to content

Commit

Permalink
Merge pull request #13 from SidOfc/patch/mp4-extended-size
Browse files Browse the repository at this point in the history
patch/mp4 extended size
  • Loading branch information
SidOfc authored Mar 19, 2023
2 parents a32ab09 + f806405 commit 50ee59c
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 21 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,4 @@ All supported image and video formats can be found in the table below:
- http://netpbm.sourceforge.net/doc/#formats
- https://www.garykessler.net/library/file_sigs.html
- https://github.com/sannies/mp4parser/blob/c869d076e9cd42aba5a3e35d88827610dec6ca15/examples/src/main/java/com/google/code/mp4parser/example/GetHeight.java
- https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "leather",
"version": "2.1.3",
"version": "2.1.4",
"description": "A pure JS library for extracting image/video attributes such as width, height, size, and mime type",
"author": "Sidney Liebrand",
"license": "MIT",
Expand Down
29 changes: 11 additions & 18 deletions src/extractors/mp4.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,53 +7,46 @@ const MIME_TYPES = {

export function attributes(input) {
const stream = lazystream(input);
const size = stream.size();
const type = stream.skip(4).take(8).toString('hex');
const mime = MIME_TYPES[type] || 'video/mp4';

stream.goto(0);

const result = Object.assign(parse(stream) ?? {}, {
size: stream.size(),
mime,
});
const result = Object.assign(parse(stream), {size, mime});

stream.close();

return result;
}

function parse(stream, lastTkhd, ftypSize = 32) {
function parse(stream, lastTkhd) {
while (stream.more()) {
let size = stream.takeUInt32BE();
const initialSize = stream.takeUInt32BE();
const header = stream.take(4).toString();

if (header === 'ftyp') ftypSize = size;
const size = initialSize === 1 ? stream.takeUInt64BE() : initialSize;

if (['moov', 'mdia', 'trak'].includes(header)) {
const result = parse(stream, lastTkhd, ftypSize);
const result = parse(stream, lastTkhd);

if (result) return result;
} else if (ftypSize === 28 && header === 'mdat') {
size += stream.skip(4).takeUInt32BE() - size;
} else if (header === 'tkhd') {
const pos = stream.position();
lastTkhd = stream.take(size - 8);

stream.goto(pos);
stream.rewind(size - 8);
} else if (header === 'hdlr') {
const pos = stream.position();
const hdlr = stream.skip(8).take(4);

if (hdlr.includes('vide')) {
if (stream.skip(8).take(4).includes('vide')) {
return {
width: lastTkhd.readUInt32BE(lastTkhd.length - 8) / 65536,
height: lastTkhd.readUInt32BE(lastTkhd.length - 4) / 65536,
};
}

stream.goto(pos);
stream.rewind(12);
}

stream.skip(size - 8);
}

return {width: 0, height: 0};
}
9 changes: 9 additions & 0 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export function lazystream(file) {
take(bytes = 1) {
if (isBuffer) {
const buffer = reader.subarray(position, position + bytes);

position += buffer.length;

return buffer;
Expand All @@ -97,6 +98,7 @@ export function lazystream(file) {
bytes,
position
);

position += bytesRead;

return buffer;
Expand Down Expand Up @@ -160,6 +162,13 @@ export function lazystream(file) {
return methods.take(4).readUInt32LE();
},

takeUInt64BE() {
const v1 = methods.takeUInt32BE();
const v2 = methods.takeUInt32BE();

return 0x100000000 * v1 + v2;
},

takeUInt64LE() {
const v1 = methods.takeUInt32LE();
const v2 = methods.takeUInt32LE();
Expand Down

0 comments on commit 50ee59c

Please sign in to comment.