问题背景
我们在使用ExoPlayer播放视频的视频发现一种特殊的M3U8视频,播放总是失败。
而且报如下的错误:
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)
复制代码
这样的报错似乎是ExoPlayer的原生问题,我们赶紧找到ExoPlayer的源码:

github.com/google/ExoP…
原生报错的地方找到了,但是接下来我们还需要解决下面几个问题:
- TS格式是怎么样的?
- ExoPlayer为什么要这样修改?
- 正确的修改方式是什么样的?
TS格式解析

正常的TS Packet是188字节,其层次结果如下:
| 名称 | 位数 | 备注 |
|---|---|---|
| sync_byte | 8b | 同步字节,固定为0x47 |
| transport_error_indicator | 1b | 传输错误指示符,表明在ts头的adapt域后由一个无用字节,通常都为0,这个字节算在adapt域长度内 |
| payload_unit_start_indicator | 1b | 负载单元起始标示符,一个完整的数据包开始时标记为1 |
| transport_priority | 1b | 传输优先级,0为低优先级,1为高优先级,通常取0 |
| pid | 13b | pid值 |
| transport_scrambling_control | 2b | 传输加扰控制,00表示未加密 |
| adaptation_field_control | 2b | 是否包含自适应区,‘00’保留;‘01’为无自适应域,仅含有效负载;‘10’为仅含自适应域,无有效负载;‘11’为同时带有自适应域和有效负载。 |
| continuity_counter | 4b | 递增计数器,从0-f,起始值不一定取0,但必须是连续的 |
已经规定好了每一个TS Packet大小是188字节,识别TS Packet大小的重要标志是读sync_byte位,两个sync_byte之间相距188字节,说明它是标准的TS格式。
但是,制定的标准,有的遵守标准,有的不一定遵守标准。真的发生的标准不遵守怎么办?
这次ExoPlayer发生播放这样视频失败的原因,就是因为视频源没有遵守TS Packet大小为188字节的规则,这样的错误很尴尬,它违反了标准,但是它前188字节是标准的TS数据。
我们先追踪一下ExoPlayr这段修改的原因。
ExoPlayer这样修改的原因
先放上两个源码修改链接:
github.com/google/ExoP…
github.com/google/ExoP…


从注释来看,google觉得每次加载不一定要等到TS_SYNC_BYTE才算加载成功,但是他们显然又怕当前不是标准的TS流,就加了一个兜底,要是当前读到的位置超过两个188字节还是没有发现TS_SYNC_BYTE,说明当前大概率不是TS流的格式。
这样的判断在标准上而言是没有什么问题的。
我们应该怎么改
我们遇到这样的播放失败,只能采用两种办法了?
- 向M3U8的提供方提意见,最好修改一下TS内部格式,让其符合标准。
- 定制化修改ExoPlayer源码,适配这种异常的类型。
第一种难度可能要点高,不太现实,毕竟让服务方给你改东西,人接不太原因。那就只好播放器去适配,播放器将这个校验去掉有没有问题?
从对TS格式分析来看,这样的修改不太完美,但是从播放器的兜底处理来看,这样的处理基本没有风险。因为最坏的结果就是播放失败。已经有兜底方案了,应该没有问题。
制定了标准,总有人不去遵守。


















![[02/27][官改] Simplicity@MIX2 ROM更新-一一网](https://www.proyy.com/wp-content/uploads/2020/02/3168457341.jpg)


![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)