Skip to content

Instantly share code, notes, and snippets.

@OllieJones
Last active September 5, 2018 13:38
Show Gist options
  • Save OllieJones/5ffb011fa3a11964154975582360391c to your computer and use it in GitHub Desktop.
Save OllieJones/5ffb011fa3a11964154975582360391c to your computer and use it in GitHub Desktop.
Read useful information from a MP4 data stream
/*
* this code examines a MP4 data stream.
* it looks at the appropriate atoms to determine width, height, and frame rate.
*
* It is a sleazy approach, the equivalent of grepping for necessary
* boxes rather than using box lengths to parse the file.
*/
function read32( buff, fourcc, offset ) {
let start = 0;
for( let i = 0; i < fourcc.length; i++ ) {
start = buff.indexOf( new Buffer( fourcc[i] ), start ) + 4;
}
return buff.readUInt32BE( start + offset, 4 );
}
function readfourcc( buff, fourcc, offset ) {
let start = 0;
for( let i = 0; i < fourcc.length; i++ ) {
start = buff.indexOf( new Buffer( fourcc[i] ), start ) + 4;
}
return buff.toString( 'ascii', start + offset, start + offset + 4 );
}
function read16( buff, fourcc, offset ) {
let start = 0;
for( let i = 0; i < fourcc.length; i++ ) {
start = buff.indexOf( new Buffer( fourcc[i] ), start ) + 4;
}
return buff.readUInt16BE( start + offset, 2 );
}
function streamPeek( buff ) {
let result = { format: '?', framerate: 0, width: 0, height: 0 };
try {
let format = readfourcc( buff, ['ftyp'], 0 );
if( format === 'mp42' ) {
let timescale = read32( buff, ['moov', 'mvhd'], 12 );
let framescale = read32( buff, ['moov', 'trak', 'mdhd'], 12 );
let framerate = framescale / timescale;
let width = read16( buff, ['moov', 'trak', 'stbl', 'avc1'], 24 );
let height = read16( buff, ['moov', 'trak', 'stbl', 'avc1'], 26 );
result.format = format;
result.framerate = framerate;
result.width = width;
result.height = height;
}
}
catch( e ) {
/* empty */
}
return result;
}
/* sample use */
const fs = require( 'fs' );
let buff = new Buffer( 600 );
fs.open( file, 'r', function( err, fd ) {
fs.read( fd, buff, 0, buff.length, 0, function( err, bytesRead, buffer ) {
let str = streamPeek( buffer );
console.log( str );
} );
} );
@OllieJones
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment