Code Monkey home page Code Monkey logo

gots's Introduction

Go Reference Build Status Go Report Card Coverage Status

goTS (Go Transport Streams)

gots (Go Transport Streams) is a library for working with MPEG transport streams. It provides abstractions for reading packet information and program specific information (psi)

Bug / Feature Reporting

Add requests to Github issues. To submit a PR see CONTRIBUTING

Tests

go test -race ./...

Travis-CI will run these tests:

go test -v ./...

License

This software is licensed under the MIT license. For full text see LICENSE

Code of Conduct

We take our code of conduct very seriously. Please abide by it.

Examples

This is a simple example that extracts all PIDs from a ts file and prints them. CLI example parser can be found here

func main() {
	pidSet := make(map[uint16]bool, 5)
	filename := "./scenario1.ts"
	file, err := os.Open(filename)
	if err == nil {
		pkt := make([]byte, packet.PacketSize)
		for read, err := file.Read(pkt); read > 0 && err == nil; read, err = file.Read(pkt) {
                        if err != nil {
                                println(err)
                                return
                        }
			pid, err := packet.Pid(pkt)
			if err != nil {
				println(err)
				continue
			}
			pidSet[pid] = true
		}

        	for v := range pidSet {
	        	fmt.Printf("Found pid %d\n", v)
	        }
	} else {
		fmt.Printf("Unable to open file [%s] due to [%s]\n", filename, err.Error())
}

gots's People

Contributors

alextarasov1 avatar blakeorth avatar cveazey avatar davemt avatar eric avatar guygrigsby avatar ianeckart avatar ieckart avatar igilham avatar jdeisenh avatar jessejlt avatar jheitz200 avatar kortschak avatar laba2346 avatar levizhao avatar limitlessearth avatar michaelhedrick avatar mikereedell avatar morrowa avatar nehashanbhag avatar paulboschert avatar rachelding avatar shanbhagneha avatar stephenwithav avatar stilldavid avatar tmm1 avatar willgunther avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gots's Issues

packet: Sync potentially double buffers

The Sync function requires that the input reader be a *bufio.Reader. This is to allow confirmation of the following sync byte. In some cases (when the reader is already read into a []byte, this requires double buffering and will have a significant impact on performance (e.g. in IoT use cases).

The problem can be fixed by performing type-conditional work with the provided io.Reader io.ByteScanner; in the case that the io.Reader is only an io.Reader document that the follow-up packet cannot be confirmed and just sync to the sync byte. If it is a Peeker, use that in the approach currently used. In the case that it is an io.ByteScanner iterate the bytes, reading until PacketLength and unreading when the sync byte is found.

[edit: cannot be a pure io.Reader under any circumstance]

Improve docs

The go docs are pretty sparse. They need to be reviewed and improved to include more specifics on what functions do and any side effects. Also, we make a number of references to byte slices and those should probably be made more clear by using packet.Packet.

runtime panics in psi

panic: runtime error: index out of range [2] with length 2

goroutine 180 [running]:
github.com/Comcast/gots/psi.sectionLength(...)
	github.com/Comcast/[email protected]/psi/psi.go:74
github.com/Comcast/gots/psi.SectionLength(...)
	github.com/Comcast/[email protected]/psi/psi.go:60
github.com/Comcast/gots/psi.pat.NumPrograms(0xc0024e60c4, 0xb8, 0xb8, 0x6ed1c5)
	github.com/Comcast/[email protected]/psi/pat.go:77 +0xa6
github.com/Comcast/gots/psi.pat.ProgramMap(0xc0024e60c4, 0xb8, 0xb8, 0x0)
	github.com/Comcast/[email protected]/psi/pat.go:97 +0x74
panic: runtime error: index out of range [10] with length 10

goroutine 182 [running]:
github.com/Comcast/gots/psi.(*pmt).parsePMTSection(0xc004d1a000, 0xc0012af9d4, 0xa, 0x234, 0xc004c5d1a0, 0x6f037f)
	github.com/Comcast/[email protected]/psi/pmt.go:126 +0x7d1
github.com/Comcast/gots/psi.(*pmt).parseTables(0xc004d1a000, 0xc0012af700, 0x2e0, 0x508, 0x508, 0x0)
	github.com/Comcast/[email protected]/psi/pmt.go:106 +0x10c
github.com/Comcast/gots/psi.NewPMT(0xc0012af700, 0x2e0, 0x508, 0x4, 0x0, 0x0, 0x0)
	github.com/Comcast/[email protected]/psi/pmt.go:92 +0x69

packet: tests ignore errors in set up

In #97 I found that the test was failing got go1.9 or lower, but not above. I tracked this down to a failure of the set up to provide an non-empty input string because hex.DecodeString was given an odd-length string. The call to hex.DecodeString in the tests in "io_test.go" ignore the "error" returned allowing this kind of test corruption.

Reconcile the two versions of `adaptationfield.go`.

There are two files that deal with AdaptationFields:

  • packet/adaptionfield.go: This one feels like the "right" one to use.
  • packet/adaptationfield/adaptationfield.go: This one uses the older functional style.

I propose removing the packet/adaptationfield/adaptationfield.go file in favor of packet/adaptationfield.go as long as the functionality is the same and anything that is missing from packet/adaptationfield.go is filled in.

PSI interface and PMT parser assume single "Program Map" section

psi.TableID() and psi.SectionLength() assume that each PSI packet only contains one section, but in fact there can be multiple. See for instance https://en.wikipedia.org/wiki/Program-specific_information#Table_Sections, which states that after the pointer field, section headers are "repeated until the end of the TS packet payload".

Specifically, on streams from Comcast and other cable providers, tables 0xc0 and 0xc1 may be present in the PMT pid's packets (see "SCTE specific tables" on https://en.wikipedia.org/wiki/Program-specific_information#Table_Identifiers).

I'd like to open a PR to fix this, but I'm curious if I can change the implementations of TableID and SectionLength, or if you would prefer to keep them as-is for backwards compatibility for any existing users of the public API?

Move CLI helpers into package(s) to be part of API

There are a few helpers in the parsefile cli example that would be useful if made available as part of package(s) rather than just the cli program. For example, sync function, and functions to read PAT/PMT. I think they are general enough (with a couple of tweaks) that it could save from people needing to repeat those bits of code.

Proposal: Please start using Semantic Versioning

I found that this project already supports Go modules. But sadly, the tags doesn't follow Semantic Versioning, which means that all tags of this project will be ignored by Go modules and replaced by pseudo-versions, go get acts weirdly when tags are not in that form. It would be great to have the tagged release be named in the format vX.X.X format so that go mod can read it.

	github.com/Comcast/gots v0.0.0-20200213175321-9799558ed3e2

Else the mod file shows something like github.com/Comcast/gots v0.0.0-20200213175321-9799558ed3e2 which is not very readable and difficult to upgrade. Itโ€™s hard to verify which version is in use. This is not conducive to version control.

So, I propose this project to follow Semantic Versioning in future versions. For example, v1.0.1, v2.0.0, v3.1.0-alpha, v3.1.0-beta.2etc.

packet.PESHeader returns the entire packet payload.

The function packet.PESHeader is supposed to return just the header for the PES, not the entire packet payload:

Example code:

payload, _ := packet.Payload(pkt)
fmt.Printf("payload start payload: \n%X\n", payload)

pesHeader, _ := packet.PESHeader(pkt)
fmt.Printf("pes header: \n%X\n", pesHeader)

Output:

payload start payload:
000001BD0C32808005210001C55B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111110101249210124921012492101249210124920000000000000000002EC70B7701CB3F8420281E4083100000000100000003FC6080FE5BB83F3C
pes header:
000001BD0C32808005210001C55B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111110101249210124921012492101249210124920000000000000000002EC70B7701CB3F8420281E4083100000000100000003FC6080FE5BB83F3C

NewPESHeader causes memory escape

Version of go

go version go1.12 linux/amd64

Example:

package main

import (
	"encoding/hex"

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

func main() {
	pkt := parseHexString(
		"4740661a000001c006ff80800521dee9ca57fff94c801d2000210995341d9d43" +
			"61089848180b0884626048901425ddc09249220129d2fce728111c987e67ecb7" +
			"4284af5099181d8cd095b841b0c7539ad6c06260536e137615560052369fc984" +
			"0b3af532418b3924a6b28d6208a6a9e3d22d533ec89646246c734a696407a95e" +
			"3bf230404a4ad0000201038cf0c6a2e32abda45b7effe9f79280a137ed120fd3" +
			"bd8252e07cddadbe6d2b60084208500e06f6ceb6acf2c43011c5938b")

	test(&pkt)
}

func test(pkt *packet.Packet) {
	data, err := packet.PESHeader(pkt)
	if err != nil {
		panic(err)
	}

	pesHeaderData := make([]byte, packet.PacketSize)
	copy(pesHeaderData, data)

	_, err = pes.NewPESHeader(pesHeaderData[:len(data)])
	if err != nil {
		panic(err)
	}
}

func parseHexString(h string) packet.Packet {
	b, err := hex.DecodeString(h)
	if err != nil {
		panic("bad test: " + h)
	}
	var pkt packet.Packet
	if copy(pkt[:], b) != packet.PacketSize {
		panic("bad test (wrong length): " + h)
	}

	return pkt
}
go build --gcflags '-m -l' escape.go 
# command-line-arguments
./escape.go:40:22: "bad test: " + h escapes to heap
./escape.go:44:37: "bad test (wrong length): " + h escapes to heap
./escape.go:37:21: parseHexString h does not escape
./escape.go:43:13: parseHexString pkt does not escape
./escape.go:28:23: make([]byte, packet.PacketSize) escapes to heap
./escape.go:22:11: test pkt does not escape
./escape.go:19:7: main &pkt does not escape

Solution options:

  • Use sync.Pool for pESHeader.data
  • Use copy of pesBytes for pESHeader.data
  • Something else?

Improve README

The readme is too brief. Possible additions include:

  • More examples
  • More in depth explanation of the lib
  • Brief intro to MPEG2 systems layer
  • Make sure existing example compiles

Remove deprecated methods

#28 added MPTS support, but we kept two methods, ProgramMapPid and ProgramNumber for compatibility. We need to remove those after sufficient time is given to update projects that depend on gots.

Support for MPTS

Hi gang, great work!

Do you have plans to support multi-program transport streams in the future?

Proposal: Deprecation of non-receiver functions in packet package

Pull Request #92 moves to pointer receivers on the type Packet for interacting with the various fields of an mpeg TS packet. This creates duplicate functionality with functions that are already in place.

  • Proposal: To create parity with the other packages we would like to move towards pointer receivers for all the functions that interact with packet. This means deprecating many of the current functions in packet.go

We would love input and guidance from the open source community on whether these are worthwhile changes. If this is decided to be a valuable change the old functions would be depreciated, and removed in a few months time.

Idiomatic Go Style notes

I just stumbled across this repo, linked to from golang/go#16353, which proposes to add packages under golang.org/x. A necessary but not sufficient condition for golang.org/x is that that code be in idiomatic Go style. Here are some miscellaneous notes on that topic, in no particular order:

First up, it doesn't build. AFAICT, the canonical github URL https://github.com/Comcast/gots has a capital C in Comcast. The import paths in the code are something like "github.com/comcast/gots" with a lower case C. I'm guessing that you're developing on Windows.

The example code in Readme.md doesn't look like it would build. The structure is:

func main() {
    etc
    if err == nil {
        etc
    } else {
        fmt.Printf(etc)
}

and you're missing an }.

Also, we usually check err != nil (and return early) instead of err == nil.

Also, the ".Error()" in

fmt.Printf("Unable to open file [%s] due to [%s]\n", filename, err.Error())

is redundant. Grep https://golang.org/pkg/fmt/ for "Error" for more details.

The loop:

pkt := make([]byte, packet.PacketSize)
for read, err := file.Read(pkt); read > 0 && err == nil; read, err = file.Read(pkt) {
    etc
}

is incorrect. As per https://golang.org/pkg/io/#Reader, the Read method is allowed to read fewer bytes than the buffer length. You may want https://golang.org/pkg/io/#ReadFull. You might also want a bufio.Reader to avoid lots of small reads.

In package packet:

return packet[0:start]

can be just

return packet[:start]
func badLen(packet Packet) bool {
    if len(packet) != PacketSize {
        return true
    }
    return false
}

can be just

func badLen(packet Packet) bool {
    return len(packet) != PacketSize
}

Similarly with func IsPat:

if pid(packet) == 0 {
    return true, nil
}
return false, nil

can be just:

return pid(packet) == 0, nil

The uint8 in

return packet[3] & uint8(0x0f), nil

is redundant, as per https://blog.golang.org/constants

Similarly, the int in

if int(packet[dataOffset+0]) == 0

is redundant.

Similarly for the uint8 in

func Length(packet packet.Packet) uint8 {
    return uint8(packet[4])
}

The parens in

return (packet[5] & 0x80) != 0

are unnecessary, and once you remove them, gofmt will emphasize the operator precedence:

return packet[5]&0x80 != 0
const PacketSize

can probably be just

const Size

as we are already in "package packet", so users of this constant would refer to it as "packet.Size". In the standard library's net/http package, the type is called Server, which users refer to as "http.Server". It's not "type HTTPServer" and "http.HTTPServer". Similarly for many other names in this repo.

Pid should probably be PID, as per https://github.com/golang/go/wiki/CodeReviewComments#initialisms, and similarly it'd be MPEG, AAC, CRC, etc.

"var emptyByteArray []byte" is unnecessary. Instead of:

return emptyByteArray, err

write:

return nil, err

and similarly, drop the "var emptyByteSlice []byte".

The "Array" in "emptyByteArray" is also incorrect: it's a slice, not an array. In Go, an array has fixed length.

In the _test.go files, the usual Go naming is "want", not "expected".

The outer parens in

!(bytes.Equal(payload, expected))

are unnecessary.

The byte in

packet[3] = byte(0x00)

is unnecessary.

The "== false" in:

if isNull, _ := IsNull(p); isNull == false {

is usually written:

if isNull, _ := IsNull(p); !isNull {

The "e" variable name in

pid, e := Pid(p)

should be "err".

The blank line in

// Create creates a new etc.
[blank line]
// Example usage
// etc
func Create(pid uint16, options ...func(*Packet)) Packet { etc }

means that godoc does not associate that first line comment line with the function. Instead, that blank line should be a blank comment line:

//

The asterisks in

func WithHasPayloadFlag(pkt *Packet) {
    (*pkt)[3] = byte((*pkt)[3] | 0x10)
}

are unnecessary. Packet is already a slice type, which contains an implicit pointer. There's no need for another indirection.

The second "size" in:

pay := make([]byte, size, size)

is redundant.

The double-parens in:

start := payloadStart((*pkt))

is unnecessary.

There is a typo with the "creatio" in "This is a convenience function for often used packet creatio options functions".

In func Create:

var pkt Packet = make([]byte, 188)

can be

pkt := make(Packet, 188)

Doc comments should also be complete sentences, and therefore end with a full stop. https://github.com/golang/go/wiki/CodeReviewComments#comment-sentences

That link also says that "Comments should begin with the name of the thing being described and end in a period", so that the "Parses" in

// Parses the accumulated packets and returns the
// concatenated payloads or any error that occurred, not both
func (a *accumulator) Parse() ([]byte, error) { etc }

should instead be

// Parse parses the accumulated packets and etc.

and similarly for various other doc comments in the repo.

I think that

func SetPayload(pkt *Packet, pay []byte) int {
    start := payloadStart((*pkt))
    i := start
    j := 0
    for i < PacketSize && j < len(pay) {
        (*pkt)[i] = pay[j]
        i++
        j++
    }
    return i - start
}

can instead be:

func SetPayload(pkt Packet, pay []byte) int {
    return copy(pkt[payloadStart(pkt):], pay)
}

if you are assuming that len(pkg) == PacketSize.

In general, it seems like functions like ContainsPayload, SetPayload and Equal could be methods instead of functions.

The make call in

if payloadUnitStartIndicator(pkt) {
    a.packets = make([]Packet, 0)
}

is probably redundant. A nil slice is a valid (empty) slice. It has length zero, you can range over it (zero times), and you can append to it.

This:

done, err := a.f(b)
if err != nil {
    return false, err
}
return done, nil

can probably just be

return a.f(b)

The var b line in

var b []byte
buf := bytes.NewBuffer(b)

is redundant, and the second can be just:

buf := bytes.NewBuffer(nil)

In package pmtdescriptor:

The receiver name, "descriptor" in

func (descriptor *pmtDescriptor) Tag() uint8 { etc }

is unusually long. See https://github.com/golang/go/wiki/CodeReviewComments#receiver-names

The constructor function:

func NewPmtDescriptor(tag uint8, data []byte) PmtDescriptor {
    descriptor := &pmtDescriptor{}
    descriptor.tag = tag
    descriptor.data = data
    return descriptor
}

could use a struct literal instead:

func NewPmtDescriptor(tag uint8, data []byte) PmtDescriptor {
    return &pmtDescriptor{
        tag:  tag,
        data: data,
    }
}

Go variable names lookLikeThis with camel case, not like representation_id_flag or num_partitions. https://golang.org/doc/effective_go.html#mixed-caps

indx is also an unusual variable name. Just use i.

The atscPmtStreamType type could be an anonymous struct. This:

type atscPmtStreamType struct {
    firstCode   uint8
    lastCode    uint8
    description string
}
var atscPmtStreamTypes = []atscPmtStreamType{etc}

could instead be

var atscPmtStreamTypes = []struct {
    firstCode   uint8
    lastCode    uint8
    description string
}{etc}

The i++ in

for i, descriptor := range descriptors {
    descriptorsBuf.WriteString(fmt.Sprintf("descriptor%d='%v'", i, descriptor))
    i++
    if i < len(descriptors) {
        descriptorsBuf.WriteString(",")
    }
}

looks like a bug.

Also,

descriptorsBuf.WriteString(fmt.Sprintf("descriptor%d='%v'", i, descriptor))

can instead be

fmt.Fprintf(&descriptorsBuf, "descriptor%d='%v'", i, descriptor)

The "descriptorsBuf" variable name is also unusually long, for such a short function (pmtElementaryStream.String).

This:

for i := 0; i < len(packets); i++ {
    pay, err := packet.Payload(packets[i])
    etc
}

can be:

for _, p := range packets {
    pay, err := packet.Payload(p)
    etc
}

or if you made Payload a method:

for _, p := range packets {
    pay, err := p.Payload()
    etc
}

but in the larger loop:

var pmtByteBuffer bytes.Buffer
for i := 0; i < len(packets); i++ {
    pay, err := packet.Payload(packets[i])
    if err != nil {
        return nil
    }
    pmtByteBuffer.Write(pay)
}

the bytes.Buffer is overkill. If you're just mushing byte slices together, have a "var buffer []byte" at the top and use the append function with dot-dot-dot.

The capital-B in

const BitsPerByte = 8

means that that constant is exported, but I doubt that users of that package would ever refer to psi.BitsPerByte. If that constant is only meant for internal use, the general rule is that we don't export names unless we have to. Similarly, it's not clear to me whether the psi.PointerField function needs to be exported or if it's only meant to be used by other functions inside that package.

There were more directories of code, but I didn't look at them. This note is already long enough.

I also only looked at code style in this note. I did not assess whether the API design style was idiomatic, which is again a necessary but not sufficient condition for moving under golang.org/x.

I hope that this has been helpful. Please let me know if it comes across as overly aggressive.

Panic when calling pes.NewPESHeader

While building a tool to do an analysis of MPEGTS for HLS delivery, ran into a panic while calling pes.NewPESHeader.

pes := new(pESHeader)
var err error

if CheckLength(pesBytes, "PES", 6) {

	pes.packetStartCodePrefix = uint32(pesBytes[0])<<16 | uint32(pesBytes[1])<<8 | uint32(pesBytes[2])

	pes.streamId = uint8(pesBytes[3])
	pes.pesPacketLength = uint16(pesBytes[4])<<8 | uint16(pesBytes[5])
--->	pes.dataAlignment = pesBytes[6]&0x04 != 0
	dataStartIndex := 6

The code panics on the pesBytes[6] check being out of bounds.

I think that CheckLength should be called with a value of seven in this case since it's checking the length of the byte array which is one-based, but the index is zero based.

Thank you for this code, it made getting started much easier!

packet: Sync may skip over an entire packet

The call to UnreadByte here may fail today, and will fail 100% of the time using go1.12beta1 (see golang/go#18556):

gots/packet/io.go

Lines 51 to 59 in 06ffb31

nextData, err := rp.Peek(PacketSize)
if err == io.EOF || err == io.ErrUnexpectedEOF {
break
}
if err != nil {
return 0, err
}
if nextData[187] == SyncByte {
r.UnreadByte()

If r.Size() < rp.Size(), then the call to rp.Peek may cause r to read and discard part of the next packet, and the call to UnreadByte will unread the second packet's SyncByte rather than the first one, skipping over an entire packet in the process.

packet: propose Packet be changed to [188]byte

At the moment, a packet.Packet is a []byte and in many places it's passed as a point to this. It's not clear to me why that is since the type is already a point to the backing array. Removing the pointer would be one option, but given that the packet size is fixed at 188 bytes, making it a [188]byte and passing pointers to that makes more sense. Of course this breaks users, so feel free to ignore this - it just seems weird and incurs a double dereference unnecessarily.

PTS values from gots doesnt match that of ffprobe

PTS values returned from pesHeader.PTS or pes.ExtraTime() doesnt match with the ffprobe -show_frames output

In the attachment:

ffprobe_output.txt: is the output of ffprobe -show_frames -pretty media-u6iutp8g5_b2128000_20125.ts >> ffprobe_output.txt

gots_output.txt: is the output of the following go code

media-u6iutp8g5_b2128000_20125.ts.gz: is the media file used in this example

Code

 import (
     "github.com/Comcast/gots/packet"
     "github.com/Comcast/gots/pes"
     //

[ffprobe_output.txt](https://github.com/Comcast/gots/files/1022103/ffprobe_output.txt)
[gots_output.txt](https://github.com/Comcast/gots/files/1022102/gots_output.txt)


"github.com/Comcast/gots"
     "fmt"
     "io"
     //"encoding/hex"
 )

 type PacketWrapper struct {
     MgepTs io.Reader
 }

 func NewPacketWrapper(mpegTs io.Reader) *PacketWrapper {
     return &PacketWrapper{mpegTs}
 }

 func (pw *PacketWrapper) Parse() (bool, error) {
     pkt := make([]byte, packet.PacketSize)
     read, err := pw.MgepTs.Read(pkt)
     for ;read > 0 && err == nil; read, err = pw.MgepTs.Read(pkt) {
         if err != nil {
             println(err)
             return false, err
         }

         pid, err := packet.Pid(pkt)
         if err != nil {
             println(err)
             continue
         }

         if (pid == 256 || pid == 257) {
             header, errP := pes.NewPESHeader(pkt)
             if errP != nil {
                 println(errP)
                 return false, errP
             }

             if header.HasPTS() {
                 fmt.Printf("PID %d, PTS %d\n", pid, header.PTS())
             }

         }
     }

     return true, nil
 }

ffprobe_output.txt

gots_output.txt

media-u6iutp8g5_b2128000_20125.ts.gz

Trying to run parsefile.go to extract information

  1. Trying to run parsefile.go to extract information

go run parsefile.go -f wjz-200309111230-clip.ts

(0x276028,0xc82006e0a0)
Pat
PMT PID 4720
ProgramNumber 37976
Number of Programs 37976
Cannot close File wjz-200309111230-clip.ts
panic: runtime error: index out of range

goroutine 1 [running]:
panic(0x10af40, 0xc82000e060)
/usr/local/go/src/runtime/panic.go:481 +0x3e6
github.com/Comcast/gots/psi.PmtAccumulatorDoneFunc(0xc820080240, 0xb8, 0xb8, 0xb8, 0x0, 0x0)
/_/src/github.com/Comcast/gots/psi/pmt.go:49 +0xcc
github.com/Comcast/gots/packet.(_accumulator).Add(0xc82007e080, 0xc820080180, 0xbc, 0xbc, 0xbc, 0x0, 0x0)
/
/src/github.com/Comcast/gots/packet/accumulator.go:77 +0x347
main.extractPmt(0x2b6348, 0xc820076008, 0x2b1270, 0x0, 0x0, 0x0, 0x0)
/
parsefile.go:183 +0x314
main.main()
/
*/parsefile.go:68 +0x416
exit status 2

  1. Information about media used:

General
ID : 1403 (0x57B)
Complete name : wjz-200309111230-clip.ts
Format : MPEG-TS
File size : 10.0 MiB
Duration : 4s 153ms
Start time : UTC 2003-09-11 16:34:33
End time : UTC 2003-09-11 16:34:36
Overall bit rate mode : Constant
Overall bit rate : 19.4 Mbps
Movie name : The Young and The Restless
Law rating : TV-14 (D)

Video
ID : 17 (0x11)
Menu ID : 1 (0x1)
Format : MPEG Video
Format version : Version 2
Format profile : Main@High
Format settings, BVOP : Yes
Format settings, Matrix : Default
Format settings, GOP : M=3, N=15
Format settings, picture structure : Frame
Codec ID : 2
Duration : 3s 937ms
Bit rate mode : Variable
Bit rate : 18.0 Mbps
Maximum bit rate : 19.2 Mbps
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate : 29.970 (30000/1001) fps
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Interlaced
Scan order : Top Field First
Compression mode : Lossy
Bits/(Pixel*Frame) : 0.290
Stream size : 8.47 MiB (85%)

Audio
ID : 20 (0x14)
Menu ID : 1 (0x1)
Format : AC-3
Format/Info : Audio Coding 3
Mode extension : CM (complete main)
Format settings, Endianness : Big
Codec ID : 129
Duration : 4s 128ms
Bit rate mode : Constant
Bit rate : 384 Kbps
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 48.0 KHz
Frame rate : 31.250 fps (1536 spf)
Compression mode : Lossy
Delay relative to video : -256ms
Stream size : 194 KiB (2%)
Language : English

Text #1
ID : 17 (0x11)-CC1
Menu ID : 1 (0x1)
Format : EIA-608
Muxing mode : A/53 / DTVCC Transport
Muxing mode, more info : Muxed in Video #1
Duration : 3s 937ms
Bit rate mode : Constant
Stream size : 0.00 Byte (0%)

Text #2
ID : 17 (0x11)-1
Menu ID : 1 (0x1)
Format : EIA-708
Muxing mode : A/53 / DTVCC Transport
Muxing mode, more info : Muxed in Video #1
Duration : 3s 937ms
Bit rate mode : Constant
Stream size : 0.00 Byte (0%)

Menu
ID : 16 (0x10)
Menu ID : 1 (0x1)
Duration : 4s 153ms
List : 17 (0x11) (MPEG Video) / 20 (0x14) (AC-3, English)
Title : The Young and The Restless
Language : / English
Service name : WJZ Digital
Service channel number : 13-1
Service type : Digital television
Law rating : TV-14 (D)

Also how to use other options like pmt, ebp and pid. Can someone please give me an example?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.