feat: live TV time-shift
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/// Represents the seekable capture buffer for a live TV transcode session.
|
||||
///
|
||||
/// Extracted from the `TranscodeSession` element in the tune response:
|
||||
/// - [startedAt] = `timeStamp` (epoch seconds, the buffer origin)
|
||||
/// - [seekStartSeconds] = `minOffsetAvailable` (earliest seekable offset)
|
||||
/// - [seekEndSeconds] = `maxOffsetAvailable` (latest seekable offset / live edge)
|
||||
class CaptureBuffer {
|
||||
final double startedAt;
|
||||
final double seekStartSeconds;
|
||||
final double seekEndSeconds;
|
||||
|
||||
const CaptureBuffer({
|
||||
required this.startedAt,
|
||||
required this.seekStartSeconds,
|
||||
required this.seekEndSeconds,
|
||||
});
|
||||
|
||||
/// Absolute epoch second of the earliest seekable point.
|
||||
int get seekableStartEpoch => (startedAt + seekStartSeconds).round();
|
||||
|
||||
/// Absolute epoch second of the latest seekable point (≈ live edge).
|
||||
int get seekableEndEpoch => (startedAt + seekEndSeconds).round();
|
||||
|
||||
/// Duration of the seekable range in seconds.
|
||||
int get seekableDurationSeconds => (seekEndSeconds - seekStartSeconds).round();
|
||||
|
||||
/// Parse from a TranscodeSession JSON map. Returns null if required fields are missing.
|
||||
/// Values may be num or String depending on whether the server returned JSON or XML.
|
||||
static CaptureBuffer? fromTranscodeSession(Map<String, dynamic> session) {
|
||||
final timeStamp = _parseDouble(session['timeStamp']);
|
||||
final minOffset = _parseDouble(session['minOffsetAvailable']);
|
||||
final maxOffset = _parseDouble(session['maxOffsetAvailable']);
|
||||
if (timeStamp == null || minOffset == null || maxOffset == null) return null;
|
||||
return CaptureBuffer(
|
||||
startedAt: timeStamp,
|
||||
seekStartSeconds: minOffset,
|
||||
seekEndSeconds: maxOffset,
|
||||
);
|
||||
}
|
||||
|
||||
static double? _parseDouble(dynamic value) {
|
||||
if (value is num) return value.toDouble();
|
||||
if (value is String) return double.tryParse(value);
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'CaptureBuffer(startedAt: $startedAt, seek: $seekStartSeconds..$seekEndSeconds, '
|
||||
'range: $seekableStartEpoch..$seekableEndEpoch)';
|
||||
}
|
||||
Reference in New Issue
Block a user