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
我正在尝试使用以下包:
Comcast/gots
Comcast/gots
gots - Go语言中的MPEG传输流处理
是否有其他包或脚本来捕获上述指标?
谢谢
更多关于Golang实现TS文件指标捕获的脚本工具的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于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已覆盖了大部分基本需求。

