Files
2026-07-14 11:11:36 +08:00

182 lines
4.7 KiB
Dart

import 'package:freezed_annotation/freezed_annotation.dart';
import 'library.dart';
part 'playback.freezed.dart';
part 'playback.g.dart';
@freezed
abstract class PlaybackRequestPayload with _$PlaybackRequestPayload {
const factory PlaybackRequestPayload({
required String itemId,
@JsonKey(includeIfNull: false) String? itemType,
@JsonKey(includeIfNull: false) String? mediaSourceId,
@JsonKey(includeIfNull: false) int? startPositionTicks,
@Default(false) bool playFromStart,
}) = _PlaybackRequestPayload;
factory PlaybackRequestPayload.fromJson(Map<String, dynamic> json) =>
_$PlaybackRequestPayloadFromJson(json);
}
@freezed
abstract class EmbySubtitleTrack with _$EmbySubtitleTrack {
const factory EmbySubtitleTrack({
@JsonKey(fromJson: _intRequired) required int index,
@JsonKey(includeIfNull: false) String? title,
@JsonKey(includeIfNull: false) String? language,
@JsonKey(fromJson: _boolOrFalse) @Default(false) bool isDefault,
@JsonKey(fromJson: _boolOrFalse) @Default(false) bool isForced,
@JsonKey(fromJson: _boolOrFalse) @Default(false) bool isExternal,
@JsonKey(includeIfNull: false) String? deliveryUrl,
@JsonKey(includeIfNull: false) String? codec,
}) = _EmbySubtitleTrack;
factory EmbySubtitleTrack.fromJson(Map<String, dynamic> json) =>
_$EmbySubtitleTrackFromJson(json);
}
@freezed
abstract class EmbyAudioTrack with _$EmbyAudioTrack {
const factory EmbyAudioTrack({
@JsonKey(fromJson: _intRequired) required int index,
@JsonKey(includeIfNull: false) String? title,
@JsonKey(includeIfNull: false) String? language,
@JsonKey(includeIfNull: false) String? codec,
@JsonKey(fromJson: _intOrNull, includeIfNull: false) int? channels,
@JsonKey(includeIfNull: false) String? displayTitle,
@JsonKey(fromJson: _boolOrFalse) @Default(false) bool isDefault,
}) = _EmbyAudioTrack;
factory EmbyAudioTrack.fromJson(Map<String, dynamic> json) =>
_$EmbyAudioTrackFromJson(json);
}
int _intRequired(Object? value) => (value as num).toInt();
int? _intOrNull(Object? value) => (value as num?)?.toInt();
bool _boolOrFalse(Object? value) => (value as bool?) ?? false;
class PlaybackRequestResult {
final String streamUrl;
final String? container;
final String? mimeType;
final bool directStream;
final EmbyRawItem item;
final EmbyRawMediaSource? mediaSource;
final double startPositionSeconds;
final double? durationSeconds;
final List<EmbySubtitleTrack> subtitles;
final int? defaultSubtitleIndex;
final List<EmbyAudioTrack> audioTracks;
final int? defaultAudioStreamIndex;
final String? playSessionId;
final String playMethod;
const PlaybackRequestResult({
required this.streamUrl,
this.container,
this.mimeType,
required this.directStream,
required this.item,
this.mediaSource,
this.startPositionSeconds = 0,
this.durationSeconds,
this.subtitles = const [],
this.defaultSubtitleIndex,
this.audioTracks = const [],
this.defaultAudioStreamIndex,
this.playSessionId,
this.playMethod = 'DirectStream',
});
}
class PlaybackReportPayload {
final String itemId;
final String? mediaSourceId;
final String? playSessionId;
final int positionTicks;
final int? runTimeTicks;
final String playMethod;
final bool canSeek;
final bool isPaused;
final bool isMuted;
final double playbackRate;
final int playlistIndex;
final int playlistLength;
final String repeatMode;
final String? eventName;
const PlaybackReportPayload({
required this.itemId,
this.mediaSourceId,
this.playSessionId,
required this.positionTicks,
this.runTimeTicks,
this.playMethod = 'DirectStream',
this.canSeek = true,
this.isPaused = false,
this.isMuted = false,
this.playbackRate = 1,
this.playlistIndex = 0,
this.playlistLength = 1,
this.repeatMode = 'RepeatNone',
this.eventName,
});
Map<String, dynamic> toJson({bool includeNowPlayingQueue = false}) => {
'ItemId': itemId,
if (mediaSourceId != null && mediaSourceId!.isNotEmpty)
'MediaSourceId': mediaSourceId,
if (playSessionId != null && playSessionId!.isNotEmpty)
'PlaySessionId': playSessionId,
'PositionTicks': positionTicks,
if (runTimeTicks != null) 'RunTimeTicks': runTimeTicks,
'CanSeek': canSeek,
'PlayMethod': playMethod,
'PlaylistIndex': playlistIndex,
'PlaylistLength': playlistLength,
'PlaybackRate': playbackRate,
'IsMuted': isMuted,
'IsPaused': isPaused,
'RepeatMode': repeatMode,
if (eventName != null && eventName!.isNotEmpty) 'EventName': eventName,
if (includeNowPlayingQueue)
'NowPlayingQueue': [
{'Id': itemId, 'PlaylistItemId': 'playlistItem$playlistIndex'},
],
};
}