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 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 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 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 subtitles; final int? defaultSubtitleIndex; final List 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 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'}, ], }; }