-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #426 from adrums86/emsg-support
feat: support emsg box ID3 parsing
- Loading branch information
Showing
9 changed files
with
630 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
var uint8ToCString = require('../utils/string.js').uint8ToCString; | ||
|
||
/** | ||
* Based on: ISO/IEC 23009 Section: 5.10.3.3 | ||
* References: | ||
* https://dashif-documents.azurewebsites.net/Events/master/event.html#emsg-format | ||
* https://aomediacodec.github.io/id3-emsg/ | ||
* | ||
* Takes emsg box data as a uint8 array and returns a emsg box object | ||
* @param {UInt8Array} boxData data from emsg box | ||
* @returns A parsed emsg box object | ||
*/ | ||
var parseEmsgBox = function(boxData) { | ||
// version + flags | ||
var offset = 4; | ||
var version = boxData[0]; | ||
var scheme_id_uri, | ||
value, | ||
timescale, | ||
presentation_time, | ||
presentation_time_delta, | ||
event_duration, | ||
id, | ||
message_data; | ||
if (version === 0) { | ||
scheme_id_uri = uint8ToCString(boxData.subarray(offset)); | ||
offset += scheme_id_uri.length; | ||
value = uint8ToCString(boxData.subarray(offset)); | ||
offset += value.length; | ||
var dv = new DataView(boxData.buffer); | ||
timescale = dv.getUint32(offset); | ||
offset += 4; | ||
presentation_time_delta = dv.getUint32(offset); | ||
offset += 4; | ||
event_duration = dv.getUint32(offset); | ||
offset += 4; | ||
id = dv.getUint32(offset); | ||
offset += 4; | ||
} else if (version === 1) { | ||
var dv = new DataView(boxData.buffer); | ||
timescale = dv.getUint32(offset); | ||
offset += 4; | ||
presentation_time = Number(dv.getBigUint64(offset)); | ||
offset += 8; | ||
event_duration = dv.getUint32(offset); | ||
offset += 4; | ||
id = dv.getUint32(offset); | ||
offset += 4; | ||
scheme_id_uri = uint8ToCString(boxData.subarray(offset)); | ||
offset += scheme_id_uri.length; | ||
value = uint8ToCString(boxData.subarray(offset)); | ||
offset += value.length; | ||
} | ||
|
||
message_data = new Uint8Array(boxData.subarray(offset, boxData.byteLength)); | ||
var emsgBox = { | ||
scheme_id_uri, | ||
value, | ||
// if timescale is undefined or 0 set to 1 | ||
timescale: timescale ? timescale : 1, | ||
presentation_time, | ||
presentation_time_delta, | ||
event_duration, | ||
id, | ||
message_data }; | ||
|
||
return isValidEmsgBox(version, emsgBox) ? emsgBox : undefined; | ||
}; | ||
|
||
/** | ||
* Scales a presentation time or time delta with an offset with a provided timescale | ||
* @param {number} presentationTime | ||
* @param {number} timescale | ||
* @param {number} timeDelta | ||
* @param {number} offset | ||
* @returns the scaled time as a number | ||
*/ | ||
var scaleTime = function(presentationTime, timescale, timeDelta, offset) { | ||
return presentationTime || presentationTime === 0 ? presentationTime / timescale : offset + timeDelta / timescale; | ||
}; | ||
|
||
/** | ||
* Checks the emsg box data for validity based on the version | ||
* @param {number} version of the emsg box to validate | ||
* @param {Object} emsg the emsg data to validate | ||
* @returns if the box is valid as a boolean | ||
*/ | ||
var isValidEmsgBox = function(version, emsg) { | ||
var hasScheme = emsg.scheme_id_uri !== '\0' | ||
var isValidV0Box = version === 0 && isDefined(emsg.presentation_time_delta) && hasScheme; | ||
var isValidV1Box = version === 1 && isDefined(emsg.presentation_time) && hasScheme; | ||
// Only valid versions of emsg are 0 and 1 | ||
return !(version > 1) && isValidV0Box || isValidV1Box; | ||
}; | ||
|
||
// Utility function to check if an object is defined | ||
var isDefined = function(data) { | ||
return data !== undefined || data !== null; | ||
}; | ||
|
||
module.exports = { | ||
parseEmsgBox: parseEmsgBox, | ||
scaleTime: scaleTime | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.