Locate and read MPEG audio file sections: Individual frames as well as ID3v2 and Xing/Lame tags. For
any of these found within a given buffer, mp3 Parser will provide data indicating their presence,
their position within the buffer, as well as relevant informative data (with varying degrees of
detail).
Set up
To use mp3 Parser
install with bower, bower install mp3-parser or
install with npm, npm install mp3-parser or
just include the relevant files (see below), in case you're targeting a browser and don't want to
go over npm or bower.
mp3 Parser may be used as a CommonJS module on Node or in a browser, either as an AMD module or
through plain <script> tags. It's automatically exported in the appropriate format depending on
the current environment:
When working with CommonJS (e.g. Node), assuming mp3 Parser is npm installed:
var mp3Parser = require("mp3-parser");
var mp3Tags = mp3Parser.readTags(someMp3DataView);
When working with an AMD loader (e.g. requireJS):
// Your module
define(["path/to/mp3-parser/main"], function (mp3Parser) {
var mp3Tags = mp3Parser.readTags(someMp3DataView);
});
In the example above, it is assumed that mp3-parser source files live in
path/to/mp3-parser (relative to the root path used for module lookups). When using requireJS
you may prefer to treat mp3-parser as a package:
// Configure requireJS for the mp3-parser package ..require.config({
packages: [{
name: "mp3-parser",
location: "path/to/mp3-parser"
}]
})
// .. and refer to mp3-parser module by its given package name
define(["mp3-parser"], function (mp3Parser) {
var mp3Tags = mp3Parser.readTags(someMp3DataView);
});
Setting up mp3 Parser in projects targetting browsers, without an AMD module loader, is
unfortunately quite verbose as it relies on the (order-specific) inclusion of a number of
sources. This should be mitigated in the future, but for now you would need:
var mp3Tags = mp3Parser.readTags(someMp3DataView);
Usage
The parser's API consists of read____ methods, each dedicated to reading a specific section
of the MPEG audio file. The current implementation includes readFrameHeader, readFrame,
readLastFrame, readId3v2Tag, readXingTag and readTags. Each of these accepts a
DataView-wrapped ArrayBuffer
containing the audio data, and optionally an offset into the buffer.
In all cases, a 'description' will be returned - a hash containing key-value pairs relevant to the
specific section being read. For example, the hash returned by readFrameHeader for an mp3 file
will include an mpegAudioVersion key of value "MPEG Version 1 (ISO/IEC 11172-3)" and a
layerDescription key of value "Layer III". A section description will always include a
_section attribute - a hash with type, byteLength and offset keys:
type: "frame", "frameHeader", "Xing" or "ID3v2"
byteLenfth: Size of the section in bytes
offset: Buffer offset at which this section resides
In further detail:
readFrameHeader(view, [offset])
Read and return description of header of frame located at offset of DataView view. Returns
null in the event that no frame header is found at offset.
A couple of example descriptions:
Version 1, Layer III (mp3), 44.1KHz 128Kbs Joint Stereo:
Read and return description of frame located at offset of DataView view. Includes the frame
header description (see readFrameHeader) plus basic information about the frame: The frame's
length in bytes and the index of the next frame ifrequireNextFrame is set. In this case, the
presence of a next valid frame will be required for this frame to be regarded as valid. Returns
null in the event that no frame is found at offset.
Locate and return the description of the very last valid frame in given DataView view. The search
is carried out in reverse, from given offset (or the very last octet if offset is omitted) to
the buffer's beginning. If requireNextFrame is set, the presence of a next valid frame will be
required for any found frame to be regarded as valid (causing the method to essentially return the
next-to-last frame on success). Returns null in the event that no frame is found at offset.
readId3v2Tag(view[, offset])
Read and return description of ID3v2 Tag located at offset of
DataView view. (This will include any and all
currently supported ID3v2 frames located within the
tag). Returns null in the event that no tag is found at offset.
Read and return description of Xing / Lame Tag
located at offset of DataView view. Returns null in the event that no frame is found at
offset.
As an example description:
{
_section: {
type: 'Xing',
offset: 2462,
byteLength: 417,
nextFrameIndex: 2879
},
header: { /* .. a frame header description .. */ },
identifier: 'Xing'// Or 'Info' if Lame tag
}
readTags(view[, offset])
Read and return descriptions of all tags found up to (and additionally including) the very first
frame. Returns an array of descriptions which may include that of a located ID3V2 tag, of a located
Xing / Lame tag and of a located first frame.
Take a look at the project's wiki which contains a
list of currently (un)supported ID3v2 tag frames.
Contributing
Contibutions are appreciated, naturally. Feel free to submit pull requests against master. Please
make sure that npm run lint and npm test are green before you do so. Pull requests featuring
appropriate unit tests are ideal. However, less than ideal pull requests are also fine, especially
until the test suite gets the documentation it deserves - probably along with some necessary
housekeeping.
mp3 Parser
Locate and read MPEG audio file sections: Individual frames as well as ID3v2 and Xing/Lame tags. For any of these found within a given buffer, mp3 Parser will provide data indicating their presence, their position within the buffer, as well as relevant informative data (with varying degrees of detail).
Set up
To use mp3 Parser
bower install mp3-parser
ornpm install mp3-parser
ormp3 Parser may be used as a CommonJS module on Node or in a browser, either as an AMD module or through plain
<script>
tags. It's automatically exported in the appropriate format depending on the current environment:When working with CommonJS (e.g. Node), assuming mp3 Parser is
npm install
ed:var mp3Parser = require("mp3-parser"); var mp3Tags = mp3Parser.readTags(someMp3DataView);
When working with an AMD loader (e.g. requireJS):
// Your module define(["path/to/mp3-parser/main"], function (mp3Parser) { var mp3Tags = mp3Parser.readTags(someMp3DataView); });
In the example above, it is assumed that mp3-parser source files live in
path/to/mp3-parser
(relative to the root path used for module lookups). When using requireJS you may prefer to treat mp3-parser as a package:// Configure requireJS for the mp3-parser package .. require.config({ packages: [{ name: "mp3-parser", location: "path/to/mp3-parser" }] }) // .. and refer to mp3-parser module by its given package name define(["mp3-parser"], function (mp3Parser) { var mp3Tags = mp3Parser.readTags(someMp3DataView); });
Setting up mp3 Parser in projects targetting browsers, without an AMD module loader, is unfortunately quite verbose as it relies on the (order-specific) inclusion of a number of sources. This should be mitigated in the future, but for now you would need:
... <script type="text/javascript" src="path/to/mp3-parser/lib/lib.js"></script> <script type="text/javascript" src="path/to/mp3-parser/lib/xing.js"></script> <script type="text/javascript" src="path/to/mp3-parser/lib/id3v2.js"></script> <script type="text/javascript" src="path/to/mp3-parser/main.js"></script> ...
which would export the
mp3Parser
global:var mp3Tags = mp3Parser.readTags(someMp3DataView);
Usage
The parser's API consists of
read____
methods, each dedicated to reading a specific section of the MPEG audio file. The current implementation includesreadFrameHeader
,readFrame
,readLastFrame
,readId3v2Tag
,readXingTag
andreadTags
. Each of these accepts a DataView-wrapped ArrayBuffer containing the audio data, and optionally an offset into the buffer.In all cases, a 'description' will be returned - a hash containing key-value pairs relevant to the specific section being read. For example, the hash returned by
readFrameHeader
for an mp3 file will include anmpegAudioVersion
key of value "MPEG Version 1 (ISO/IEC 11172-3)" and alayerDescription
key of value "Layer III". A section description will always include a_section
attribute - a hash withtype
,byteLength
andoffset
keys:type
: "frame", "frameHeader", "Xing" or "ID3v2"byteLenfth
: Size of the section in bytesoffset
: Buffer offset at which this section residesIn further detail:
readFrameHeader(view, [offset])
Read and return description of header of frame located at
offset
of DataViewview
. Returnsnull
in the event that no frame header is found atoffset
.A couple of example descriptions:
Version 1, Layer III (mp3), 44.1KHz 128Kbs Joint Stereo:
{ _section: { type: 'frameHeader', offset: 99934, byteLength: 4 }, mpegAudioVersionBits: '11', mpegAudioVersion: 'MPEG Version 1 (ISO/IEC 11172-3)', layerDescriptionBits: '01', layerDescription: 'Layer III', isProtected: 1, protectionBit: '1', bitrateBits: '1001', bitrate: 128, samplingRateBits: '00', samplingRate: 44100, frameIsPaddedBit: '1', frameIsPadded: true, framePadding: 1, privateBit: '0', channelModeBits: '01', channelMode: 'Joint stereo (Stereo)' }
Version 2, Layer II, 16KHz 32Kbs Mono:
{ _section: { type: 'frameHeader', offset: 0, byteLength: 4 }, mpegAudioVersionBits: '10', mpegAudioVersion: 'MPEG Version 2 (ISO/IEC 13818-3)', layerDescriptionBits: '10', layerDescription: 'Layer II', isProtected: 1, protectionBit: '1', bitrateBits: '0100', bitrate: 32, samplingRateBits: '10', samplingRate: 16000, frameIsPaddedBit: '0', frameIsPadded: false, framePadding: 0, privateBit: '0', channelModeBits: '11', channelMode: 'Single channel (Mono)' }
readFrame(view, [offset[, requireNextFrame]])
Read and return description of frame located at
offset
of DataViewview
. Includes the frame header description (seereadFrameHeader
) plus basic information about the frame: The frame's length in bytes and the index of the next frame ifrequireNextFrame
is set. In this case, the presence of a next valid frame will be required for this frame to be regarded as valid. Returnsnull
in the event that no frame is found atoffset
.As an example description:
{ _section: { type: 'frame', offset: 99934, byteLength: 418, sampleLength: 1152, nextFrameIndex: 100352 // Available iff 'requireNextFrame' }, header: { /* .. a frame header description .. */ } }
readLastFrame(view, [offset[, requireNextFrame]])
Locate and return the description of the very last valid frame in given DataView
view
. The search is carried out in reverse, from givenoffset
(or the very last octet ifoffset
is omitted) to the buffer's beginning. IfrequireNextFrame
is set, the presence of a next valid frame will be required for any found frame to be regarded as valid (causing the method to essentially return the next-to-last frame on success). Returnsnull
in the event that no frame is found atoffset
.readId3v2Tag(view[, offset])
Read and return description of ID3v2 Tag located at
offset
of DataViewview
. (This will include any and all currently supported ID3v2 frames located within the tag). Returnsnull
in the event that no tag is found atoffset
.As an example description:
{ _section: { type: 'ID3v2', offset: 0, byteLength: 2048 }, header: { majorVersion: 3, minorRevision: 0, flagsOctet: 0, unsynchronisationFlag: false, extendedHeaderFlag: false, experimentalIndicatorFlag: false, size: 2038 }, frames: [{ header: { id: 'TIT2', size: 12, flagsOctet1: 0, flagsOctet2: 0 }, name: 'Title/songname/content description', content: { encoding: 0, value: 'Flight Path' } }, { header: { id: 'TPUB', size: 10, flagsOctet1: 0, flagsOctet2: 0 }, name: 'Publisher', content: { encoding: 0, value: 'Planet Mu' } }, { header: { id: 'TCON', size: 4, flagsOctet1: 0, flagsOctet2: 0 }, name: 'Content type', content: { encoding: 0, value: '(3)' } }, { header: { id: 'TALB', size: 9, flagsOctet1: 0, flagsOctet2: 0 }, name: 'Album/Movie/Show title', content: { encoding: 0, value: 'Severant' } }, { header: { id: 'TRCK', size: 3, flagsOctet1: 0, flagsOctet2: 0 }, name: 'Track number/Position in set', content: { encoding: 0, value: '11' } }, { header: { id: 'TYER', size: 5, flagsOctet1: 0, flagsOctet2: 0 }, name: 'Year', content: { encoding: 0, value: '2011' } }, { /* .. more frames follow .. */ }] }
readXingTag(view[, offset])
Read and return description of Xing / Lame Tag located at
offset
of DataViewview
. Returnsnull
in the event that no frame is found atoffset
.As an example description:
{ _section: { type: 'Xing', offset: 2462, byteLength: 417, nextFrameIndex: 2879 }, header: { /* .. a frame header description .. */ }, identifier: 'Xing' // Or 'Info' if Lame tag }
readTags(view[, offset])
Read and return descriptions of all tags found up to (and additionally including) the very first frame. Returns an array of descriptions which may include that of a located ID3V2 tag, of a located Xing / Lame tag and of a located first frame.
You may also want to
Contributing
Contibutions are appreciated, naturally. Feel free to submit pull requests against
master
. Please make sure thatnpm run lint
andnpm test
are green before you do so. Pull requests featuring appropriate unit tests are ideal. However, less than ideal pull requests are also fine, especially until the test suite gets the documentation it deserves - probably along with some necessary housekeeping.Changelog
Next — Diff
TBD
0.3.0 — Nov 20, 2016 — Diff
License
Licensed and freely distributed under the MIT License (LICENSE.txt).
Copyright (c) 2013-2016 Alex Lambiris