Skip to content

Latest commit

 

History

History
348 lines (263 loc) · 9.54 KB

File metadata and controls

348 lines (263 loc) · 9.54 KB

Using threefive as a library.

threefive is made almost entirely of classes.

The class used most often is the Cue class.

Decoding

A Cue instance can decode SCTE-35 from Base64, Bytes, Hex, Integer, JSON, Xml, Xml+bin, or a raw MPEGTS packet.

  • Some Examples
>>>> from threefive import Cue
  • Base64
>>>> cue=Cue('/DAgAAAAAAAAAP/wDwUAAAABf//+AFJlwAABAAAAAMOOklg=')
  • Bytes
>>>> cue =Cue(b'\xfc0 \x00\x00\x00\x00\x00\x00\x00\xff\xf0\x0f\x05\x00\x00\x00\x01\x7f\xff\xfe\x00Re\xc0\x00\x01\x00\x00\x00\x00\xc3\x8e\x92X')
  • Int
>>>> cue=Cue(1913741249324105789713965315611872444571137197654250805822733947388252170837252018776)
  • Xml
>>>> exemel='''<scte35:SpliceInfoSection xmlns:scte35="https://scte.org/schemas/35"  ptsAdjustment="0" protocolVersion="0" sapType="3" tier="4095">
   <scte35:SpliceInsert spliceEventId="1" spliceEventCancelIndicator="false" spliceImmediateFlag="true" eventIdComplianceFlag="true" availNum="0" availsExpected="0" outOfNetworkIndicator="true" uniqueProgramId="1">
      <scte35:BreakDuration autoReturn="true" duration="5400000"/>
   </scte35:SpliceInsert>
</scte35:SpliceInfoSection>'''

>>>> cue =Cue(exemel)

Once you have a Cue instance you can print the data in JSON with the show() method.

>>>> from threefive import Cue

>>>> cue=Cue('/DAgAAAAAAAAAP/wDwUAAAABf//+AFJlwAABAAAAAMOOklg=')

>>>> cue.show()

{
    "info_section": {
        "table_id": "0xfc",
        "section_syntax_indicator": false,
        "private": false,
        "sap_type": "0x03",
        "sap_details": "No Sap Type",
        "section_length": 32,
        "protocol_version": 0,
        "encrypted_packet": false,
        "encryption_algorithm": 0,
        "pts_adjustment": 0.0,
        "cw_index": "0x00",
        "tier": "0x0fff",
        "splice_command_length": 15,
        "splice_command_type": 5,
        "descriptor_loop_length": 0,
        "crc": "0xc38e9258"
    },
    "command": {
        "command_length": 15,
        "command_type": 5,
        "name": "Splice Insert",
        "break_auto_return": true,
        "break_duration": 60.0,
        "splice_event_id": 1,
        "splice_event_cancel_indicator": false,
        "out_of_network_indicator": true,
        "program_splice_flag": true,
        "duration_flag": true,
        "splice_immediate_flag": true,
        "event_id_compliance_flag": true,
        "unique_program_id": 1,
        "avail_num": 0,
        "avails_expected": 0
    },
    "descriptors": []
}

Cue variables or attributes can be accessed via dot notation.

>>>> from threefive import Cue
>>>> cue=Cue('/DAWAAAAAAAAAP/wBQb+AKmKxwAACzuu2Q==')
>>>> cue.info_section.table_id
'0xfc'
>>>> cue.command.pts_time
123.456789

Output methods

