### Getting Started
Source: https://github.com/xqq/mpegts.js/blob/master/README.md
Basic usage of mpegts.js to play a live stream.
```html
```
--------------------------------
### Installation
Source: https://github.com/xqq/mpegts.js/blob/master/README.md
Install mpegts.js using npm.
```bash
npm install --save mpegts.js
```
--------------------------------
### Local Storage Functions
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
Helper functions for getting and setting demo settings in local storage.
```javascript
function ls_get(key, def) {
try {
var ret = localStorage.getItem('mpegts_demo.' + key);
if (ret === null) {
ret = def;
}
return ret;
} catch (e) {}
return def;
}
function ls_set(key, value) {
try {
localStorage.setItem('mpegts_demo.' + key, value);
} catch (e) {}
}
```
--------------------------------
### Debug Commands
Source: https://github.com/xqq/mpegts.js/blob/master/README.md
Commands for installing dependencies, build tools, and building the project for debugging.
```bash
npm install # install dev-dependencies
npm install -g webpack-cli # install build tool
npm run build:debug # packaged & minimized js will be emitted in dist folder
```
--------------------------------
### CORS Header Example
Source: https://github.com/xqq/mpegts.js/blob/master/docs/cors.md
Example of an Access-Control-Allow-Origin header for a specific origin.
```http
Access-Control-Allow-Origin: http://flvplayback.com
```
--------------------------------
### Sample Input for Multipart Playback
Source: https://github.com/xqq/mpegts.js/blob/master/docs/multipart.md
An example of a JSON input conforming to the MediaDataSource structure for multipart FLV playback, demonstrating the expected format for 'type', 'duration', and 'segments' with specific values for duration, filesize, and URL.
```json
{
"type": "flv",
"duration": 1373161,
"segments": [
{
"duration": 333438,
"filesize": 60369190,
"url": "http://127.0.0.1/flv/7182741-1.flv"
},{
"duration": 390828,
"filesize": 75726439,
"url": "http://127.0.0.1/flv/7182741-2.flv"
},{
"duration": 434453,
"filesize": 103453988,
"url": "http://127.0.0.1/flv/7182741-3.flv"
},{
"duration": 214442,
"filesize": 44189200,
"url": "http://127.0.0.1/flv/7182741-4.flv"
}
]
}
```
--------------------------------
### Local Storage Functions
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
Functions to get and set items in local storage for persisting demo settings.
```javascript
function ls_get(key, def) {
try {
var ret = localStorage.getItem('mpegts_demo.' + key);
if (ret === null) {
ret = def;
}
return ret;
} catch (e) {}
return def;
}
function ls_set(key, value) {
try {
localStorage.setItem('mpegts_demo.' + key, value);
} catch (e) {}
}
```
--------------------------------
### Build
Source: https://github.com/xqq/mpegts.js/blob/master/README.md
Steps to build the project.
```bash
npm install # install dev-dependencies
npm install -g webpack-cli # install build tool
npm run build # packaged & minimized js will be emitted in dist folder
```
--------------------------------
### DOM Content Loaded Event Listener
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
Initializes the demo by loading settings, showing the version, and loading the player when the DOM is ready.
```javascript
document.addEventListener('DOMContentLoaded', function () {
streamURL = document.getElementById('streamURL');
mediaSourceURL = document.getElementById('mediaSourceURL');
loadSettings();
showVersion();
player_load();
});
```
--------------------------------
### Settings Saving and Loading
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
Functions to save the current demo settings to local storage and load them on initialization.
```javascript
function saveSettings() {
if (mediaSourceURL.className === '') {
ls_set('inputMode', 'MediaDataSource');
} else {
ls_set('inputMode', 'StreamURL');
}
var i;
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
ls_set(field, checkbox.checked ? '1' : '0');
}
var msURL = document.getElementById('msURL');
var sURL = document.getElementById('sURL');
ls_set('msURL', msURL.value);
ls_set('sURL', sURL.value);
console.log('save');
}
function loadSettings() {
var i;
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
var c = ls_get(field, checkbox.checked ? '1' : '0');
checkbox.checked = c === '1' ? true : false;
}
var msURL = document.getElementById('msURL');
var sURL = document.getElementById('sURL');
msURL.value = ls_get('msURL', msURL.value);
sURL.value = ls_get('sURL', sURL.value);
if (ls_get('inputMode', 'StreamURL') === 'StreamURL') {
switch_url();
} else {
switch_mds();
}
}
```
--------------------------------
### Sample HTTP FLV source
Source: https://github.com/xqq/mpegts.js/blob/master/docs/livestream.md
Configuration for an HTTP FLV livestream.
```json
{
// HTTP FLV
"type": "flv",
"isLive": true,
"url": "http://127.0.0.1:8080/live/livestream.flv"
}
```
--------------------------------
### Sample WebSocket source
Source: https://github.com/xqq/mpegts.js/blob/master/docs/livestream.md
Configuration for an MPEG2-TS/FLV over WebSocket livestream.
```json
{
// MPEG2-TS/FLV over WebSocket
"type": "mse",
"isLive": true,
"url": "ws://127.0.0.1:9090/live/livestream.flv"
}
```
--------------------------------
### DOM Content Loaded Event Listener
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
Initializes settings, shows version, and loads the player when the DOM is fully loaded.
```javascript
document.addEventListener('DOMContentLoaded', function () {
streamURL = document.getElementById('streamURL');
mediaSourceURL = document.getElementById('mediaSourceURL');
loadSettings();
showVersion();
player_load();
});
```
--------------------------------
### URL and MediaDataSource Switching Functions
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
Functions to switch between stream URL input and MediaDataSource JSON input modes.
```javascript
function switch_url() {
streamURL.className = '';
mediaSourceURL.className = 'hidden';
saveSettings();
}
function switch_mds() {
streamURL.className = 'hidden';
mediaSourceURL.className = '';
saveSettings();
}
```
--------------------------------
### Player Control Functions
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
JavaScript functions for loading, playing, pausing, destroying, and seeking within the media player.
```javascript
function player_load() {
console.log('isSupported: ' + mpegts.isSupported());
if (mediaSourceURL.className === '') {
var url = document.getElementById('msURL').value;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var mediaDataSource = JSON.parse(xhr.response);
player_load_mds(mediaDataSource);
}
xhr.send();
} else {
var i;
var mediaDataSource = { type: 'mse' };
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
mediaDataSource[field] = checkbox.checked;
}
mediaDataSource['url'] = document.getElementById('sURL').value;
console.log('MediaDataSource', mediaDataSource);
player_load_mds(mediaDataSource);
}
}
function player_load_mds(mediaDataSource) {
var element = document.getElementsByName('videoElement')[0];
if (typeof player !== "undefined") {
if (player != null) {
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
}
player = mpegts.createPlayer(mediaDataSource, {
enableWorker: true,
lazyLoadMaxDuration: 3 * 60,
seekType: 'range',
liveBufferLatencyChasing: document.getElementById('liveBufferLatencyChasing').checked,
});
player.attachMediaElement(element);
player.load();
}
function player_start() {
player.play();
}
function player_pause() {
player.pause();
}
function player_destroy() {
player.pause();
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
function player_seekto() {
var input = document.getElementsByName('seekpoint')[0];
player.currentTime = parseFloat(input.value);
}
```
--------------------------------
### Sample MPEG2-TS over HTTP source
Source: https://github.com/xqq/mpegts.js/blob/master/docs/livestream.md
Configuration for an MPEG2-TS over HTTP livestream.
```json
{
// MPEG2-TS over HTTP
"type": "mpegts",
"isLive": true,
"url": "http://127.0.0.1:8080/live/livestream.ts"
}
```
--------------------------------
### Show Version
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
Updates the document title to include the mpegts.js version.
```javascript
function showVersion() {
var version = mpegts.version;
document.title = document.title + " (v" + version + ")";
}
```
--------------------------------
### isSupported()
Source: https://github.com/xqq/mpegts.js/blob/master/docs/api.md
Checks if basic playback is supported in the current browser.
```javascript
function isSupported(): boolean;
```
--------------------------------
### URL and Settings Switching Functions
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
JavaScript functions to switch between stream URL and media source URL inputs, and to save settings.
```javascript
function switch_url() {
streamURL.className = '';
mediaSourceURL.className = 'hidden';
saveSettings();
}
function switch_mds() {
streamURL.className = 'hidden';
mediaSourceURL.className = '';
saveSettings();
}
```
--------------------------------
### Log Listener
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
Adds a listener to capture and display mpegts.js logs in a textarea.
```javascript
var logcatbox = document.getElementsByName('logcatbox')[0];
mpegts.LoggingControl.addLogListener(function(type, str) {
logcatbox.value = logcatbox.value + str + '\n';
logcatbox.scrollTop = logcatbox.scrollHeight;
});
```
--------------------------------
### Event Listener for Stream URL Input
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
Handles Enter key press on the stream URL input to save settings and reload the player.
```javascript
var sURL = document.getElementById('sURL');
sURL.onkeyup = function(event) {
if (event.key === 'Enter' || event.keyCode === 13) {
saveSettings()
if (player != null) {
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
player_load();
}
};
```
--------------------------------
### Version Display
Source: https://github.com/xqq/mpegts.js/blob/master/demo/index.html
Function to display the mpegts.js version on the page title.
```javascript
function showVersion() {
var version = mpegts.version;
document.title = document.title + " (v" + version + ")";
}
```
--------------------------------
### Save and Load Settings
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
Functions to save the current ARIB caption transmit mode and input mode to local storage, and to load them back.
```javascript
function saveSettings() {
if (document.getElementById('radio_private_stream_1').checked) {
arib_caption_transmit_mode = 'private_stream_1';
ls_set('aribCaptionTransmitMode', 'private_stream_1');
} else if (document.getElementById('radio_timed_id3').checked) {
arib_caption_transmit_mode = 'timed_id3';
ls_set('aribCaptionTransmitMode', 'timed_id3');
}
if (mediaSourceURL.className === '') {
ls_set('inputMode', 'MediaDataSource');
} else {
ls_set('inputMode', 'StreamURL');
}
var i;
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
ls_set(field, checkbox.checked ? '1' : '0');
}
var msURL = document.getElementById('msURL');
var sURL = document.getElementById('sURL');
ls_set('msURL', msURL.value);
ls_set('sURL', sURL.value);
console.log('save');
}
function loadSettings() {
arib_caption_transmit_mode = ls_get('aribCaptionTransmitMode', 'private_stream_1');
if (arib_caption_transmit_mode == "timed_id3") {
document.getElementById('radio_private_stream_1').checked = false;
document.getElementById('radio_timed_id3').checked = true;
}
var i;
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
var c = ls_get(field, checkbox.checked ? '1' : '0');
checkbox.checked = c === '1' ? true : false;
}
var msURL = document.getElementById('msURL');
var sURL = document.getElementById('sURL');
msURL.value = ls_get('msURL', msURL.value);
sURL.value = ls_get('sURL', sURL.value);
if (ls_get('inputMode', 'StreamURL') === 'StreamURL') {
switch_url();
} else {
switch_mds();
}
}
```
--------------------------------
### Static File Playback Header
Source: https://github.com/xqq/mpegts.js/blob/master/docs/cors.md
Recommended header for static MPEG2-TS/FLV file playback to expose Content-Length.
```http
Access-Control-Expose-Headers: Content-Length
```
--------------------------------
### MSEPlayer Interface
Source: https://github.com/xqq/mpegts.js/blob/master/docs/api.md
Interface for MSE (Media Source Extensions) player.
```typescript
interface MSEPlayer extends Player {}
```
--------------------------------
### ARIB Caption and Superimposition Logic
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
JavaScript code demonstrating how to handle private stream data for ARIB captions and superimposition, including parsing malformed PES packets and rendering them using aribb24.js.
```javascript
var checkBoxFields = ['isLive', 'withCredentials', 'liveSync'];
var streamURL, mediaSourceURL;
var arib_caption_transmit_mode;
function parseMalformedPES(data) {
var PES_scrambling_control = (data[0] & 0x30) >>> 4;
var PTS_DTS_flags = (data[1] & 0xC0) >>> 6;
var PES_header_data_length = data[2];
var payload_start_index = 3 + PES_header_data_length;
var payload_length = data.byteLength - payload_start_index;
var payload = data.subarray(payload_start_index, payload_start_index + payload_length);
return payload;
}
function player_load() {
console.log('isSupported: ' + mpegts.getFeatureList().mseLivePlayback);
if (mediaSourceURL.className === '') {
var url = document.getElementById('msURL').value;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var mediaDataSource = JSON.parse(xhr.response);
player_load_mds(mediaDataSource);
}
xhr.send();
} else {
var i;
var mediaDataSource = {
type: 'mse'
};
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
mediaDataSource[field] = checkbox.checked;
}
mediaDataSource['url'] = document.getElementById('sURL').value;
console.log('MediaDataSource', mediaDataSource);
player_load_mds(mediaDataSource);
}
}
function player_load_mds(mediaDataSource) {
var element = document.getElementsByName('videoElement')[0];
if (typeof player !== "undefined") {
if (player != null) {
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
if (captionRenderer != null) {
captionRenderer.dispose();
captionRenderer = null;
}
if (superimposeRenderer != null) {
superimposeRenderer.dispose();
superimposeRenderer = null;
}
}
player = mpegts.createPlayer(mediaDataSource, {
enableWorker: true,
enableWorkerForMSE: true,
liveSync: document.getElementById('liveSync').checked,
});
player.attachMediaElement(element);
player.load();
captionRenderer = new aribb24js.CanvasRenderer({
data_identifer: 0x80,
forceStrokeColor: 'black',
normalFont: '"Windows TV MaruGothic", "Hiragino Maru Gothic Pro", "HGMaruGothicMPRO", "Yu Gothic Medium", sans-serif',
gaijiFont: '"Windows TV MaruGothic", "Hiragino Maru Gothic Pro", "HGMaruGothicMPRO", "Yu Gothic Medium", sans-serif',
drcsReplacement: true,
useStrokeText: true,
});
captionRenderer.attachMedia(element);
captionRenderer.show();
superimposeRenderer = new aribb24js.CanvasRenderer({
data_identifer: 0x81,
forceStrokeColor: 'black',
normalFont: '"Windows TV MaruGothic", "Hiragino Maru Gothic Pro", "HGMaruGothicMPRO", "Yu Gothic Medium", sans-serif',
gaijiFont: '"Windows TV MaruGothic", "Hiragino Maru Gothic Pro", "HGMaruGothicMPRO", "Yu Gothic Medium", sans-serif',
drcsReplacement: true,
useStrokeText: true,
});
superimposeRenderer.attachMedia(element);
superimposeRenderer.show();
player.on(mpegts.Events.PES_PRIVATE_DATA_ARRIVED, function(data) {
if (arib_caption_transmit_mode !== 'private_stream_1') {
return;
}
if (data.stream_id === 0xBD && data.data[0] === 0x80) { // private_stream_1, caption
captionRenderer.pushData(data.pid, data.data, data.pts / 1000);
} else if (data.stream_id === 0xBF) { // private_stream_2, superimpose
var payload = data.data;
if (payload[0] !== 0x81) {
payload = parseMalformedPES(data.data);
}
if (payload[0] !== 0x81) {
return;
}
superimposeRenderer.pushData(data.pid, payload, data.nearest_pts / 1000);
}
});
/*
var process = [];
player.on(mpegts.Events.SMPTE2038_METADATA_ARRIVED, function(data) {
const pts = data.pts;
for (const ancillary of data.ancillaries) {
const { user_data } = ancillary;
// header 4 byte
const end_packet_flag = (user_data[2] & 0x20) !== 0;
const start_packet_flag = (user_data[2] & 0x40) !== 0;
// timing 12 byte
if (start_packet_flag && end_packet_flag) {
const offset = 16;
const packet = user_data.slice(offset, offset + 188);
const header = 4;
const adaptation_field_length = packet[header];
const pes = packet.slice(header + 1 + adaptation_field_length);
const pes_header = 6;
const pes_offset = pes_header + 3 + pes[pes_header + 2];
const data = pes.slice(pes_offset);
captionRenderer.pushData(data.pid, data, pts / 1000);
console.log(pts, Array.from(data).map((e) => e.toString(16)))
}
}
});
*/
player.on(mpegts.Events.TIMED_ID3_METADATA_ARRIVED, function(data) {
if (arib_caption_transmit_mode !== 'timed_id3') {
return;
}
captionRenderer.pushID3v2Data(data.pts / 1000, data.data);
});
player.on(mpegts.Events.ASYNCHRONOUS_KLV_METADATA_ARRIVED, function(data) {
console.log('sync', data);
})
player.on(mpegts.Events.PES_PRIVATE_DATA_DESCRIPTOR, function
```
--------------------------------
### Player Interface (abstract)
Source: https://github.com/xqq/mpegts.js/blob/master/docs/api.md
Abstract interface defining the core player functionalities.
```typescript
interface Player {
constructor(mediaDataSource: MediaDataSource, config?: Config): Player;
destroy(): void;
on(event: string, listener: Function): void;
off(event: string, listener: Function): void;
attachMediaElement(mediaElement: HTMLMediaElement): void;
detachMediaElement(): void;
load(): void;
unload(): void;
play(): Promise;
pause(): void;
type: string;
buffered: TimeRanges;
duration: number;
volume: number;
muted: boolean;
currentTime: number;
mediaInfo: Object;
statisticsInfo: Object;
}
```
--------------------------------
### Player Control Functions
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
JavaScript functions for controlling the media player, including play, pause, destroy, and seek.
```javascript
function player_start() {
player.play();
}
function player_pause() {
player.pause();
}
function player_destroy() {
player.pause();
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
function player_seekto() {
var input = document.getElementsByName('seekpoint')[0];
player.currentTime = parseFloat(input.value);
}
```
--------------------------------
### createPlayer Function Signature
Source: https://github.com/xqq/mpegts.js/blob/master/docs/api.md
The function signature for mpegts.createPlayer, which creates a player instance.
```typescript
function createPlayer(mediaDataSource: MediaDataSource, config?: Config): Player;
```
--------------------------------
### Stream URL Key Up Handler
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
Handles the Enter key press on the stream URL input to save settings and reload the player.
```javascript
var sURL = document.getElementById('sURL');
sURL.onkeyup = function(event) {
if (event.key === 'Enter' || event.keyCode === 13) {
saveSettings()
if (player != null) {
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
player_load();
}
};
```
--------------------------------
### getFeatureList()
Source: https://github.com/xqq/mpegts.js/blob/master/docs/api.md
Retrieves a list of supported features and their status.
```javascript
function getFeatureList(): FeatureList;
```
--------------------------------
### Log Listener
Source: https://github.com/xqq/mpegts.js/blob/master/demo/arib.html
Adds a listener to mpegts.LoggingControl to display log messages in a textarea.
```javascript
var logcatbox = document.getElementsByName('logcatbox')[0];
mpegts.LoggingControl.addLogListener(function(type, str) {
logcatbox.value = logcatbox.value + str + '\n';
logcatbox.scrollTop = logcatbox.scrollHeight;
});
```
--------------------------------
### NativePlayer Interface
Source: https://github.com/xqq/mpegts.js/blob/master/docs/api.md
Interface for native browser player wrapper, useful for single-part MP4 playback.
```typescript
interface NativePlayer extends Player {}
```
--------------------------------
### Wildcard CORS Header
Source: https://github.com/xqq/mpegts.js/blob/master/docs/cors.md
Using a wildcard value for Access-Control-Allow-Origin to allow any request origin.
```http
Access-Control-Allow-Origin: *
```
--------------------------------
### Preflight OPTIONS Response Headers
Source: https://github.com/xqq/mpegts.js/blob/master/docs/cors.md
Required CORS headers for the server's response to an OPTIONS request for Range seek.
```http
Access-Control-Allow-Origin: | *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: range
```
--------------------------------
### Basic CORS Header
Source: https://github.com/xqq/mpegts.js/blob/master/docs/cors.md
The server must respond with an Access-Control-Allow-Origin header when playing streams from another Origin.
```http
Access-Control-Allow-Origin: | *
```
--------------------------------
### MediaDataSource Structure for Multipart Playback
Source: https://github.com/xqq/mpegts.js/blob/master/docs/multipart.md
This JSON structure defines the format for providing a playlist for MediaDataSource when using FLV type for multipart playback. It includes details about the stream type, duration, CORS settings, audio/video presence, and a list of segments with their respective durations, file sizes, and URLs.
```json
{
// Required
"type": "flv", // Only flv type supports multipart playback
// Optional
"duration": 12345678, // total duration, in milliseconds
"cors": true,
"withCredentials": false,
// Optional
// true by default, do not indicate unless you have to deal with audio-only or video-only stream
"hasAudio": true,
"hasVideo": true,
// Required
"segments": [
{
"duration": 1234, // in milliseconds
"filesize": 5678, // in bytes
"url": "http://cdn.flvplayback.com/segments-1.flv"
},
{
"duration": 2345,
"filesize": 6789,
"url": "http://cdn.flvplayback.com/segments-2.flv"
},
{
"duration": 4567,
"filesize": 7890,
"url": "http://cdn.flvplayback.com/segments-3.flv"
}
// more segments...
]
}
```
--------------------------------
### LoggingControl Interface
Source: https://github.com/xqq/mpegts.js/blob/master/docs/api.md
Global interface for controlling mpegts.js log verbosity levels.
```typescript
interface LoggingControl {
forceGlobalTag: boolean;
globalTag: string;
enableAll: boolean;
enableDebug: boolean;
enableVerbose: boolean;
enableInfo: boolean;
enableWarn: boolean;
enableError: boolean;
getConfig(): Object;
applyConfig(config: Object): void;
addLogListener(listener: Function): void;
removeLogListener(listener: Function): void;
}
```
--------------------------------
### CORS with 301/302 Redirect
Source: https://github.com/xqq/mpegts.js/blob/master/docs/cors.md
Required CORS header for the redirection's response when a 3xx redirection occurs.
```http
Access-Control-Allow-Origin: null | *
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.