Expand description
§scte104 — ANSI/SCTE 104 2023 Automation↔Compression DPI signalling
SCTE 104 is the message protocol an automation system uses to tell a
compression/injection system to insert SCTE 35 (DPI) cueing into the outgoing
Transport Stream. This crate parses + builds the SCTE 104 messages:
single_operation_message and multiple_operation_message and the DPI
operations they carry (splice, time_signal, insert-descriptor, segmentation,
…).
ANSI/SCTE 104 2023 — Automation System to Compression System Communications Applications Program Interface (API).
Depends only on broadcast-common and is #![no_std] (+ alloc).
§Coverage
SingleOperationMessage— single-operation framing (§8.2.2, Table 8-1) with basic request/response operations.MultipleOperationMessage— multi-operation framing (§8.2.3, Table 8-2) with Normal, Supplemental, and Control operations.- All 15 Table 8-3 operations (basic request/response, including the
general_response/init_*/alive_*/inject_*messages of §9 and theconfig_*/provisioning_*/fault_*/AS_alive_*PAMS⇔AS messages of §10) and all 22 Table 8-4 operations (Normal/Supplemental/Control): splice, time_signal, splice_null, descriptor inserts, segmentation, encryption, schedule, control words, proprietary commands, and more. Timestamp(§12.5): variable-length (none/UTC/VITC/GPI) with typed payloads.Time(§12.4): 8-byte GPS-epoch timestamp used in alive_request/response.AnyOperation: unified dispatch enum with a drift test pinning opID literals to type constants.
§Quick start
use scte104::{SingleOperationMessage, MultipleOperationMessage, operations::{AnyOperation, Operation, splice_request::{SpliceRequest, SpliceInsertType}}};
use broadcast_common::{Parse, Serialize};
// Build a splice_request single_operation_message (basic response wrap).
let msg = SingleOperationMessage::new_request(
0x0101, 0, 1, 42, 0,
scte104::operations::AnySingleOperation::Unknown { op_id: 0x0101, body: &[] },
);
let bytes = msg.to_bytes();
// Build a multiple_operation_message with splice + insert_descriptor
let ops = vec![
Operation {
op_id: 0x0101,
data: AnyOperation::SpliceRequest(SpliceRequest {
splice_insert_type: SpliceInsertType::SpliceStartNormal,
splice_event_id: 42,
unique_program_id: 1,
pre_roll_time: 5000,
break_duration: 300,
avail_num: 0,
avails_expected: 0,
auto_return_flag: 1,
not_an_entry_flag: 0,
}),
},
];
let mom = MultipleOperationMessage::new(
0, 1, 42, 0, 0,
scte104::time::Timestamp::None,
ops,
);
let bytes = mom.to_bytes();§Examples
Two runnable examples ship with this crate (cargo run -p scte104 --example <name>).
ⓘ
//! Build and serialize a single_operation_message with a splice_request.
//!
//! This example constructs a basic response (inject_response),
//! serializes it, then parses it back to verify round-trip integrity.
use broadcast_common::{Parse, Serialize};
use scte104::SingleOperationMessage;
use scte104::operations::{AnySingleOperation, InjectResponse};
fn main() {
// Build an inject_response single_operation_message.
let msg = SingleOperationMessage::new_response(
0x0007, // opID = inject_response
0x0000, // result = success
0xFFFF, // result_extension
0, // protocol_version
1, // AS_index
42, // message_number
0, // DPI_PID_index
AnySingleOperation::InjectResponse(InjectResponse { message_number: 42 }),
);
// Serialize.
let bytes = msg.to_bytes();
println!("Serialized {} bytes: {:02x?}", bytes.len(), bytes);
// Round-trip: parse back.
let parsed = SingleOperationMessage::parse(&bytes).unwrap();
assert_eq!(msg, parsed);
println!("Round-trip OK: message_number={}", parsed.message_number);
// Build a second message with an unknown opID (raw body preserved).
let raw_body = [0xCA, 0xFE];
let msg2 = SingleOperationMessage::new_response(
0xDEAD,
0x0000,
0xFFFF,
0,
1,
99,
0,
AnySingleOperation::Unknown {
op_id: 0xDEAD,
body: &raw_body,
},
);
let bytes2 = msg2.to_bytes();
let parsed2 = SingleOperationMessage::parse(&bytes2).unwrap();
assert_eq!(msg2, parsed2);
println!("Unknown opID round-trip OK");
}ⓘ
//! Build a multiple_operation_message with several operations and round-trip.
//!
//! This example constructs a message with a splice_request followed by a
//! time_signal_request (≥2 operations), serializes it, then parses it back.
use broadcast_common::{Parse, Serialize};
use scte104::MultipleOperationMessage;
use scte104::operations::{
AnyOperation, Operation,
splice_request::{SpliceInsertType, SpliceRequest},
time_signal_request::TimeSignalRequest,
};
use scte104::time::Timestamp;
fn main() {
// Build operations: splice + time_signal.
let ops = vec![
Operation {
op_id: 0x0101,
data: AnyOperation::SpliceRequest(SpliceRequest {
splice_insert_type: SpliceInsertType::SpliceStartNormal,
splice_event_id: 42,
unique_program_id: 1,
pre_roll_time: 5000,
break_duration: 300,
avail_num: 0,
avails_expected: 0,
auto_return_flag: 1,
not_an_entry_flag: 0,
}),
},
Operation {
op_id: 0x0104,
data: AnyOperation::TimeSignalRequest(TimeSignalRequest {
pre_roll_time: 2000,
}),
},
];
// Build the multi-op message.
let msg = MultipleOperationMessage::new(
0, // protocol_version
1, // AS_index
42, // message_number
0, // DPI_PID_index
0, // SCTE35_protocol_version
Timestamp::None, // immediate processing
ops,
);
// Serialize.
let bytes = msg.to_bytes();
println!(
"Serialized {} bytes with {} ops",
bytes.len(),
msg.operations.len()
);
// Round-trip.
let parsed = MultipleOperationMessage::parse(&bytes).unwrap();
assert_eq!(msg, parsed);
assert_eq!(parsed.operations.len(), 2);
println!("Round-trip OK: 2 operations preserved");
// Verify operations are correctly parsed.
for op in &parsed.operations {
println!(" opID {:#06x}: {}", op.op_id, op.data.name());
}
// Demonstrate mutation detection.
let mut msg2 = msg.clone();
msg2.message_number = 99;
assert_ne!(msg.to_bytes(), msg2.to_bytes());
println!("Mutation changes output: OK");
}Re-exports§
pub use error::Error;pub use error::Result;pub use multi::MultipleOperationMessage;pub use single::SingleOperationMessage;
Modules§
- error
- Error types for the scte104 crate.
- multi
- Multiple operation message framing — ANSI/SCTE 104 2023 §8.2.3, Table 8-2.
- operations
- SCTE 104 operations (request/response data structures).
- single
- Single operation message framing — ANSI/SCTE 104 2023 §8.2.2, Table 8-1.
- time
- Time structures — ANSI/SCTE 104 2023 §12.4, §12.5.
- traits
- SCTE 104 dispatch traits, mirroring scte35-splice’s
CommandDef.