The data can be returned in a variety of formats.

  • Cue.base64() returns SCTE-35 as bytes

  • Cue.bytes() returns SCTE-35 darta as bytes

  • Cue.hex() returns SCTE-35 data as a hex string

  • Cue.int() returns SCTE-35 data as a big integer

  • Cue.json() returns SCTE-35 data as a json string

  • Cue.xml() returns SCTE-35 data as Xml `

  • Cue.xmlbin() returns SCTE-35 as Xml+binary


Components

A Cue can also be initialized without data.

>>>> from threefive import Cue 

>>>> cue=Cue()
  • A Cue instance contains

    • 1 Splice InfoSection as Cue.InfoSection
    • 1 Splice Command as Cue.command
    • 0 or more Splice Descriptors as a list Cue.descriptors
      • A Splice Descriptor contains 0 or more Upids

  • Splice Commands
    • BandwidthReservation
    • PrivateCommand
    • SpliceNull
    • TimeSignal
    • SpliceInsert

  • Splice Descriptors
    • AvailDescriptor
    • DtmfDescriptor
    • DVBDASDescriptor
    • SegmentationDescriptor
    • TimeDescriptor

  • Upids

    • Upid
    • AirId
    • Atsc
    • Mid
    • Mpu
    • Eidr
    • NoUpid
    • Isan
    • Umid

The individual components of a Cue can be initialized and added to the Cue, the Splice Info Section is automatically added for you.

>>>> from threefive import Cue, TimeSignal

>>>> cue=Cue()

>>>> ts=TimeSignal()

>>>> cue.command=ts


>>>> cue

{'command': {'command_length': 0, 'command_type': 6, 'name': 'Time Signal', 'bites': None, 'time_specified_flag': None, 'pts_time': None},
 'descriptors': [],
 'info_section': {'table_id': None, 'section_syntax_indicator': None, 'private': None, 'sap_type': None,
 'sap_details': None, 'section_length': None, 'protocol_version': None, 'encrypted_packet': None, 'encryption_algorithm': None,
 'pts_adjustment': 0, 'cw_index': None, 'tier': None, 'splice_command_length': None, 'splice_command_type': None,
 'descriptor_loop_length': 0, 'crc': None},
 'bites': None, 'packet_data': None, 'dash_data': None}

Cue vars can be edited via dot notation

>>>> cue.command.time_specified_flag
False

>>>> cue.command.time_specified_flag=True

>>>> cue.command.time_specified_flag
True

>>>> cue.command.pts_time=123.456789

>>>> cue

{'command': {'command_length': 0, 'command_type': 6, 'name': 'Time Signal', 'bites': None, 'time_specified_flag': True, 'pts_time': 123.456789}, 'descriptors': [], 'info_section': {'table_id': None, 'section_syntax_indicator': None, 'private': None, 'sap_type': None, 'sap_details': None, 'section_length': None, 'protocol_version': None, 'encrypted_packet': None, 'encryption_algorithm': None, 'pts_adjustment': 0, 'cw_index': None, 'tier': None, 'splice_command_length': None, 'splice_command_type': None, 'descriptor_loop_length': 0, 'crc': None}, 'bites': None, 'packet_data': None, 'dash_data': None}

Running Cue.encode() will fill in the Splice Info Section.

>>>> cue.encode()
'/DAWAAAAAAAAAP/wBQb+AKmKxwAACzuu2Q=='

>>>> cue

{'command': {'command_length': 5, 'command_type': 6, 'name': 'Time Signal', 'time_specified_flag': True, 'pts_time': 123.456789},
 'descriptors': [],
'info_section': {'table_id': '0xfc', 'section_syntax_indicator': False, 'private': False, 'sap_type': '0x03',
 'sap_details': 'No Sap Type', 'section_length': 22, 'protocol_version': 0, 'encrypted_packet': False,
 'encryption_algorithm': 0, 'pts_adjustment': 0.0, 'cw_index': '0x00', 'tier': '0x0fff', 'splice_command_length': 5,
 'splice_command_type': 6, 'descriptor_loop_length': 0, 'crc': '0xb3baed9'},
'bites': b'\xfc0\x16\x00\x00\x00\x00\x00\x00\x00\xff\xf0\x05\x06\xfe\x00\xa9\x8a\xc7\x00\x00\x0b;\xae\xd9',
 'packet_data': None, 'dash_data': None}

>>>> cue.show()
{
    "info_section": {
        "table_id": "0xfc",
        "section_syntax_indicator": false,
        "private": false,
        "sap_type": "0x03",
        "sap_details": "No Sap Type",
        "section_length": 22,
        "protocol_version": 0,
        "encrypted_packet": false,
        "encryption_algorithm": 0,
        "pts_adjustment": 0.0,
        "cw_index": "0x00",
        "tier": "0x0fff",
        "splice_command_length": 5,
        "splice_command_type": 6,
        "descriptor_loop_length": 0,
        "crc": "0xb3baed9"
    },
    "command": {
        "command_length": 5,
        "command_type": 6,
        "name": "Time Signal",
        "time_specified_flag": true,
        "pts_time": 123.456789
    },
    "descriptors": []
}

Cue, Splice Info Section, Splice Commands, Splice Descriptors, and Upids all have these methods.

  • decode() decode the SCTE-35 component
  • encode() encode the SCTE-35 component and return the byte string
  • xml() return a threefive.Node xml instance

Splice Info Section, Splice Commands, Splice Descriptors, and Upids can be manipulated with or without a Cue.

>>>> from threefive import TimeSignal

>>>> ts = TimeSignal()
>>>> cue.command.time_specified_flag=True
>>>> cue.command.pts_time=123.456789

>>>>ts.encode()
b'\xfe\x00\xa9\x8a\xc7'

>>>> ts.xml()

<scte35:TimeSignal >
   <scte35:SpliceTime ptsTime="11111111"/>
</scte35:TimeSignal>

threefive.SCTE35Base

Cue, Splice Info Section, Splice Commands, and Splice Descriptors all inherit from threefive.SCTE35Base

Methods inherited from threefive.base.SCTE35Base:

  • has(self, what) has runs hasattr with self and what as the attribute. Returns value of what if set or None if not set.
>>>> cue.has('info_section')

{'table_id': '0xfc', 'section_syntax_indicator': False, 'private': False, 'sap_type': '0x03', 'sap_details': 'No Sap Type',
'section_length': 32, 'protocol_version': 0, 'encrypted_packet': False, 'encryption_algorithm': 0, 'pts_adjustment': 0.0,
'cw_index': '0x00', 'tier': '0x0fff', 'splice_command_length': 15, 'splice_command_type': 5,
'descriptor_loop_length': 0, 'crc': '0x961b236d'}

>>>> cue.has('bob')

>>>> 
  • json(self) returns self as kv_clean'ed json
  • kv_clean(self) recursively removes attributes from the instance if the value is None.
  • show(self) prints kv_clean'ed self as json to stderr

Static methods inherited from threefive.base.SCTE35Base:

  • as_90k(int_time) ticks to 90k timestamps
  • as_hms(secs_of_time) converts timestamp to 00:00:00.000 format
  • as_ticks(float_time) 90k timestamps to ticks
  • fix_hex(hexed) adds padded zero if needed for byte conversion.
>>> from threefive import Cue
>>>> cue=Cue()
>>>> cue.fix_hex('0xDBEE3')
'0x0DBEE3'
  • idxsplit(gonzo, sep) split gonzo at sep and return sep + everything after.
>>> from threefive import Cue
>>>> cue=Cue()
>>>> cue.idxsplit("Hello","e")
'ello'