@alessmicrosystems/mpegts.js
v1.8.4
Published
HTML5 MPEG2-TS Stream Player
Maintainers
Readme
mpegts.js 
HTML5 MPEG2-TS stream player written in TypeScript & JavaScript.
mpegts.js is optimized for low-latency live stream playback, such as DVB/ISDB television or surveillance cameras.
This project is based on flv.js.
Overview
mpegts.js works by transmuxing MPEG2-TS stream into ISO BMFF (Fragmented MP4) segments, followed by feeding mp4 segments into an HTML5 <video> element through Media Source Extensions API.
News
v1.8.4 (alessmicrosystems fork)
Configurable audio timestamp correction policy:
- Added
audioTimestampCorrectionPolicywithstrict,lenient, andoffmodes - Added
audioTimestampCorrectionThresholdMsfor tuning startup audio anchoring and lenient stale pre-wrap acceptance - Keeps existing safe behavior by default while allowing problematic live MPEG-TS streams to be relaxed per deployment
Safer timestamp handling diagnostics:
- Logs accepted stale pre-wrap audio timestamp corrections in lenient/off modes
- Continues rate-limited warnings for dropped stale timestamps and startup anchor normalization
- Added
v1.8.3 (alessmicrosystems fork)
Audio startup failure recovery:
- When audio init never becomes ready (dead audio PID, corrupt stream), the demuxer now abandons audio and proceeds video-only
isInitSegmentDispatched()allows video-only dispatch whenaudio_startup_failed_is flagged- Prevents indefinite stall waiting for audio that will never arrive
- 6-second timeout before audio is declared failed
Startup stash capped at 12 payloads:
- Audio stash limited to 12 most recent payloads during video init wait
- Prevents unbounded memory growth on slow-IDR streams
- Stash filter threshold tightened from 1500ms to 500ms for cleaner first-sample alignment
StartupStallJumper improved for slow canplay:
- Allows seek after 3 progress checks + 750ms buffer even if
canplayhasn't fired yet - Recovers streams where browser never emits
canplaybut buffered data is available - Counter reset on
canplayreceipt keeps normal path unaffected
selectAudioPididempotent guard:- No-ops when the requested PID is already active — avoids unnecessary audio init reset
- Prevents brief audio dropout on redundant PID selection calls
Diagnostic logging:
- First 3 media dispatches log video/audio sample counts, DTS values, and keyframe status
- Startup stash trim events logged with rate-limited counters
v1.8.2 (alessmicrosystems fork)
Audio PTS wrap-around detection and correction:
- Detects 33-bit PTS counter wrap-around in live MPEG-TS audio streams
- Automatically normalizes forward-wrapped timestamps to maintain monotonic time
- Drops stale pre-wrap timestamps that arrive after the wrap point
Audio timestamp discontinuity resilience (mp4-remuxer):
- Detects massive audio timestamp discontinuities (>30s or >180 frame durations) caused by audio PID switching
- Resets the audio timeline reference instead of dropping all frames (backward) or generating thousands of silent frames (forward)
- Prevents audio dropout and long silence gaps when switching audio tracks on live streams
Startup audio timestamp anchoring:
- Snaps the first audio sample's PTS to the video anchor DTS when drift exceeds 5 seconds
- Filters out stashed audio payloads with timestamps more than 1.5s behind the video anchor before replay
- Prevents remuxer-level discontinuity events on audio PID switches during stream startup
- Applied to all six audio codecs (AAC, LOAS-AAC, AC-3, E-AC-3, Opus, MP3)
selectAudioPidhardened against stale codec state:- Clears all legacy codec PID mappings and rebuilds only the requested track
selectAudioPid(0)correctly restores the default audio route- Resets audio init state on PID switch so the new codec config is cleanly dispatched
Stashed audio codec-aware replay:
- Audio payloads stashed before video init are tagged with their codec
- Replayed through the correct parser instead of always using AAC
- Fixes silent/garbled audio on tracks switched during stream startup
preferredAudioPidextended to all stream types:- Previously only applied during AC-3/E-AC-3 auto-fallback
- Now also selects the preferred track on AAC, MP3, and other codec streams
- Respects the config option on first PMT parse regardless of primary codec
v1.8.1 (alessmicrosystems fork)
Audio track selection for MPEG-TS live streams:
TRACKS_UPDATEDplayer event reports all available audio tracks (PID, codec, language) and subtitle tracks from PMT parsingswitchAudioPid(pid)API for in-place audio PID switchingpreferredAudioPidconfig option for pre-selecting an audio track beforeload()- ISO 639 language descriptor extraction for all audio PIDs
AC-3 / E-AC-3 auto-fallback:
- Detects browser-incompatible AC-3/E-AC-3 primary audio
- Auto-switches to the first compatible AAC or MP3 alternative without user intervention
- Respects
preferredAudioPidconfig when set
Keyframe-gated media dispatch:
- Media segments are held until the first H.264/H.265 IDR keyframe is seen after init segment dispatch
- Audio data before the first keyframe is stashed with its codec tag and replayed through the correct parser
- 6-second fallback timeout prevents indefinite stalling on streams with missing keyframes
SEI support:
SEI_ARRIVEDevent for H.264/H.265 Supplemental Enhancement Information NAL unitsSEIDatatype withtype,size,uuid,user_data, and optionalptsfields
Bug fixes:
- Fixed stashed audio replay always using AAC parser regardless of actual codec (affected MP3 fallback streams)
- Fixed
selectAudioPid(0)not restoring default audio route — now clears all stale codec PID mappings - Fixed
audio_metadata_changed_flag being set tofalseon video init instead of audio init (copy-paste bug) - Fixed
parseMP3Payloadmissingaudio_last_sample_pts_tracking - Fixed MP3 init segment missing
refSampleDuration - Fixed PMT multi-section parsing —
parsed_sectionsmap prevents duplicate audio entries
v1.8.0
Support working on iOS Safari with iOS 17.1+ through Apple's ManagedMediaSource API
Great performance improvements by supporting MSE in Workers on Chrome, Safari 18 (includes iOS)
Introduced support for AV1 over MPEG-TS
Introduced support for AV1 over HTTP-FLV defined in Enhanced RTMP
Support chasing live latency more smoothly by changing playback rate
Introduced ATSC EAC-3 audio codec in MPEG-TS
Support Opus and FLAC audio codec over HTTP-FLV (Enhanced RTMP)
v1.7.3
Introduced Enhanced RTMP with HEVC support for FLV.
Introduced Opus and ATSC AC-3 audio codec support for MPEG-TS.
Introduced LOAS AAC support for MPEG-TS.
v1.7.0
Introduced H.265/HEVC over MPEG-TS/FLV support.
Demo
http://xqq.github.io/mpegts.js/demo/
Features
- Playback for MPEG2-TS stream with H.264/H.265 + AAC codec transported in http(s) or WebSocket
- Playback for FLV stream with H.264/H.265 + AAC codec transported in http(s) or WebSocket
- Extremely low latency of less than 1 second in the best case
- Playback for
.m2tsfile like BDAV/BDMV with 192 bytes TS packet, or 204 bytes TS packet - Support handling dynamic codec parameters change (e.g. video resolution change)
- Support Chrome, FireFox, Safari, Edge (Old or Chromium) or any Chromium-based browsers
- Support chasing latency automatically for internal buffer of HTMLMediaElement
- Low CPU overhead and low memory usage (JS heap takes about 10MiB for each instance)
- Support extracting PES private data (stream_type=0x06) like ARIB B24 subtitles (with aribb24.js)
- Support Timed ID3 Metadata (stream_type=0x15) callback (TIMED_ID3_METADATA_ARRIVED)
- Multi-audio track support with PID switching for MPEG-TS live streams
- Automatic AC-3 / E-AC-3 fallback to AAC or MP3 for browser compatibility
CORS
If you use standalone video server for MPEG2-TS stream, Access-Control-Allow-Origin header must be configured correctly on video server for cross-origin resource fetching.
See cors.md for more details.
Installation
npm install --save mpegts.jsBuild
npm install # install dev-dependencies
npm install -g webpack-cli # install build tool
npm run build # packaged & minimized js will be emitted in dist foldercnpm mirror is recommended if you are in Mainland China.
Getting Started
<script src="mpegts.js"></script>
<video id="videoElement"></video>
<script>
if (mpegts.getFeatureList().mseLivePlayback) {
var videoElement = document.getElementById('videoElement');
var player = mpegts.createPlayer({
type: 'mse', // could also be mpegts, m2ts, flv
isLive: true,
url: 'http://example.com/live/livestream.ts'
});
player.attachMediaElement(videoElement);
player.load();
player.play();
}
</script>mpegts.js could be tested with Simple Realtime Server.
TODO
- MPEG2-TS static file playback (seeking is not supported now)
Limitations
- mpeg2video is not supported
- HTTP MPEG2-TS live stream could not work on old browsers like IE11
- mpegts.js is not usable on iOS version 17.0 or older caused by the banning of Media Source Extensions (available on iPadOS), iOS 17.1 works through Managed Media Source API
Features inherited from flv.js
- FLV container with H.264 + AAC / MP3 codec playback
- Multipart segmented video playback
- HTTP FLV low latency live stream playback
- FLV over WebSocket live stream playback
- Compatible with Chrome, FireFox, Safari 10, IE11 and Edge
- Extremely low overhead, and hardware accelerated by your browser!
FLV playback limitations
- MP3 audio codec is currently not working on IE11 / Edge
- HTTP FLV live stream is not currently working on all browsers, see livestream.md
FLV Multipart playback
You only have to provide a playlist for MediaDataSource. See multipart.md
Livestream playback
See livestream.md
API and Configuration
See api.md
Debug
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 folderDesign
See design.md
License
Copyright (C) 2021 magicxqq. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.