Created
March 12, 2014 17:52
-
-
Save sbowman/9512354 to your computer and use it in GitHub Desktop.
SCTE35 Parsing with iobit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/base64" | |
"fmt" | |
"github.com/bamiaux/iobit" | |
) | |
type SpliceInfoSection struct { | |
TableID uint32 | |
SectionSyntaxIndicator bool | |
PrivateIndicator bool | |
SectionLength uint32 | |
ProtocolVersion uint32 | |
EncryptedPacket bool | |
EncryptionAlgorithm uint32 | |
PTSAdjustment uint64 | |
CWIndex uint32 | |
Tier uint32 | |
SpliceCommandLength uint32 | |
SpliceCommandType uint32 | |
DescriptorLoopLength uint32 | |
AlignmentStuffing []int | |
EncryptedCRC uint32 | |
CRC32 uint32 | |
// SpliceCommand interface{} | |
// SpliceDescriptors []*SpliceDescriptor | |
} | |
// Create an iobit reader to parse the Base64 SCTE35 string. | |
func NewReader(base64str string) (*iobit.Reader, error) { | |
decoded, err := base64.StdEncoding.DecodeString(base64str) | |
if err != nil { | |
return nil, err | |
} | |
return iobit.NewReader(decoded), nil | |
} | |
func ParseSpliceInfoSection(base64str string) (*SpliceInfoSection, error) { | |
r, err := NewReader(base64str) | |
if err != nil { | |
return nil, err | |
} | |
sis := new(SpliceInfoSection) | |
sis.TableID = r.Uint32Le(8) | |
sis.SectionSyntaxIndicator = r.IsBit() | |
sis.PrivateIndicator = r.IsBit() | |
// Reserved | |
r.Skip(2) | |
sis.SectionLength = r.Uint32(12) | |
sis.ProtocolVersion = r.Uint32(8) | |
sis.EncryptedPacket = r.IsBit() | |
sis.EncryptionAlgorithm = r.Uint32(6) | |
sis.PTSAdjustment = r.Uint64(33) | |
sis.CWIndex = r.Uint32(8) | |
sis.Tier = r.Uint32Le(12) | |
sis.SpliceCommandLength = r.Uint32(12) | |
sis.SpliceCommandType = r.Uint32(8) | |
sis.DescriptorLoopLength = r.Uint32(16) | |
spliceDescriptor := make([]byte, sis.DescriptorLoopLength) | |
for i, _ := range spliceDescriptor { | |
spliceDescriptor[i] = byte(r.Uint32Le(8)) | |
} | |
// TODO: Pass the spliceDescriptor along to be read into | |
// SegmentationDescriptor, etc. | |
if sis.EncryptedPacket { | |
if r.Bits() > 64 { | |
r.Skip(64 - r.Bits()) | |
} | |
sis.EncryptedCRC = r.Uint32Le(32) | |
} else if r.Bits() > 32 { | |
r.Skip(32 - r.Bits()) | |
} | |
sis.CRC32 = r.Uint32Le(32) | |
return sis, nil | |
} | |
// Convert the Base64 string into it's binary representation manually. | |
func showBinary(base64str string) { | |
decoded, err := base64.StdEncoding.DecodeString(base64str) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
bin := "" | |
for i := 0; i < len(decoded); i += 16 { | |
for offset := 0; offset < 16 && offset+i < len(decoded); offset++ { | |
bin += fmt.Sprintf("%b", decoded[i+offset]) | |
} | |
} | |
fmt.Println(bin) | |
} | |
// Cycle through the bits in the Base64 string using the iobit library. | |
func showBits(base64str string) { | |
r, err := NewReader(base64str) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
for r.Bits() != 0 { | |
if r.IsBit() { | |
fmt.Print("1") | |
} else { | |
fmt.Print("0") | |
} | |
} | |
fmt.Println() | |
} | |
func main() { | |
// Test string | |
base64str := "/ABVAAAAAAAAAAAABQaAZPXfAAA/Aj1DVUVJQUJDRH/fAAD3MUAJKUJMQUNLT1VUOlRXdEhLMDFNU0VKRlpVdFpNM2RMV0RCaE5rbFJkejA5NAAAZ6usxA==" | |
fmt.Println("Manually parsing:") | |
showBinary(base64str) | |
fmt.Println() | |
fmt.Println("Using iobit:") | |
showBits(base64str) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That showBinary function is a trimmed down version of my production one, hence the weird loop.