Author: Brendan Long b.long@cablelabs.com
CRC-32 code adapted from the output of Thomas Pircher's (MIT licensed) pycrc.
This library decodes MPEG-TS program-specific information into JSON. It's intended to be used with HTML5 DataCues, but will work in any case where you have an ArrayBuffer
.
For additional information, you may want to consult the ISO 13818-1 spec.
To use, copy mpegtssections.js into your application's script directory, then add something like this to the <head>
of your HTML page(s):
<script src="your-script-directory/mpegtssections.js"></script>
You can then use MpegTs
methods in your JavaScript code.
You can run the tests using Node.js:
cd ~/mpegtssection-js
npm install
npm test # runs unit tests
npm run-script hint # runs JSHint
See test/tests.js
for the Nodeunit tests.
JSHint follows directives in the /*jslint ... */
block at the top of each JavaScript file.
The following uses Web IDL syntax to describe the resulting data structures. The attribute names are taken directly from the MPEG-TS spec (except changed to CamelCase to match JavaScript conventions). Data which isn't only needed for parsing or validation is validated, but not exposed.
interface MpegTsSyntaxSection {
attribute unsigned short tableIdExtension;
attribute octet versionNumber;
attribute boolean currentNextIndicator;
attribute octet sectionNumber;
attribute octet lastSectionNumber;
}
interface MpegTsSection {
attribute octet tableId;
attribute MpegTsSyntaxSection? syntaxSection;
}
interface MpegTsDescriptor {
attribute octet tag;
attribute ArrayBuffer data;
}
See Table 2-25 - Program association section
interface MpegTsPatProgramInfo {
attribute unsigned short programNumber;
// this is the network_PID if programNumber == 0,
// or the program_map_PID if programNumber != 0
attribute unsigned short pid;
}
interface MpegTsPat implements MpegTsSection {
attribute unsigned short transportStreamId;
attribute MpegTsPatProgramInfo[] programInfo;
}
See Table 2-27 - Conditional access section.
interface MpegTsCat implements MpegTsSection {
attribute MpegTsDescriptor[] descriptors;
}
See Table 2-28 - Transport Stream program map section.
interface MpegTsElementaryStream {
attribute octet streamType;
attribute unsigned short elementaryPID;
attribute MpegTsDescriptor[] descriptors;
}
interface MpegTsPmt implements MpegTsSection {
attribute unsigned short programNumber;
attribute unsigned short? pcrPID; // 8191 maps to null
attribute MpegTsDescriptor[] descriptors;
attribute MpegTsElementaryStreamData[] streams;
}
See Table 2-30 - Private Section
interface MpegTsPrivateSection implements MpegTsSection {
attribute boolean privateIndicator;
attribute MpegTsSyntaxSection? syntaxSection;
ArrayBuffer privateData;
}
See Table 2-30-1 - The Transport Stream Description Table
interface MpegTsDescriptionSection implements MpegTsSection {
attribute MpegTsDescriptor[] descriptors;
}
String MpegTs.decodeSection(ArrayBuffer buf)
If buf
is a PSI table (starting with the table_id
), it will be decoded into the most appropriate type, using the following algorithm:
- If there are any serious problems with the data (lengths are wrong), throw a
BadSizeError
. - If
table_id
is 0, 1, 2, or 3 (PAT, CAT, PMT, Description), throw aMissingSyntaxSectionError
ifsyntax_section_indicator
is not 1. - If
syntax_section_indicator
is 1, throw anInvalidCrcError
if the CRC-32 of the buffer is not 0. - If the
table_id
is 0, return anMpegTsPat
. - If the
table_id
is 1, return anMpegTsCat
. - If the
table_id
is 2, return anMpegTsPmt
. - If the
table_id
is 3, return anMpegTsDescriptionSection
. - If the
table_id
is >= 128, return anMpegTsPrivateSection
. - Return an
MpegTsSection
.
unsigned short MpegTs.calculateCrc32(ArrayBuffer buf)
Calculates the CRC32/MPEG-2 of the given data. If you want to calculate the CRC of just part of the buffer, use ArrayBuffer.slice()
. For a valid MPEG-TS section with a syntax section, the CRC-32 of all of the data from the table_id
to the CRC_32
should be 0. This check will be run automatically by decodeSection()
.