TS File Documentation
Summary
A .ts file (in video) is an MPEG Transport Stream, the container defined by MPEG-2 Systems (ISO/IEC 13818-1, 1995) for broadcasting and streaming. It carries multiplexed video, audio and data as a chain of fixed 188-byte packets, each beginning with the sync byte 0x47, a design meant to stay recoverable through transmission errors. It is the format of digital TV, PVR recordings, AVCHD camcorders, Blu-ray and HLS streaming. Play it in VLC; remux it to MP4 with ffmpeg. Its MIME type is video/mp2t.
Technical details
| Feature | Value |
|---|---|
| Full name | MPEG Transport Stream (MPEG-2 TS) |
| File extension | .ts (variants .mts, .m2ts, .trp) |
| MIME type | video/mp2t |
| Format type | Binary multiplexed container, fixed 188-byte packets |
| Developer | MPEG / ISO/IEC (MPEG-2 Systems) |
| Introduced | 1995 (ISO/IEC 13818-1) |
| Standard | ISO/IEC 13818-1, MPEG-2 Systems (Transport Stream) |
| Open standard | Yes (ISO/IEC standard) |
| Packet size | 188 bytes (192 with a 4-byte timecode in M2TS/BDAV) |
| Byte order | Big-endian (network byte order) |
| Sync byte | 0x47 at the start of every 188-byte packet |
| Typical video codecs | H.262 (MPEG-2), H.264/AVC, H.265/HEVC |
| Typical audio codecs | MPEG audio, AC-3, AAC |
| Multiplex tables | PAT (PID 0) → PMT → elementary-stream PIDs |
| Related extensions | .mts, .m2ts, .mp4, .mkv, .vob |
| Specification | ISO/IEC 13818-1 |
What is a TS file?
A .ts file, in the video sense, is an MPEG Transport Stream. It is the container defined in MPEG-2 Systems, standardised as ISO/IEC 13818-1 in 1995, for carrying audio, video and data over channels that can lose or corrupt bytes: terrestrial, satellite and cable broadcast (DVB and ATSC), AVCHD camcorders, Blu-ray (whose .m2ts is a TS variant), PVR/DVR recordings, and HTTP Live Streaming segments. Where a file container like MP4 assumes it lives on reliable storage and can seek freely, a transport stream assumes the opposite and is built to be picked up mid-stream and to survive errors.
The whole format is a chain of small, fixed-size packets, and almost everything interesting about it follows from that one decision. The sections below cover the 188-byte packet and its sync byte, the PID addressing that lets many programs share one stream, the PAT/PMT tables that map the stream, how coded video and audio are wrapped in PES packets, the timestamps that keep everything in sync, and why all of this makes TS trivial to cut and join but awkward to seek and edit.
The 188-byte packet and the 0x47 sync byte
A transport stream is a continuous run of 188-byte packets. Every packet begins with the sync byte 0x47, so byte 0, byte 188, byte 376 and so on are all 0x47. A decoder that tunes into a stream part-way through finds packet boundaries by looking for 0x47 repeating at 188-byte intervals; a single stray 0x47 in the payload is ruled out because the next one would not fall on the interval. This is also why file-type detection for TS looks for the repeating sync rather than a one-off header — there is no file header at all.
Transport packet (188 bytes)
byte 0 sync_byte = 0x47
bytes 1-3 flags + 13-bit PID
transport_error_indicator (1 bit)
payload_unit_start_indicator (1 bit) // start of a PES/section here
transport_priority (1 bit)
PID (13 bits) // which stream this packet carries
byte 3 scrambling (2) + adaptation_field_control (2) + continuity_counter (4)
[adaptation field, optional] // PCR, stuffing, random-access flags
[payload] // up to the rest of the 188 bytes
The 4-bit continuity_counter increments per PID so a receiver can detect a dropped packet. The adaptation_field_control says whether an adaptation field, a payload, or both follow the header. In the Blu-ray/AVCHD M2TS variant each packet is 192 bytes: a 4-byte arrival timestamp is prepended to the standard 188, which is the main structural difference between plain .ts and .m2ts.
PID: how one stream carries many streams
The 13-bit PID (Packet Identifier) in the header is the routing key of the whole format. Every elementary stream — a video track, an audio track, a subtitle track, a table — is assigned a PID, and a packet belongs to whichever stream its PID names. Demultiplexing is therefore just sorting packets by PID. This is what lets a single broadcast transport stream carry several complete TV programs at once (multi-program transport stream): the video of program 1, the audio of program 1, the video of program 2 and so on are all interleaved as packets with different PIDs. A single .ts file recorded from a tuner is usually one program, but the addressing scheme is the same. Certain PIDs are reserved: PID 0x0000 always carries the Program Association Table.
PAT and PMT: the map of the stream
A receiver that knows nothing about a stream needs to discover what is in it, and that is the job of two tables carried as special packets. The Program Association Table (PAT) is always on PID 0x0000. It lists every program in the stream and, for each, gives the PID of that program’s Program Map Table (PMT). The PMT then lists the elementary streams of one program: the PID and stream type of the video, of each audio track, of subtitles, and which PID carries that program’s clock.
PAT (PID 0x0000)
program_number 1 -> PMT on PID 0x1000
PMT (PID 0x1000)
PCR_PID = 0x0100
stream_type 0x1B (H.264) -> PID 0x0100 video
stream_type 0x0F (AAC) -> PID 0x0101 audio
stream_type 0x06 (subs) -> PID 0x0102 subtitle
The lookup is always PAT → PMT → elementary PIDs. Because these tables are re-sent periodically rather than written once at the top of the file, a player can begin decoding from any point in the stream, which is precisely the property broadcast needs. It is also why a truncated .ts that starts mid-file still plays: the tables come around again.
PES packets: wrapping the coded audio and video
Coded video and audio do not sit raw in the transport packets. Each elementary stream is first cut into Packetized Elementary Stream (PES) packets, and those PES packets are then chopped across the 188-byte transport payloads of that stream’s PID. The payload_unit_start_indicator in the transport header flags the packet where a new PES packet begins. A PES header carries the stream ID and, importantly, the presentation and decode timestamps for the media it introduces. So the layering is: elementary bitstream (e.g. an H.264 access unit) → PES packet with timestamps → a run of 188-byte TS packets sharing one PID. Typical payloads are H.264 or H.265 video with AC-3 or AAC audio.
PCR, PTS and DTS: keeping audio and video in sync
Synchronisation in a transport stream is clock-based, not offset-based. One PID (named by PCR_PID in the PMT) carries the Program Clock Reference in its adaptation fields: periodic samples of a 27 MHz reference clock that let the decoder reconstruct the encoder’s clock. Against that clock, each PES header supplies a PTS (presentation timestamp, when to display a unit) and, when decode order differs from display order because of B-frames, a DTS (decode timestamp). The decoder locks its local clock to the PCR, decodes each access unit at its DTS, and presents it at its PTS, which keeps a video frame and its audio aligned even though they arrived as separately interleaved packets. This is a fundamentally different model from MP4, where timing is stored once in sample tables that index absolute file offsets.
Why TS joins cleanly but seeks and edits poorly
Because a transport stream is just a sequence of self-contained 188-byte packets with periodic tables and clock references, two streams concatenate at a packet boundary and the result is still a valid stream. This is exactly how HLS works: a video is split into many short .ts segments listed in an .m3u8 playlist, and the player fetches and stitches them back together, switching bitrate at segment boundaries. Merging a folder of downloaded HLS segments is therefore a lossless copy, not a re-encode: ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4. The flip side is that TS has no central index, so precise seeking means scanning for the nearest random-access point, and the format is less convenient to trim, tag and share than a seekable container. When a .ts recording already holds H.264/AAC, the fast fix is a container swap into MP4 or MKV — ffmpeg -i in.ts -c copy out.mp4 — which rewrites the packaging into sample tables while copying the coded bitstream untouched.
FAQ
What is the difference between .ts and .m2ts?
Both are MPEG transport streams. Plain .ts uses 188-byte packets and is the broadcast/streaming form. .m2ts (BDAV, used on Blu-ray and by AVCHD camcorders) prepends a 4-byte arrival timestamp to each packet, making them 192 bytes; the AVCHD .mts from camcorders is the same BDAV structure. Players handle both, and either remuxes losslessly to MP4.
How do I convert a .ts recording to MP4 without quality loss?
If the stream already holds MP4-compatible codecs (H.264 video, AAC audio) it is a container swap, not a re-encode: ffmpeg -i in.ts -c copy out.mp4 copies the coded samples and rebuilds them as MP4 sample tables. Re-encoding is only needed if you want to trim, fix audio, or change codec.
My .ts file looks like source code, not video — why?
Then it is not a transport stream. The .ts extension is also used by TypeScript source code (and by Qt Linguist translation files). If the file is readable text with import, const or function in it, open it in a code editor such as VS Code, not a media player.
References
- ISO/IEC 13818-1 — MPEG-2 Systems (Transport Stream)
- Wikipedia — MPEG transport stream
- FFmpeg — documentation (remux / convert)
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.