cuei

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2023 License: BSD-3-Clause Imports: 6 Imported by: 0

README

cuei is a SCTE35 parser library in Go.

  • Parses SCTE-35 Cues from MPEGTS or Bytes or Base64
  • Parses SCTE-35 Cues spread over multiple MPEGTS packets
  • Supports multi-packet PAT and PMT tables
  • Supports multiple MPEGTS Programs and multiple SCTE-35 streams

Install cuei

go install github.com/futzu/cuei@latest

Nutshell

Use this To do this
cuei.Cue Parse SCTE-35 from a Base64 or Byte string.
cuei.Stream Parse SCTE35 Cues from MPEGTS packets.
cuei.Scte35Parser Parse SCTE-35 from MPEGTS packets from a external demuxer.

Quick Demo

  • cueidemo.go
package main

import (
	"os"
	"fmt"
	"github.com/futzu/cuei"
)

func main(){

	args := os.Args[1:]
	for i := range args{
		fmt.Printf( "\nNext File: %s\n\n",args[i] )
		var stream   cuei.Stream
		stream.Decode(args[i])
	}
} 


build cueidemo
go build cueidemo.go
parse mpegts video for scte35
./cueidemo a_video_with_scte35.ts
output
Next File: mpegts/out.ts

{
    "Name": "Splice Info Section",
    "TableID": "0xfc",
    "SectionSyntaxIndicator": false,
    "Private": false,
    "Reserved": "0x3",
    "SectionLength": 49,
    "ProtocolVersion": 0,
    "EncryptedPacket": false,
    "EncryptionAlgorithm": 0,
    "PtsAdjustment": 0,
    "CwIndex": "0x0",
    "Tier": "0xfff",
    "SpliceCommandLength": 20,
    "SpliceCommandType": 5,
    "DescriptorLoopLength": 12,
    "Command": {
        "Name": "Splice Insert",
        "CommandType": 5,
        "SpliceEventID": "0x5d",
        "OutOfNetworkIndicator": true,
        "ProgramSpliceFlag": true,
        "DurationFlag": true,
        "BreakDuration": 90.023266,
        "TimeSpecifiedFlag": true,
        "PTS": 38113.135577
    },
    "Descriptors": [
        {
            "Tag": 1,
            "Length": 10,
            "Identifier": "CUEI",
            "Name": "DTMF Descriptor",
            "PreRoll": 177,
            "DTMFCount": 4,
            "DTMFChars": 4186542473
        }
    ],
    "Packet": {
        "PacketNumber": 73885,
        "Pid": 515,
        "Program": 51,
        "Pcr": 38104.526277,
        "Pts": 38105.268588
    }
}


Parse base64 encoded SCTE-35

package main

import (
	"fmt"
	"github.com/futzu/cuei"
)

func main(){

	var cue cuei.Cue
	data := cuei.DeB64("/DA7AAAAAAAAAP/wFAUAAAABf+/+AItfZn4AKTLgAAEAAAAWAhRDVUVJAAAAAX//AAApMuABACIBAIoXZrM=")
        cue.Decode(data) 
        fmt.Println("Cue as Json")
        cue.Show()
}

Use cuei with another MPEGTS stream parser / demuxer

  • Scte35Parser is for incorporating with another MPEGTS parser.
  • Example
	       import(
	           "github.com/futzu/cuei"
	           )
	       scte35parser := cuei.NewScte35Parser()

	       // Each time your parser/demuxer finds a SCTE-35 packet (stream type 0x86)

	       // do something like

	       cue := scte35parser.Parse(aScte35Packet)
	       if cue != nil {
	           // do something with the cue
	       }

  • If the MPEGTS SCTE-35 packet contains a complete cue message

    • The cue message is decoded into a Cue and returned.
  • If the MPEGTS SCTE-35 packet is a partial cue message

    • It will be stored and aggregated with the next MPEGTS SCTE-35 packet until complete.

    • Completed cue messages are decoded into a Cue and returned.


