The problem background

We found a special kind of M3U8 video when we used ExoPlayer to play videos, which always failed. And the following error is reported:

ExoPlayerImplInternal: Source error. 
com.google.android.exoplayer2.ParserException: Cannot find sync byte. Most likely not a Transport Stream. 
at com.google.android.exoplayer2.extractor.ts.TsExtractor.read(TsExtractor.java:260) 
at com.google.android.exoplayer2.source.hls.e.f(HlsMediaChunk.java:284) 
at com.google.android.exoplayer2.source.hls.e.load(HlsMediaChunk.java:209) 
at com.google.android.exoplayer2.upstream.Loader$a.run(Loader.java:330) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
at java.lang.Thread.run(Thread.java:919) 
Copy the code

This seems to be a native problem in ExoPlayer, so we quickly found the source code for ExoPlayer:

Github.com/google/ExoP…The native error was found, but we still need to address the following issues:

  • What about the TS format?
  • Why did ExoPlayer change this way?
  • What is the right way to modify?

TS format parsing

A normal TS Packet is 188 bytes, and its hierarchical results are as follows:

The name of the digits note
sync_byte 8b Synchronization byte, fixed to 0x47
transport_error_indicator 1b A transmission error indicator indicating that the adapt field in ts header is followed by a useless byte, usually 0, that counts in the length of the ADAPT field
payload_unit_start_indicator 1b Load unit start identifier. A complete packet starts with a mark of 1
transport_priority 1b Transmission priority: 0 indicates the low priority, and 1 indicates the high priority
pid 13b The pid value
transport_scrambling_control 2b Transmission interference control, 00 indicates unencrypted
adaptation_field_control 2b Whether to include adaptive zone, ’00’ reserved; ’01’ is no adaptive domain and contains only payload; ’10’ means only adaptive domain and no payload; ’11’ means with both adaptive domain and payload.
continuity_counter 4b Increments the counter from 0 to f, not necessarily starting at 0, but must be continuous

It has been specified that the size of each TS Packet is 188 bytes. The important mark to identify the size of TS Packet is the read sync_byte bit. The distance between the two sync_bytes is 188 bytes, indicating that it is a standard TS format. However, some of the standards formulated comply with the standards, and some do not necessarily comply with the standards. What about non-compliance with standards that actually occur? The reason ExoPlayer failed to play this video is because the video source did not follow the 188-byte TS Packet size rule. This error is embarrassing. It violates the standard, but its first 188 bytes are standard TS data. Let’s first trace the cause of the change in ExoPlayr.

The reason ExoPlayer is modified in this way

First put two source code modification links: github.com/google/ExoP… Github.com/google/ExoP…

According to the comment, Google didn’t think it was necessary to wait for TS_SYNC_BYTE to load each time, but they were obviously afraid that the current TS stream wasn’t standard, so they added a bottom line. If TS_SYNC_BYTE was not found in two 188-byte readings, Note The current high probability is not the TS stream format. There is nothing wrong with such a judgment in terms of standards.

What should we do

We have a failure like this, so there are two options, right?

  • Advise the M3U8 provider that it is best to modify the internal TS format to make it conform to the standard.
  • Customize the ExoPlayer source code to accommodate this exception type.

The first difficulty may point high, not realistic, after all, let the service side to change things for you, the person is not too reason. Then the player has to adapt. Is there any problem with the player removing this check? From the analysis of TS format, this modification is not perfect, but from the bottom of the player processing, it is basically no risk. Because the worst that can happen is that it fails. There’s a plan in place. It shouldn’t be a problem. When standards are set, there are always people who don’t follow them.