Skip to content

Commit

Permalink
Basic support for FLAC-in-MP4 audio tracks
Browse files Browse the repository at this point in the history
Allows for creating an MP4 stream with FLAC contents using
the MP4 box generation functions or AudioSegmentStream.

Use codec string 'fLaC' and specify a 'metadata' field in the
track info with the FLAC METADATA_BLOCK_HEADER fields to go
into the dfLa box.

See https://github.com/xiph/flac/blob/master/doc/isoflac.txt
for details of the MP4 embedding of FLAC audio.

Also allows variable-length audio packets in AudioSegmentStream

FLAC may have variable-length packets, so allow passing a
duration in samples on incoming frames.

This gets FLAC with, say, 960 samples per frame working
consistently in Firefox and Chrome.
  • Loading branch information
bvibber committed Jun 1, 2019
1 parent d17649e commit 46e4327
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lib/mp4/audio-frame-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ var generateSampleTable = function(frames) {
currentFrame = frames[i];
samples.push({
size: currentFrame.data.byteLength,
duration: 1024 // For AAC audio, all samples contain 1024 samples
duration: currentFrame.duration || 1024 // For AAC audio, all samples contain 1024 samples
});
}
return samples;
Expand Down
22 changes: 19 additions & 3 deletions lib/mp4/mp4-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

var UINT32_MAX = Math.pow(2, 32) - 1;

var box, dinf, esds, ftyp, mdat, mfhd, minf, moof, moov, mvex, mvhd,
var box, dfLa, dinf, esds, ftyp, mdat, mfhd, minf, moof, moov, mvex, mvhd,
trak, tkhd, mdia, mdhd, hdlr, sdtp, stbl, stsd, traf, trex,
trun, types, MAJOR_BRAND, MINOR_VERSION, AVC1_BRAND, VIDEO_HDLR,
AUDIO_HDLR, HDLR_TYPES, VMHD, SMHD, DREF, STCO, STSC, STSZ, STTS;
Expand All @@ -23,10 +23,12 @@ var box, dinf, esds, ftyp, mdat, mfhd, minf, moof, moov, mvex, mvhd,
avc1: [], // codingname
avcC: [],
btrt: [],
dfLa: [],
dinf: [],
dref: [],
esds: [],
ftyp: [],
fLaC: [],
hdlr: [],
mdat: [],
mdhd: [],
Expand Down Expand Up @@ -184,6 +186,13 @@ box = function(type) {
return result;
};

dfLa = function(track) {
return box(types.dfLa, new Uint8Array([
0x00, // version
0x00, 0x00, 0x00 // flags
]), track.metadata || []);
};

dinf = function() {
return box(types.dinf, box(types.dref, DREF));
};
Expand Down Expand Up @@ -465,7 +474,10 @@ stbl = function(track) {
};

audioSample = function(track) {
return box(types.mp4a, new Uint8Array([
var audioSampleBox = new Uint8Array([

// FLACSampleEntry extends AudioSampleEntry
// https://github.com/xiph/flac/blob/master/doc/isoflac.txt

// SampleEntry, ISO/IEC 14496-12
0x00, 0x00, 0x00,
Expand All @@ -488,7 +500,11 @@ stbl = function(track) {
0x00, 0x00 // samplerate, 16.16

// MP4AudioSampleEntry, ISO/IEC 14496-14
]), esds(track));
]);
if (track.codec === 'fLaC') {
return box(types.fLaC, audioSampleBox, dfLa(track));
}
return box(types.mp4a, audioSampleBox, esds(track));
};
}());

Expand Down

0 comments on commit 46e4327

Please sign in to comment.