Golang实现TS文件指标捕获的脚本工具

Golang实现TS文件指标捕获的脚本工具 我需要从TS视频文件中获取以下指标:

TS_sync_loss Sync_byte_error PAT_error PAT_error_2 Continuity_count_error PMT_error PMT_error_2 PID_error

我正在尝试使用以下包:

GitHub

Comcast/gots

Avatar

Comcast/gots

gots - Go语言中的MPEG传输流处理

是否有其他包或脚本来捕获上述指标?

谢谢


更多关于Golang实现TS文件指标捕获的脚本工具的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang实现TS文件指标捕获的脚本工具的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,使用Comcast/gots包可以有效地处理MPEG传输流(TS)并捕获所需的指标。以下是一个示例脚本,展示如何读取TS文件并检测您提到的各种错误类型。该脚本会解析TS包,检查同步字节、PAT表、PMT表以及连续计数错误等关键指标。

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/Comcast/gots"
	"github.com/Comcast/gots/packet"
	"github.com/Comcast/gots/psi"
)

func main() {
	// 打开TS文件
	file, err := os.Open("example.ts")
	if err != nil {
		log.Fatal("无法打开文件:", err)
	}
	defer file.Close()

	// 初始化统计变量
	var (
		tsSyncLoss        int
		syncByteError     int
		patError          int
		patError2         int
		continuityCountError int
		pmtError          int
		pmtError2         int
		pidError          int
	)

	// 创建包读取器
	packetReader := packet.NewReader(file)
	prevContinuity := make(map[uint16]uint8) // 存储每个PID的上一个连续计数

	// 解析PAT和PMT
	var pat psi.PAT
	var pmt psi.PMT
	patFound := false
	pmtFound := false

	for {
		pkt, err := packetReader.ReadNext()
		if err != nil {
			if err.Error() == "EOF" {
				break
			}
			log.Printf("读取包错误: %v", err)
			continue
		}

		// 检查同步字节错误
		if pkt[0] != packet.SyncByte {
			syncByteError++
			continue
		}

		// 检查TS同步丢失(基于连续包结构)
		if tsSyncLoss > 0 {
			tsSyncLoss++ // 示例逻辑,实际中需定义更复杂的检测
		}

		// 获取PID
		pid := packet.Pid(pkt)

		// 处理PAT(PID 0)
		if pid == 0 {
			patData, err := psi.PATFromBytes(pkt)
			if err != nil {
				patError++
			} else {
				if !patFound {
					pat = patData
					patFound = true
				} else {
					// 检查PAT一致性错误
					if !patEqual(pat, patData) {
						patError2++
					}
				}
			}
		}

		// 处理PMT(基于PAT中的程序映射)
		if patFound && pid == pat.ProgramMapPid() {
			pmtData, err := psi.PMTFromBytes(pkt, pid)
			if err != nil {
				pmtError++
			} else {
				if !pmtFound {
					pmt = pmtData
					pmtFound = true
				} else {
					// 检查PMT一致性错误
					if !pmtEqual(pmt, pmtData) {
						pmtError2++
					}
				}
			}
		}

		// 检查连续计数错误
		cc := packet.ContinuityCounter(pkt)
		if prev, exists := prevContinuity[pid]; exists {
			expected := (prev + 1) % 16
			if cc != expected {
				continuityCountError++
			}
		}
		prevContinuity[pid] = cc

		// 检查PID错误(例如未定义的PID)
		if !isValidPID(pid, pat, pmt) {
			pidError++
		}
	}

	// 输出捕获的指标
	fmt.Printf("TS_sync_loss: %d\n", tsSyncLoss)
	fmt.Printf("Sync_byte_error: %d\n", syncByteError)
	fmt.Printf("PAT_error: %d\n", patError)
	fmt.Printf("PAT_error_2: %d\n", patError2)
	fmt.Printf("Continuity_count_error: %d\n", continuityCountError)
	fmt.Printf("PMT_error: %d\n", pmtError)
	fmt.Printf("PMT_error_2: %d\n", pmtError2)
	fmt.Printf("PID_error: %d\n", pidError)
}

// 辅助函数:比较两个PAT是否相等
func patEqual(a, b psi.PAT) bool {
	// 简化比较逻辑,实际中需比较所有程序映射
	return a.ProgramMapPid() == b.ProgramMapPid()
}

// 辅助函数:比较两个PMT是否相等
func pmtEqual(a, b psi.PMT) bool {
	// 简化比较逻辑,实际中需比较所有元素流
	return a.PID() == b.PID()
}

// 辅助函数:检查PID是否有效
func isValidPID(pid uint16, pat psi.PAT, pmt psi.PMT) bool {
	// 示例逻辑:仅检查PID 0(PAT)和PMT PID
	if pid == 0 || (pat != nil && pid == pat.ProgramMapPid()) {
		return true
	}
	// 实际中应扩展以包括PMT中的所有元素PID
	return false
}

说明:

  • TS_sync_loss:通过检查连续包的同步字节来检测,示例中使用了简单计数器,实际应用可能需要更复杂的逻辑(如基于时间间隔)。
  • Sync_byte_error:直接检查每个包的同步字节(0x47)。
  • PAT_error:在解析PAT表时捕获错误(例如CRC错误或格式无效)。
  • PAT_error_2:比较多个PAT实例以检测不一致性。
  • Continuity_count_error:跟踪每个PID的连续计数,检查是否按预期递增。
  • PMT_error:在解析PMT表时捕获错误。
  • PMT_error_2:比较多个PMT实例以检测不一致性。
  • PID_error:验证PID是否在PAT或PMT中定义(示例中仅检查基本PID,实际中需扩展)。

这个脚本使用了gots包的核心功能,包括包解析、PAT/PMT处理以及错误检测。您可以根据实际TS文件调整逻辑,例如通过扩展isValidPID函数来覆盖所有有效的PID。运行前,请确保使用go mod init初始化模块并添加require github.com/Comcast/gots v0.0.0到您的go.mod文件(具体版本请查看GitHub仓库)。

对于更高级的指标,您可以参考gots文档或结合其他库(如github.com/asticode/go-astits用于更详细的解析),但gots已覆盖了大部分基本需求。

回到顶部