简介面向数字电视/DVB开发者的TS码流分析实用工具以Tree视图直观显示PAT、PMT、SDT、EIT及Subtitle的PES包结构帮助初学者通过实例快速掌握TS封装与SI/PSI信息组织方式。它同样适用于运维和高频排查码流问题的技术支持场景既能用于学习也能辅助日常调试。相比常见分析软件它额外解析LCN和Subtitle数据支持Subtitle图片仿真显示、搜台过程模拟与EPG仿真展示双击EIT也可将全部表导出为parsing_result.html便于复盘比对。解析完成后还可将PAT、PMT、SDT、NIT等表一键存成HTML网页统一核对更为方便。Tree结构与SI包的数据结构一一对应双击Subtitle的PES节点即可在右侧显示字幕图片双击EIT中的eventid还能弹窗查看该事件详细数据解析时也不受码流大小限制。资源包共30个文件约161KB内含可直接运行的exe、供查看结果的HTML页面、Tree控件相关JS脚本、Event.c源码文件及24张界面/树形节点示意GIF图片适合边看效果边对照代码理解TS解析逻辑。已有1911人学习/下载尤其适合刚接触DTV的新人和需要排查码流问题的工程师能快速建立完整认知少走弯路。1. 一个好的码流分析软件能让你少熬三个夜做流媒体开发的人多半经历过这种深夜画面卡成PPT抓回来的码流用十六进制编辑器打开满眼0x47后面全是陌生字节PAT、PMT、PES的概念背得头头是道却连哪个PID丢了都定位不了。其实问题不在你而在缺一个能把TS结构剥开的码流分析软件ts analysis tool——它能把传输流拆成一张张可读的表PAT、PMT、SDT、PES、PCR告诉你音视频在哪、丢没丢包、时间戳跳没跳。这篇不带你背协议文档而是从生成一段.ts文件开始一路玩到能独立排障适合流媒体开发、播放器调试、安防对接以及想彻底搞懂.ts分片结构的同学。2. 先搞到一段真实TS码流三种样本来源与一条生成命令2.1 没有素材用ffmpeg几秒生成一个标准的.ts文件最常见也最可控的做法是自己用ffmpeg把任意本地视频重新封装成TS命令只有一行ffmpeg -i input.mp4 -c copy -f mpegts -mpegts_flags resend_headers output.ts-c copy是关键意思是只重新封装、不重编码几秒钟完成而且视频编码参数和你原来的MP4完全一致便于后续在分析工具里看到熟悉的H.264/H.265 Profile。如果没有本地MP4也可以去网上抓一段公开视频转但可能会被转码结构变成SEI等新手会多看到一些干扰项。-mpegts_flags resend_headers是让ffmpeg周期性重发PAT/PMT表这样分析工具在流的中间也能找到节目信息播放器也不会因为只出现一次PAT而黑屏。另一个更真实的来源是直接从HLS地址里抓一段.ts分片。开发者抓取视频时最常见的问题就是把M3U8里的分片下载下来后用播放器一打开就卡住然后怀疑分片损坏。实际上分片开头PAT/PMT往往只出现一次很多播放器从中间插入就会等不到表这时候用分析工具能看到“PAT/PMT only at beginning”之类的提示。curl -O https://example.com/segment_0001.ts这样拿到的分片通常只有6到10秒非常适合新手做结构拆解。它比自造TS多了真实网络分片的割裂感PES头可能没有严格对齐到帧边界时间戳也可能在新分片里清零。这些在后面的避坑章里都会遇到。2.2 抓UDP组播流真实场景里码流的常见来源在广电、安防、IPTV项目里TS往往不是文件而是UDP或RTP组播流。这时就必须用wireshark抓包。常见做法是先在网卡上抓一段时间过滤条件是udp.dstport 1234 ip.addr 239.1.1.1然后通过wireshark的“导出原始载荷”把UDP payload存成二进制文件。注意如果源是RTP封装导出的payload是RTP载荷它不保证TS包边界对齐。因为TS包固定188字节一个RTP包可能只装一部分TS数据也可能一个RTP包里有多个TS包。这时不能直接按188字节切否则分析工具会疯狂报同步错误。更稳妥的做法是先用工具自动搜索0x47同步或者用tsduck的-I rtp方式直接读UDP流让它自己处理RTP头。抓包过程有个血泪经验不要用笔记本自带的WIFI网卡抓组播很容易漏包。要指定有线口并开启混杂模式。抓包时长建议20秒以上因为如果只抓2秒刚好错过PAT/PMT和PCR分析结果没有任何参考意义。tcpdump -i eth0 -s 0 -w ts.pcap udp port 1234tcpdump抓下来的pcap后续可以直接用tsduck的-I ip插件读取也可以导出为裸TS。这个流程解决了很多“线上码流正常本地却复现不了”的问题抓的是原始报文不是播放器转存的TS。2.3 验证样本是不是真TS十秒检查法拿到TS文件后第一步不是丢进分析工具而是先验证它到底是不是TS很多“分析工具报错”其实是文件本身是MP4改了后缀。先用ffprobe验证ffprobe -v error -show_entries streamindex,codec_type,codec_name -of csv output.ts正常输出类似0,video,h264 1,audio,aac如果输出“Invalid data found”那多半是假TS。也可以用xxd快速看结构xxd -l 48 output.ts如果0x47每隔0xbc188出现一次基本可以认为包对齐。另一种情况是TS带RS纠错每包204字节此时0x47间隔是0xcc。你需要告诉分析工具“Packet size204”否则它会看到大量同步丢失误以为文件损坏。这一步很重要因为后续所有PID统计、PCR检查都建立在包对齐的前提上。包没对齐工具会自己重新找同步但丢失最前面的几十个包导致连续性检查结果全是假的。我一般在任何分析之前都先跑这10秒检查省掉很多后续的翻车。3. 用 ts analysis tool 拆开TS包三张表看清全部结构3.1 TS包定长188字节同步头、PID、适配字段TS包固定188字节由4字节头部和184字节载荷组成。头部第1字节必须是0x47第2到第3字节里藏着13位PID第4字节的低4位是连续计数器continuity_counter。分析工具做的事本质就是按188字节切包、读PID、再根据PID解析不同表。当分析工具显示“同步丢失”时不要急着怀疑工具。先确认文件是不是TS、包长是不是188/204。我曾经被一个带204字节纠错的录播文件误导工具里显示每隔一会儿就有丢同步其实是因为按188切包后把每包末尾的16个RS校验字节当成了下一包的头部自然找不到0x47。PID列表是分析工具的首页信息每个PID的出现次数、首次出现位置、最后出现位置都会被统计。PID 0x0000一定是PAT0x0011是SDT0x0012是EIT音视频PID则是由PMT表动态告诉你的。只看一次PID列表你就能判断这个TS是不是多重节目如果有好几个PID都在跑而且PAT里有多个节目号说明是复用了一整条节目流。3.2 用ffprobe快速看PID、时长和音视频编码ffprobe是FFmpeg家族里的探测工具虽然它不是专门的TS分析软件但对“这文件是什么编码、有没有音轨”的判断非常快ffprobe -show_packets -read_intervals %#20 -show_data output.ts-read_intervals %#20表示只分析前20秒-show_data会打印载荷能直接看到PES头和H.264的00 00 01起始码。输出里会列出每个包的pid、pos、dts、pts、sizepacket: pos376 bytes188 flagsK__ pid0x0101 dts3600 pts3600newffprobe对PES层显示到包粒度但不会直接告诉你“PID 0x0101是视频”还是“音频”。不过我们能从dts/pts增长规律猜出来25fps视频每个PES间隔约40ms音频间隔更密集。如果要看PAT/PMT到底写了什么还得换tsduck这类TS专用分析工具。3.3 PAT/PMT/SDT三张表的关系先有PAT再有PMTTS结构里最核心的是三张表。PATProgram Association Table固定挂在PID 0x0000上它只做一件事告诉解析器“节目号1对应的PMT在PID 0x0100”。PMTProgram Map Table里才是真正的内容清单这个节目包含哪些流每个流的PID和编码类型是什么。SDTService Description Table在PID 0x0011上提供节目名、服务商等附加信息排障时用得少。用tsduck的分析插件可以直观看到这三层tsp -I file output.ts -P analyze -O drop输出大致是PAT: Program 1: PMT PID 0x0100 PMT: Stream 0x0101: H.264/AVC video, type 0x1B Stream 0x0102: AAC audio, type 0x0F这就是整个TS结构的骨架。视频PID和音频PID不是写死在解码器里的而是通过PAT找到PMT再从PMT里查出来。所以任何TS分析工具第一步都要先解析PAT否则后面全是盲猜。在避坑章里会提到很多黑屏问题就是PMT信息缺失导致的。表名PID作用关键字段PAT0x0000节目号到PMT PID的映射program_number, PMT_PIDPMT从PAT获取流类型到PID的映射stream_type, elementary_PIDSDT0x0011服务描述服务名、服务提供商PES音视频PID音视频访问单元PTS/DTS, stream_id3.4 PES拿到之后时间戳、帧边界和关键参数TS包载荷里装的数据分裂再拼起来就是PES包。视频PES通常包含一个视频访问单元也就是一帧音频PES可能包含若干帧。分析工具在这一层能显示PTS/DTS这是判断音画同步的最重要原始数据。用tsduck的PES插件或者直接看ffprobe的pts字段。视频25fps时PTS增量大概是40ms30fps是33.3ms音频则看采样率。如果PTS序列出现大跳变比如从36000直接跳到190000说明码流里有拼接、GOP被修剪或者分片边界没有连续性。.ts分片在拼接分析时经常出现这类提示但播放器本身又能播因为多数播放器会在分片边界重置时间轴。分析工具和播放器的容忍度不同所以解读输出时要带着场景。PCRProgram Clock Reference往往在音视频PID之一里或者单独的PID。它用来给解码器恢复27MHz时钟分析工具能算出每次PCR插入的间隔。正常PCR间隔应该在40ms以内超过100ms很多播放器就会出现音画不同步。第4章会专门讲怎么设置阈值因为默认情况下不少工具只显示、不报警。4. ts analysis tool的必调参数不设对分析结果会骗你4.1 连续性检查不开等于只看结构不看健康度很多通用播放器工具默认只解析帧不检查连续计数器。连续计数器是每个PID内部4bit计数从0到15循环。每收到一个该PID的TS包计数器加1。如果解析器发现某个PID的CC从5直接跳到8说明中间丢了2个包。这是检测UDP丢包最有效的手段。tsduck里打开连续性检查tsp -I file output.ts -P continuity -O drop输出样例PID 0x0101, packet 1234: continuity error, expected 5, got 8注意一个细节只有承载载荷的包CC才会递增。如果包只有适配字段比如PCR单独占用一个适配字段包那么CC不递增。分析工具如果没考虑这点就会误报。我碰到过一次某个编码器每隔一段距离插一个纯PCR适配包tsduck默认处理是对的但一些自制脚本没判断adaptation_field_control把CC不递增全算成了丢包。如果CC错误集中出现在特定PID而其他PID正常说明丢包和这个PID的码率或发送时刻有关。如果所有PID都跳大概率是抓包网卡丢包不是码流问题。判断方法就是关掉网卡收包卸载功能再抓一次。4.2 PCR间隔分析音画不同步的暗礁PCR是TS分析工具里最值得调的一个参数。默认的pcr插件会输出每个PCR的间隔但不会主动告诉你“这个间隔是不是太长”。在命令行里加阈值tsp -I file output.ts -P pcr --max-interval 40 -O drop--max-interval 40表示超过40ms就报警。为什么是40因为25fps视频一帧正好40msPCR插入间隔超过一个帧周期解码器恢复出来的时钟就开始抖。对于一些码率高的流PCR间隔稍大也能忍所以我一般会用100ms做宽放阈值定位“偶尔音画不同步”时再收紧到40ms。PCR位于哪个PID也很关键。PMT里会有PCR_PID声明。如果PCR_PID指向视频PID或音频PID解码器会跟着该流的时间戳走如果声明了一个单独的数据PID那这个PID必须定期出现。用tsduck的-P analyze能看到PCR PID: 0x0101这类信息。PCR间隔分析最怕遇到没有PCR的TS流这时解码器会退化为“音频为主时钟”视频帧率稍微波动就会出现音画漂移。工具不会把这种流标错但如果配了检查参数会提示“PCR not found”。4.3 PTS连续性窗口时间戳偏差的报警阈值PTS是播放器真正用来做音画同步的但在1分钟以上的文件里PTS会和PCR有累积偏差。比如PCR稳定PTS却每隔十几秒慢一点说明编码器生成PTS时参考时钟不精确。tsduck的-P pts插件可以限制PTS与PCR的最大偏差tsp -I file output.ts -P pts --max-pcr-pts-offset 100 -O drop超过100ms就告警。这个参数在做Android播放器时很实用Media3 ExoPlayer播同一个.ts分片有时只在特定片段出现音画异步工具正好在对应位置报PTS/PCR偏差过大。把这段流的PCR、PTS列出来比对往往能看到某个B帧顺序异常或Temporal Reference错乱。这类问题靠看播放器日志很难定位靠分析工具的阈值报警就容易得多。对于.ts分片拼成的长文件PTS经常在新分片起始处不再连续这是因为HLS分片的编码器或切片器重置了时间戳。此时--max-pcr-pts-offset会误报。可以按分片单独分析或者设置工具忽略分片边界。分析工具的输出只是一组告警我们要按场景判断是不是真故障而不是见错就改。4.4 常用参数速查表参数作用建议值continuity检测连续计数器丢包开pcr.max-intervalPCR最大插入间隔40~100mspts.max-pcr-pts-offsetPTS与PCR最大偏差100msanalyze.仅前N包快速结构判断1000包我一般的分析套路是先前1000包看结构再整段扫连续性最后由具体告警位置反查PCR/PTS。如果一开始就用全量输出几十万行日志只会把真正的问题淹没。5. TS分析避坑5个翻车现场与对应的排查手段5.1 PAT/PMT只在开头出现播放器黑屏工具却显示结构完整现象抓回来一段TSts analysis tool显示PAT/PMT都有PID列表正常但Android播放器加载后黑屏进度条一点不动。原因工具从文件开头解析在最初的几百包看到PAT/PMT就判定“有”但后续不再重复。播放器从流中任意位置进入等不到新的PAT/PMT就会判定没有节目。解决检查PAT/PMT重复周期ffmpeg封装时一定要加-mpegts_flags resend_headers编码器里PAT/PMT间隔不要超过100ms。一个好的分析工具应该能显示PAT出现次数而不是只判断“有没有”。5.2 CC连续但播放花屏抓包阶段就已经错了现象分析工具没有报CC丢失画面却花屏。原因网卡上TSO/GRO把UDP包重组了wireshark导出的payload里少了某些尾部数据但TS包又被巧合对齐CC计数器看起来连续。这是抓包环境造成的黑匣子。解决抓包前关掉网卡的校验和卸载和分片卸载Linux下命令是ethtool -K eth0 rx off tx off然后重新抓包再用ffprobe验证一次能正常解出视频帧。如果CC没错误但视频解码失败优先怀疑抓包链路而不是直接追编码器。5.3 PCR间隔忽大忽小音画不同步就是它现象分析工具报PCR间隔从30ms跳到200ms播放器表现偶发音画不同步。原因编码器插入PCR的时机不固定或者复用器没有把PCR适配包放在音频/视频包之前。解决用pcr插件看PCR间隔的直方图如果最大值超过100ms且集中在I帧附近说明PCR被大包挤占常见的补救措施是调整复用器buffer或让编码器专门单独发送PCR包。实测中最有效的一招是把PMT里的PCR_PID指定到固定间隔的专用PID代价是占用一点带宽但音画同步稳定性会好很多。5.4 PTS回绕被当成不连续跨分片误报要冷静现象分析工具对一段6小时TS的尾部报“PTS discontinuity”播放器却完全正常。原因PTS是33bit计数约26.5小时回绕一次回绕点附近工具会看到从巨大数值直接掉到0的伪跳变。另外HLS分片边界经常不保证PTS连续分析工具把多个分片拼在一起扫的时候也会误报。解决分析工具要能识别回绕比如把PTS差值按无符号数计算分析分片长流时最好按分片边界分开。我处理这种问题的方法是先看告警处前后几十个包的PTS序列如果它是从0x1FFFFFFFF滚回0x0那就是回绕不是故障。5.5 私有流和加密流工具只能分析到传输层现象分析工具到了某个PID显示“unknown”PES长度超长或全是0xFF。原因该PID承载的是条件接收加密流或工程私有数据stream_type经常是0x06private dataPES层被加密工具没有密钥自然解不开。解决先从PAT/PMT找到stream_type和CA描述符。如果确认是加密流就看它的CC是否连续、PCR是否正常传输层健康就算合格私有流则需要核对CA私有描述符。很多开发者第一次碰到这种流以为分析工具有bug其实换谁都没法在不脱壳的情况下解析载荷。分析工具在这时候更像一个“传输层体检仪”而不是破解工具。6. 进阶写一个几十行的PID统计脚本把TS分析固化到工程里6.1 一个不依赖第三方库的TS快速体检脚本前面用现成工具最后提倡自己写一个极简脚本因为把“读TS包结构”这个动作变成代码才算真正掌握了TS结构。下面这份Python脚本只做三件事统计PID、统计同步丢失、统计连续计数器跳变。import sys import collections def analyze_ts(filename): with open(filename, rb) as f: data f.read() pids collections.Counter() cc_seen {} cc_errors 0 sync_errors 0 pos data.find(b\x47) # 找第一个同步字节 while pos ! -1 and pos 188 len(data): if data[pos] ! 0x47: # 理论不会触发防御性判断 sync_errors 1 pos data.find(b\x47, pos 1) continue pid ((data[pos 1] 0x1F) 8) | data[pos 2] afc (data[pos 3] 4) 0x03 cc data[pos 3] 0x0F has_payload afc in (0b10, 0b11) if has_payload: if pid in cc_seen and cc ! (cc_seen[pid] 1) % 16: cc_errors 1 cc_seen[pid] cc pids[pid] 1 pos 188 print(fPID count: {len(pids)}) for pid, cnt in sorted(pids.items()): print(f PID 0x{pid:04X}: {cnt} packets) print(fSync errors: {sync_errors}) print(fCC errors: {cc_errors}) if __name__ __main__: analyze_ts(sys.argv[1])代码逻辑不复杂找到0x47后按188字节前进从头部提取PID和连续计数器。只有在包真正携带载荷时CC才递增所以用afc in (0b10, 0b11)过滤。如果同一PID的CC没有按步进1走说明该PID的包在这段流里有丢失或乱序。CC的错误统计比同步错误更敏锐因为TS同步检测只能看到边界错乱而CC能看到包级别的空洞。这个脚本可以直接配合命令行自动跑python ts_check.py output.ts输出PID count: 5 PID 0x0000: 120 packets PID 0x0100: 240 packets PID 0x0101: 6120 packets PID 0x0102: 2040 packets Sync errors: 0 CC errors: 0把这段脚本丢进CI每次新版本码流生成后自动跑一遍比每次手动用GUI工具快得多。如果需要分析PAT/PMT的具体映射脚本里再加一段解析PAT包的逻辑也不难但那是另一个层次的事。我现在接手任何陌生TS习惯永远是先跑这个体检脚本确认包对齐和CC无错后再拿tsduck看PAT/PMT和PCR/PTS。这个习惯帮我避开了很多假故障也希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
模型突破安全边界与全球AI监管收紧下的开发者应对指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 22:36:54
B站UID成分分析工具原理与实现:基于公开API的行为建模 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 22:36:47
OpenClaw 安装与卸载全流程:从 ollama、node.js 到 TaoToken 配置实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 23:23:27
产品外包装设计网站从零搭建成本拆解,告别模板尴尬 产品外包装设计网站从零搭建成本拆解,告别模板尴尬 很多做包装设计的朋友,第一眼看到市面上那些千篇一律的模板网站,心里都在打鼓: 模板网站太丑,完全不够用。… · 2026/9/26 23:23:27
Kimi Code没有官方桌面客户端:插件形态才是正确打开方式 1. 先把问题说清楚:Kimi Code 到底有没有官方桌面客户端先把结论摆在最前面,省得你翻半天:Kimi Code 目前没有独立的官方桌面客户端。你在搜索引擎里看到的“kimi code桌面客户端上线”“kimi code下载”这类词,绝大多数是第三方整… · 2026/9/26 23:23:21
做网站和维护网站:3步搞定性能优化,避开高价坑 做网站和维护网站:3步搞定性能优化,避开高价坑 找建站公司最怕什么?不是功能做不出来,而是后期维护像无底洞,性能优化还得加钱。很多老板花几万块做了个站,打开速度像蜗牛,想优化一下,客服回复“那是高级服务,另收费”。这种“高价坑”在行业里太常… · 2026/9/26 23:23:21
Code With Mosh MySQL课程文件包:生产级SQL工程训练套件 简介:本资源是面向SQL初学者与数据库入门学习者的MySQL系统课程配套资料包,聚焦数据库建表、数据操作与查询优化等核心能力训练。压缩包共9个文件,含5份PDF讲义(涵盖逻辑模型设计、项目实战文档及性能调优指南)、3个可… · 2026/9/26 23:23:21
新手入门必看:网站关键词百度自然排名优化实操指南 新手入门必看:网站关键词百度自然排名优化实操指南 域名和服务器配置一团糟,代码结构混乱不堪,这是绝大多数 新手入门 建站时最容易踩的坑。很多老板以为只要花钱推广,百度排名就能上去,结果发现钱花了,排名纹丝不动,甚至网站还被百度收录了垃圾信息… · 2026/9/26 23:23:14
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46