Shadow a Cue struct method

package main

import (
	"fmt"
	"github.com/futzu/cuei"
)

type Cue2 struct {
    cuei.Cue               		// Embed cuei.Cue
}
func (cue2 *Cue2) Show() {        	// Override Show
	fmt.Printf("%+v",cue2.Command)
}

func main(){

	var cue2 Cue2
	data := cuei.DeB64("/DA7AAAAAAAAAP/wFAUAAAABf+/+AItfZn4AKTLgAAEAAAAWAhRDVUVJAAAAAX//AAApMuABACIBAIoXZrM=")
        cue2.Decode(data) 
        cue2.Show()
	
}

Call a shadowed method

package main

import (
	"fmt"
	"github.com/futzu/cuei"
)

type Cue2 struct {
    cuei.Cue               		// Embed cuei.Cue
}
func (cue2 *Cue2) Show() {        	// Override Show

	fmt.Println("Cue2.Show()")
	fmt.Printf("%+v",cue2.Command) 
	
	fmt.Println("\n\ncuei.Cue.Show() from cue2.Show()")
	
	cue2.Cue.Show()			// Call the Show method from embedded cuei.Cue
}

func main(){

	var cue2 Cue2
	data := cuei.DeB64("/DA7AAAAAAAAAP/wFAUAAAABf+/+AItfZn4AKTLgAAEAAAAWAhRDVUVJAAAAAX//AAApMuABACIBAIoXZrM=")
        cue2.Decode(data) 
        cue2.Show()
	
}


Use Dot notation to access SCTE-35 Cue values


/**
Show  the packet PTS time and Splice Command Name of SCTE-35 Cues
in a MPEGTS stream.
**/


package main

import (
	"os"
	"fmt"
	"github.com/futzu/cuei"
)

func main() {

	args := os.Args[1:]
	for _,arg := range args {
		fmt.Printf("\nNext File: %s\n\n", arg)
		var stream cuei.Stream
		stream.Decode(arg)
		for _,c:= range stream.Cues {
			fmt.Printf("PTS: %v, Splice Command: %v\n",c.PacketData.Pts, c.Command.Name )
		}
	}
}

Documentation

Index

Constants

View Source
const BufSz = 16384 * PktSz

bufSz is the size of a read when parsing files.

View Source
const PktSz = 188

pktSz is the size of an MPEG-TS packet in bytes.

Variables

This section is empty.

Functions

func DeB64

func DeB64(b64 string) []byte

DeB64 decodes base64 strings.

func IsIn

func IsIn(slice []uint16, val uint16) bool

IsIn is a test for slice membership

func MkJson

func MkJson(i interface{}) string

MkJson structs to JSON

Types

type Cue

type Cue struct {
	InfoSection *InfoSection
	Command     *SpliceCommand
	Descriptors []SpliceDescriptor `json:",omitempty"`
	PacketData  *packetData        `json:",omitempty"`
}

* Cue is a SCTE35 cue.

A Cue contains:
    1 InfoSection
    1 SpliceCommand
    0 or more Splice Descriptors
    1 packetData (if parsed from MPEGTS)

*

func (*Cue) Decode

func (cue *Cue) Decode(bites []byte) bool

Decode extracts bits for the Cue values.

func (*Cue) Show

func (cue *Cue) Show()

Show display SCTE-35 data as JSON.

type InfoSection

type InfoSection struct {
	Name                   string
	TableID                string
	SectionSyntaxIndicator bool
	Private                bool
	Reserved               string
	SectionLength          uint16
	ProtocolVersion        uint8
	EncryptedPacket        bool
	EncryptionAlgorithm    uint8
	PtsAdjustment          float64
	CwIndex                string
	Tier                   string
	SpliceCommandLength    uint16
	SpliceCommandType      uint8
	DescriptorLoopLength   uint16
}

