diff --git a/container/mts/mpegts.go b/container/mts/mpegts.go index ed8cbe02..4d8ec4a8 100644 --- a/container/mts/mpegts.go +++ b/container/mts/mpegts.go @@ -33,6 +33,7 @@ import ( "fmt" "github.com/Comcast/gots/packet" + "github.com/Comcast/gots/pes" ) // General mpegts packet properties. @@ -315,3 +316,46 @@ func DiscontinuityIndicator(f bool) Option { p[DiscontinuityIndicatorIdx] |= DiscontinuityIndicatorMask & set } } + +// GetPTSRange retreives the first and last PTS of an MPEGTS clip. +func GetPTSRange(clip []byte) (pts [2]uint64, err error) { + // Find the first video packet. + pkt, _, err := FindPid(clip, videoPid) + if err != nil { + return [2]uint64{}, err + } + + // Get the payload of the packet, which will be the start of the PES packet. + var _pkt packet.Packet + copy(_pkt[:], pkt) + payload, err := packet.Payload(&_pkt) + if err != nil { + return [2]uint64{}, err + } + + // Get the the first PTS from the PES header. + _pes, err := pes.NewPESHeader(payload) + if err != nil { + return [2]uint64{}, err + } + pts[0] = _pes.PTS() + + // Get the final PTS and calculate PTS immediately after. + for i := len(clip) - PacketSize; i >= 0; i -= PacketSize { + copy(_pkt[:], clip[i:i+PacketSize]) + if packet.PayloadUnitStartIndicator(&_pkt) { + payload, err = packet.Payload(&_pkt) + if err != nil { + return [2]uint64{}, err + } + _pes, err = pes.NewPESHeader(payload) + if err != nil { + return [2]uint64{}, err + } + pts[1] = _pes.PTS() + return + } + } + + return [2]uint64{}, errors.New("could only find one access unit in mpegts clip") +}