InfoSection is the splice info section of the SCTE 35 cue.

func (*InfoSection) Decode

func (infosec *InfoSection) Decode(gob *gobs.Gob) bool

Decode Splice Info Section values.

type Pids

type Pids struct {
	PmtPids    []uint16
	PcrPids    []uint16
	Scte35Pids []uint16
}

Pids holds collections of pids by type for cuei.Stream.

type Scte35Parser

type Scte35Parser struct {
	Stream
}

Scte35Parser is for incorporating with another MPEGTS parser.

Usage:

     import(
         "fmt"
         "github.com/futzu/cuei"
     )

     scte35parser := cuei.NewScte35Parser()

 // Each time your parser/demuxer finds
 // a SCTE-35 packet do something like

     cue := scte35parser.Parse(aScte35Packet)
     if cue != nil {
            // process the Cue
            fmt.Printf("%#v",cue.Command)
     }

func NewScte35Parser

func NewScte35Parser() *Scte35Parser

initialize and return a *Scte35parser

func (*Scte35Parser) Parse

func (scte35p *Scte35Parser) Parse(pkt []byte) (cue *Cue)
	Parse accepts a MPEGTS SCTE-35 packet as input.

        If the MPEGTS SCTE-35 packet contains a complete cue message

            The cue message is decoded into a Cue and returned.

	    If the MPEGTS SCTE-35 packet is a partial cue message

            It will be stored and aggregated with the next MPEGTS SCTE-35 packet until complete.

            Completed cue messages are decoded into a Cue and returned.

type SpliceCommand

type SpliceCommand struct {
	Name                       string
	CommandType                uint8
	Identifier                 uint32  `json:",omitempty"`
	Bites                      []byte  `json:",omitempty"`
	SpliceEventID              string  `json:",omitempty"`
	SpliceEventCancelIndicator bool    `json:",omitempty"`
	OutOfNetworkIndicator      bool    `json:",omitempty"`
	ProgramSpliceFlag          bool    `json:",omitempty"`
	DurationFlag               bool    `json:",omitempty"`
	BreakAutoReturn            bool    `json:",omitempty"`
	BreakDuration              float64 `json:",omitempty"`
	SpliceImmediateFlag        bool    `json:",omitempty"`
	ComponentCount             uint8   `json:",omitempty"`
	Components                 []uint8 `json:",omitempty"`
	UniqueProgramID            uint16  `json:",omitempty"`
	AvailNum                   uint8   `json:",omitempty"`
	AvailExpected              uint8   `json:",omitempty"`
	TimeSpecifiedFlag          bool    `json:",omitempty"`
	PTS                        float64 `json:",omitempty"`
}

* SpliceCommand

These Splice Command types are consolidated into SpliceCommand.

     0x0: Splice Null,
     0x5: Splice Insert,
     0x6: Time Signal,
     0x7: Bandwidth Reservation,
     0xff: Private,

*

func (*SpliceCommand) Decode

func (cmd *SpliceCommand) Decode(cmdtype uint8, gob *gobs.Gob)

Decode returns a Command by type

type SpliceDescriptor

type SpliceDescriptor struct {
	Tag                              uint8       `json:",omitempty"`
	Length                           uint8       `json:",omitempty"`
	Identifier                       string      `json:",omitempty"`
	Name                             string      `json:",omitempty"`
	AudioComponents                  []audioCmpt `json:",omitempty"`
	ProviderAvailID                  uint32      `json:",omitempty"`
	PreRoll                          uint8       `json:",omitempty"`
	DTMFCount                        uint8       `json:",omitempty"`
	DTMFChars                        uint64      `json:",omitempty"`
	TAISeconds                       uint64      `json:",omitempty"`
	TAINano                          uint32      `json:",omitempty"`
	UTCOffset                        uint16      `json:",omitempty"`
	SegmentationEventID              string      `json:",omitempty"`
	SegmentationEventCancelIndicator bool        `json:",omitempty"`
	ProgramSegmentationFlag          bool        `json:",omitempty"`
	SegmentationDurationFlag         bool        `json:",omitempty"`
	DeliveryNotRestrictedFlag        bool        `json:",omitempty"`
	WebDeliveryAllowedFlag           bool        `json:",omitempty"`
	NoRegionalBlackoutFlag           bool        `json:",omitempty"`
	ArchiveAllowedFlag               bool        `json:",omitempty"`
	DeviceRestrictions               string      `json:",omitempty"`
	Components                       []segCmpt   `json:",omitempty"`
	SegmentationDuration             float64     `json:",omitempty"`
	SegmentationMessage              string      `json:",omitempty"`
	SegmentationUpidType             uint8       `json:",omitempty"`
	SegmentationUpidLength           uint8       `json:",omitempty"`
	SegmentationUpid                 *Upid       `json:",omitempty"`
	SegmentationTypeID               uint8       `json:",omitempty"`
	SegmentNum                       uint8       `json:",omitempty"`
	SegmentsExpected                 uint8       `json:",omitempty"`
	SubSegmentNum                    uint8       `json:",omitempty"`
	SubSegmentsExpected              uint8       `json:",omitempty"`
}

func (*SpliceDescriptor) Decode

func (dscptr *SpliceDescriptor) Decode(gob *gobs.Gob, tag uint8, length uint8)

* Decode returns a Splice Descriptor by tag.

The following Splice Descriptors are recognized.

    0x0: Avail Descriptor,
    0x1: DTMF Descriptor,
    0x2: Segmentation Descriptor,
    0x3: Time Descriptor,
    0x4: Audio Descrioptor,

*

type Stream

type Stream struct {
	Cues     []*Cue
	Pids     *Pids
	Pid2Prgm map[uint16]uint16 // pid to program map
	Pid2Type map[uint16]uint8  // pid to stream type map
	Programs []uint16
	Prgm2Pcr map[uint16]uint64 // program to pcr map
	Prgm2Pts map[uint16]uint64 // program to pts map
	// contains filtered or unexported fields
}

Stream for parsing MPEGTS for SCTE-35

func NewStream

func NewStream() *Stream

initialize and return a *Stream

func (*Stream) Decode

func (stream *Stream) Decode(fname string) []*Cue

Decode fname (a file name) for SCTE-35

func (*Stream) DecodeBytes

func (stream *Stream) DecodeBytes(b []byte) []*Cue

type Upid

type Upid struct {
	Name             string `json:",omitempty"`
	UpidType         uint8  `json:",omitempty"`
	Value            string `json:",omitempty"`
	TSID             uint16 `json:",omitempty"`
	Reserved         uint8  `json:",omitempty"`
	EndOfDay         uint8  `json:",omitempty"`
	UniqueFor        uint16 `json:",omitempty"`
	ContentID        []byte `json:",omitempty"`
	Upids            []Upid `json:",omitempty"`
	FormatIdentifier string `json:",omitempty"`
	PrivateData      []byte `json:",omitempty"`
}

* Upid is the Struct for Segmentation Upids

	    These UPID types are recognized.

            0x01: "Deprecated",
            0x02: "Deprecated",
            0x03: "AdID",
            0x05: "ISAN"
            0x06: "ISAN"
            0x07: "TID",
            0x08: "AiringID",
            0x09: "ADI",
            0x10: "UUID",
            0x11: "ACR",
            0x0a: "EIDR",
            0x0b: "ATSC",
            0x0c: "MPU",
            0x0d: "MID",
            0x0e: "ADS Info",
            0x0f: "URI",

	    Non-standard UPID types are returned as bytes.

*

func (*Upid) Decode

func (upid *Upid) Decode(gob *gobs.Gob, upidType uint8, upidlen uint8)

Decode Decodes Segmentation UPIDs

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL