feature: Video quality options (#234)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2025-02-23 13:29:59 +01:00 committed by GitHub
parent 957ad6c991
commit 935d6fe176
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 644 additions and 232 deletions

View file

@ -157,6 +157,7 @@ class StreamModel {
class VideoStreamModel extends StreamModel {
final int width;
final int height;
final int? bitRate;
final double frameRate;
final String? videoDoViTitle;
final VideoRangeType? videoRangeType;
@ -168,6 +169,7 @@ class VideoStreamModel extends StreamModel {
required super.index,
required this.videoDoViTitle,
required this.videoRangeType,
required this.bitRate,
required this.width,
required this.height,
required this.frameRate,
@ -179,6 +181,7 @@ class VideoStreamModel extends StreamModel {
isDefault: stream.isDefault ?? false,
codec: stream.codec ?? "",
videoDoViTitle: stream.videoDoViTitle,
bitRate: stream.bitRate,
videoRangeType: stream.videoRangeType,
width: stream.width ?? 0,
height: stream.height ?? 0,

View file

@ -12,52 +12,23 @@ import 'package:fladder/models/items/trick_play_model.dart';
import 'package:fladder/models/playback/playback_model.dart';
import 'package:fladder/providers/api_provider.dart';
import 'package:fladder/providers/video_player_provider.dart';
import 'package:fladder/util/bitrate_helper.dart';
import 'package:fladder/util/duration_extensions.dart';
import 'package:fladder/util/list_extensions.dart';
import 'package:fladder/wrappers/media_control_wrapper.dart';
class DirectPlaybackModel implements PlaybackModel {
class DirectPlaybackModel extends PlaybackModel {
DirectPlaybackModel({
required this.item,
required this.media,
required this.playbackInfo,
this.mediaStreams,
this.mediaSegments,
this.chapters,
this.trickPlay,
this.queue = const [],
required super.item,
required super.media,
super.playbackInfo,
super.mediaStreams,
super.mediaSegments,
super.chapters,
super.trickPlay,
super.queue,
super.bitRateOptions,
});
@override
final ItemBaseModel item;
@override
final Media? media;
@override
final PlaybackInfoResponse playbackInfo;
@override
final MediaStreamsModel? mediaStreams;
@override
final MediaSegmentsModel? mediaSegments;
@override
final List<Chapter>? chapters;
@override
final TrickPlayModel? trickPlay;
@override
ItemBaseModel? get nextVideo => queue.nextOrNull(item);
@override
ItemBaseModel? get previousVideo => queue.previousOrNull(item);
@override
Future<Duration>? startDuration() async => item.userData.playBackPosition;
@override
List<SubStreamModel> get subStreams => [SubStreamModel.no(), ...mediaStreams?.subStreams ?? []];
@ -79,6 +50,11 @@ class DirectPlaybackModel implements PlaybackModel {
return copyWith(mediaStreams: () => mediaStreams?.copyWith(defaultAudioStreamIndex: newIndex));
}
@override
Future<DirectPlaybackModel>? setQualityOption(Map<Bitrate, bool> map) async {
return copyWith(bitRateOptions: map);
}
@override
Future<PlaybackModel?> playbackStarted(Duration position, Ref ref) async {
await ref.read(jellyApiProvider).sessionsPlayingPost(
@ -86,7 +62,7 @@ class DirectPlaybackModel implements PlaybackModel {
canSeek: true,
itemId: item.id,
mediaSourceId: item.id,
playSessionId: playbackInfo.playSessionId,
playSessionId: playbackInfo?.playSessionId,
subtitleStreamIndex: item.streamModel?.defaultSubStreamIndex,
audioStreamIndex: item.streamModel?.defaultAudioStreamIndex,
volumeLevel: 100,
@ -108,7 +84,7 @@ class DirectPlaybackModel implements PlaybackModel {
body: PlaybackStopInfo(
itemId: item.id,
mediaSourceId: item.id,
playSessionId: playbackInfo.playSessionId,
playSessionId: playbackInfo?.playSessionId,
positionTicks: position.toRuntimeTicks,
),
);
@ -124,7 +100,7 @@ class DirectPlaybackModel implements PlaybackModel {
canSeek: true,
itemId: item.id,
mediaSourceId: item.id,
playSessionId: playbackInfo.playSessionId,
playSessionId: playbackInfo?.playSessionId,
subtitleStreamIndex: item.streamModel?.defaultSubStreamIndex,
audioStreamIndex: item.streamModel?.defaultAudioStreamIndex,
volumeLevel: 100,
@ -142,9 +118,6 @@ class DirectPlaybackModel implements PlaybackModel {
@override
String toString() => 'DirectPlaybackModel(item: $item, playbackInfo: $playbackInfo)';
@override
final List<ItemBaseModel> queue;
@override
DirectPlaybackModel copyWith({
ItemBaseModel? item,
@ -156,6 +129,7 @@ class DirectPlaybackModel implements PlaybackModel {
ValueGetter<List<Chapter>?>? chapters,
ValueGetter<TrickPlayModel?>? trickPlay,
List<ItemBaseModel>? queue,
Map<Bitrate, bool>? bitRateOptions,
}) {
return DirectPlaybackModel(
item: item ?? this.item,
@ -166,6 +140,7 @@ class DirectPlaybackModel implements PlaybackModel {
chapters: chapters != null ? chapters() : this.chapters,
trickPlay: trickPlay != null ? trickPlay() : this.trickPlay,
queue: queue ?? this.queue,
bitRateOptions: bitRateOptions ?? this.bitRateOptions,
);
}
}

View file

@ -2,7 +2,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
import 'package:fladder/models/item_base_model.dart';
import 'package:fladder/models/items/chapters_model.dart';
import 'package:fladder/models/items/media_segments_model.dart';
@ -15,42 +14,24 @@ import 'package:fladder/util/duration_extensions.dart';
import 'package:fladder/util/list_extensions.dart';
import 'package:fladder/wrappers/media_control_wrapper.dart';
class OfflinePlaybackModel implements PlaybackModel {
class OfflinePlaybackModel extends PlaybackModel {
OfflinePlaybackModel({
required this.item,
required this.media,
required this.syncedItem,
this.mediaStreams,
this.playbackInfo,
this.mediaSegments,
this.trickPlay,
this.queue = const [],
super.mediaStreams,
super.playbackInfo,
required super.item,
required super.media,
super.mediaSegments,
super.trickPlay,
super.queue = const [],
this.syncedQueue = const [],
});
@override
final ItemBaseModel item;
@override
final PlaybackInfoResponse? playbackInfo;
@override
final Media? media;
final SyncedItem syncedItem;
@override
final MediaStreamsModel? mediaStreams;
@override
final MediaSegmentsModel? mediaSegments;
@override
List<Chapter>? get chapters => syncedItem.chapters;
@override
final TrickPlayModel? trickPlay;
@override
Future<Duration>? startDuration() async => item.userData.playBackPosition;
@ -118,9 +99,6 @@ class OfflinePlaybackModel implements PlaybackModel {
@override
String toString() => 'OfflinePlaybackModel(item: $item, syncedItem: $syncedItem)';
@override
final List<ItemBaseModel> queue;
final List<SyncedItem> syncedQueue;
@override

View file

@ -22,11 +22,15 @@ import 'package:fladder/models/video_stream_model.dart';
import 'package:fladder/profiles/default_profile.dart';
import 'package:fladder/providers/api_provider.dart';
import 'package:fladder/providers/service_provider.dart';
import 'package:fladder/providers/settings/video_player_settings_provider.dart';
import 'package:fladder/providers/sync/sync_provider_helpers.dart';
import 'package:fladder/providers/sync_provider.dart';
import 'package:fladder/providers/user_provider.dart';
import 'package:fladder/providers/video_player_provider.dart';
import 'package:fladder/util/bitrate_helper.dart';
import 'package:fladder/util/duration_extensions.dart';
import 'package:fladder/util/list_extensions.dart';
import 'package:fladder/util/map_bool_helper.dart';
import 'package:fladder/wrappers/media_control_wrapper.dart';
class Media {
@ -52,15 +56,17 @@ extension PlaybackModelExtension on PlaybackModel? {
};
}
abstract class PlaybackModel {
final ItemBaseModel item = throw UnimplementedError();
final Media? media = throw UnimplementedError();
final List<ItemBaseModel> queue = const [];
final MediaSegmentsModel? mediaSegments = null;
final PlaybackInfoResponse? playbackInfo = throw UnimplementedError();
class PlaybackModel {
final ItemBaseModel item;
final Media? media;
final List<ItemBaseModel> queue;
final MediaSegmentsModel? mediaSegments;
final PlaybackInfoResponse? playbackInfo;
List<Chapter>? get chapters;
TrickPlayModel? get trickPlay;
Map<Bitrate, bool> bitRateOptions;
List<Chapter>? chapters = [];
TrickPlayModel? trickPlay;
Future<PlaybackModel?> updatePlaybackPosition(Duration position, bool isPlaying, Ref ref) =>
throw UnimplementedError();
@ -68,21 +74,32 @@ abstract class PlaybackModel {
Future<PlaybackModel?> playbackStopped(Duration position, Duration? totalDuration, Ref ref) =>
throw UnimplementedError();
final MediaStreamsModel? mediaStreams = throw UnimplementedError();
List<SubStreamModel>? get subStreams;
List<AudioStreamModel>? get audioStreams;
final MediaStreamsModel? mediaStreams;
List<SubStreamModel>? get subStreams => throw UnimplementedError();
List<AudioStreamModel>? get audioStreams => throw UnimplementedError();
Future<Duration>? startDuration() async => item.userData.playBackPosition;
Future<PlaybackModel>? setSubtitle(SubStreamModel? model, MediaControlsWrapper player) {
return null;
}
Future<PlaybackModel>? setAudio(AudioStreamModel? model, MediaControlsWrapper player) => null;
Future<PlaybackModel>? setSubtitle(SubStreamModel? model, MediaControlsWrapper player) => throw UnimplementedError();
Future<PlaybackModel>? setAudio(AudioStreamModel? model, MediaControlsWrapper player) => throw UnimplementedError();
Future<PlaybackModel>? setQualityOption(Map<Bitrate, bool> map) => throw UnimplementedError();
ItemBaseModel? get nextVideo => throw UnimplementedError();
ItemBaseModel? get previousVideo => throw UnimplementedError();
ItemBaseModel? get nextVideo => queue.nextOrNull(item);
ItemBaseModel? get previousVideo => queue.previousOrNull(item);
PlaybackModel copyWith();
PlaybackModel copyWith() => throw UnimplementedError();
PlaybackModel({
required this.playbackInfo,
this.mediaStreams,
required this.item,
required this.media,
this.queue = const [],
this.bitRateOptions = const {},
this.mediaSegments,
this.chapters,
this.trickPlay,
});
}
final playbackModelHelper = Provider<PlaybackModelHelper>((ref) {
@ -149,8 +166,13 @@ class PlaybackModelHelper {
}
}
Future<PlaybackModel?> createServerPlaybackModel(ItemBaseModel? item, PlaybackType? type,
{PlaybackModel? oldModel, List<ItemBaseModel>? libraryQueue, Duration? startPosition}) async {
Future<PlaybackModel?> createServerPlaybackModel(
ItemBaseModel? item,
PlaybackType? type, {
PlaybackModel? oldModel,
List<ItemBaseModel>? libraryQueue,
Duration? startPosition,
}) async {
try {
if (item == null) return null;
final userId = ref.read(userProvider)?.id;
@ -165,18 +187,18 @@ class PlaybackModelHelper {
final fullItem = await api.usersUserIdItemsItemIdGet(itemId: firstItemToPlay.id);
Map<Bitrate, bool> qualityOptions = getVideoQualityOptions(
VideoQualitySettings(
maxBitRate: ref.read(videoPlayerSettingsProvider.select((value) => value.maxHomeBitrate)),
videoBitRate: firstItemToPlay.streamModel?.videoStreams.first.bitRate ?? 0,
videoCodec: firstItemToPlay.streamModel?.videoStreams.first.codec,
),
);
final streamModel = firstItemToPlay.streamModel;
Response<PlaybackInfoResponse> response = await api.itemsItemIdPlaybackInfoPost(
final Response<PlaybackInfoResponse> response = await api.itemsItemIdPlaybackInfoPost(
itemId: firstItemToPlay.id,
enableDirectPlay: type != PlaybackType.transcode,
enableDirectStream: type != PlaybackType.transcode,
enableTranscoding: true,
autoOpenLiveStream: true,
startTimeTicks: startPosition?.toRuntimeTicks,
audioStreamIndex: streamModel?.defaultAudioStreamIndex,
subtitleStreamIndex: streamModel?.defaultSubStreamIndex,
mediaSourceId: firstItemToPlay.id,
body: PlaybackInfoDto(
startTimeTicks: startPosition?.toRuntimeTicks,
audioStreamIndex: streamModel?.defaultAudioStreamIndex,
@ -185,6 +207,9 @@ class PlaybackModelHelper {
autoOpenLiveStream: true,
deviceProfile: ref.read(videoProfileProvider),
userId: userId,
enableDirectPlay: type != PlaybackType.transcode,
enableDirectStream: type != PlaybackType.transcode,
maxStreamingBitrate: qualityOptions.enabledFirst.keys.firstOrNull?.bitRate,
mediaSourceId: firstItemToPlay.id,
),
);
@ -234,10 +259,9 @@ class PlaybackModelHelper {
chapters: chapters,
playbackInfo: playbackInfo,
trickPlay: trickPlay,
media: Media(
url: mediaPath ?? playbackUrl,
),
media: Media(url: mediaPath ?? playbackUrl),
mediaStreams: mediaStreamsWithUrls,
bitRateOptions: qualityOptions,
);
} else if ((mediaSource.supportsTranscoding ?? false) && mediaSource.transcodingUrl != null) {
return TranscodePlaybackModel(
@ -309,22 +333,17 @@ class PlaybackModelHelper {
Response<PlaybackInfoResponse> response = await api.itemsItemIdPlaybackInfoPost(
itemId: item.id,
enableDirectPlay: true,
enableDirectStream: true,
enableTranscoding: true,
autoOpenLiveStream: true,
startTimeTicks: currentPosition.toRuntimeTicks,
audioStreamIndex: audioIndex,
subtitleStreamIndex: subIndex,
mediaSourceId: item.id,
body: PlaybackInfoDto(
startTimeTicks: currentPosition.toRuntimeTicks,
audioStreamIndex: audioIndex,
enableDirectPlay: true,
enableDirectStream: true,
subtitleStreamIndex: subIndex,
enableTranscoding: true,
autoOpenLiveStream: true,
deviceProfile: ref.read(videoProfileProvider),
userId: userId,
maxStreamingBitrate: playbackModel.bitRateOptions.enabledFirst.entries.firstOrNull?.key.bitRate,
mediaSourceId: item.id,
),
);
@ -363,6 +382,8 @@ class PlaybackModelHelper {
final directPlay = '${ref.read(userProvider)?.server ?? ""}/Videos/${mediaSource.id}/stream?$params';
final mediaPath = isValidVideoUrl(mediaSource.path ?? "");
newModel = DirectPlaybackModel(
item: playbackModel.item,
queue: playbackModel.queue,
@ -370,8 +391,9 @@ class PlaybackModelHelper {
chapters: playbackModel.chapters,
playbackInfo: playbackInfo,
trickPlay: playbackModel.trickPlay,
media: Media(url: directPlay),
media: Media(url: mediaPath ?? directPlay),
mediaStreams: mediaStreamsWithUrls,
bitRateOptions: playbackModel.bitRateOptions,
);
} else if ((mediaSource.supportsTranscoding ?? false) && mediaSource.transcodingUrl != null) {
newModel = TranscodePlaybackModel(
@ -383,6 +405,7 @@ class PlaybackModelHelper {
trickPlay: playbackModel.trickPlay,
media: Media(url: "${ref.read(userProvider)?.server ?? ""}${mediaSource.transcodingUrl ?? ""}"),
mediaStreams: mediaStreamsWithUrls,
bitRateOptions: playbackModel.bitRateOptions,
);
}
if (newModel == null) return;

View file

@ -12,52 +12,23 @@ import 'package:fladder/models/items/trick_play_model.dart';
import 'package:fladder/models/playback/playback_model.dart';
import 'package:fladder/providers/api_provider.dart';
import 'package:fladder/providers/video_player_provider.dart';
import 'package:fladder/util/bitrate_helper.dart';
import 'package:fladder/util/duration_extensions.dart';
import 'package:fladder/util/list_extensions.dart';
import 'package:fladder/wrappers/media_control_wrapper.dart';
class TranscodePlaybackModel implements PlaybackModel {
class TranscodePlaybackModel extends PlaybackModel {
TranscodePlaybackModel({
required this.item,
required this.media,
required this.playbackInfo,
this.mediaStreams,
this.mediaSegments,
this.chapters,
this.trickPlay,
this.queue = const [],
required super.item,
required super.media,
required super.playbackInfo,
super.mediaStreams,
super.mediaSegments,
super.chapters,
super.trickPlay,
super.queue = const [],
super.bitRateOptions,
});
@override
final ItemBaseModel item;
@override
final Media? media;
@override
final PlaybackInfoResponse playbackInfo;
@override
final MediaStreamsModel? mediaStreams;
@override
final MediaSegmentsModel? mediaSegments;
@override
final List<Chapter>? chapters;
@override
final TrickPlayModel? trickPlay;
@override
ItemBaseModel? get nextVideo => queue.nextOrNull(item);
@override
ItemBaseModel? get previousVideo => queue.previousOrNull(item);
@override
Future<Duration>? startDuration() async => item.userData.playBackPosition;
@override
List<SubStreamModel> get subStreams => [SubStreamModel.no(), ...mediaStreams?.subStreams ?? []];
@ -79,6 +50,9 @@ class TranscodePlaybackModel implements PlaybackModel {
return copyWith(mediaStreams: () => mediaStreams?.copyWith(defaultAudioStreamIndex: newIndex));
}
@override
Future<TranscodePlaybackModel>? setQualityOption(Map<Bitrate, bool> map) async => copyWith(bitRateOptions: map);
@override
Future<PlaybackModel?> playbackStarted(Duration position, Ref ref) async {
await ref.read(jellyApiProvider).sessionsPlayingPost(
@ -86,8 +60,8 @@ class TranscodePlaybackModel implements PlaybackModel {
canSeek: true,
itemId: item.id,
mediaSourceId: item.id,
playSessionId: playbackInfo.playSessionId,
sessionId: playbackInfo.playSessionId,
playSessionId: playbackInfo?.playSessionId,
sessionId: playbackInfo?.playSessionId,
subtitleStreamIndex: item.streamModel?.defaultSubStreamIndex,
audioStreamIndex: item.streamModel?.defaultAudioStreamIndex,
volumeLevel: 100,
@ -109,7 +83,7 @@ class TranscodePlaybackModel implements PlaybackModel {
body: PlaybackStopInfo(
itemId: item.id,
mediaSourceId: item.id,
playSessionId: playbackInfo.playSessionId,
playSessionId: playbackInfo?.playSessionId,
positionTicks: position.toRuntimeTicks,
),
);
@ -125,8 +99,8 @@ class TranscodePlaybackModel implements PlaybackModel {
canSeek: true,
itemId: item.id,
mediaSourceId: item.id,
playSessionId: playbackInfo.playSessionId,
sessionId: playbackInfo.playSessionId,
playSessionId: playbackInfo?.playSessionId,
sessionId: playbackInfo?.playSessionId,
subtitleStreamIndex: item.streamModel?.defaultSubStreamIndex,
audioStreamIndex: item.streamModel?.defaultAudioStreamIndex,
volumeLevel: 100,
@ -143,9 +117,6 @@ class TranscodePlaybackModel implements PlaybackModel {
@override
String toString() => 'TranscodePlaybackModel(item: $item, playbackInfo: $playbackInfo)';
@override
final List<ItemBaseModel> queue;
@override
TranscodePlaybackModel copyWith({
ItemBaseModel? item,
@ -157,6 +128,7 @@ class TranscodePlaybackModel implements PlaybackModel {
ValueGetter<List<Chapter>?>? chapters,
ValueGetter<TrickPlayModel?>? trickPlay,
List<ItemBaseModel>? queue,
Map<Bitrate, bool>? bitRateOptions,
}) {
return TranscodePlaybackModel(
item: item ?? this.item,
@ -167,6 +139,7 @@ class TranscodePlaybackModel implements PlaybackModel {
chapters: chapters != null ? chapters() : this.chapters,
trickPlay: trickPlay != null ? trickPlay() : this.trickPlay,
queue: queue ?? this.queue,
bitRateOptions: bitRateOptions ?? this.bitRateOptions,
);
}
}

View file

@ -48,6 +48,11 @@ enum ViewSize {
ViewSize.tablet => context.localized.tablet,
ViewSize.desktop => context.localized.desktop,
};
bool operator >(ViewSize other) => index > other.index;
bool operator >=(ViewSize other) => index >= other.index;
bool operator <(ViewSize other) => index < other.index;
bool operator <=(ViewSize other) => index <= other.index;
}
enum LayoutMode {
@ -60,6 +65,11 @@ enum LayoutMode {
LayoutMode.single => context.localized.layoutModeSingle,
LayoutMode.dual => context.localized.layoutModeDual,
};
bool operator >(ViewSize other) => index > other.index;
bool operator >=(ViewSize other) => index >= other.index;
bool operator <(ViewSize other) => index < other.index;
bool operator <=(ViewSize other) => index <= other.index;
}
enum HomeBanner {

View file

@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:fladder/util/bitrate_helper.dart';
import 'package:fladder/util/localization_helper.dart';
part 'video_player_settings.freezed.dart';
@ -24,6 +25,8 @@ class VideoPlayerSettingsModel with _$VideoPlayerSettingsModel {
@Default(100) double internalVolume,
Set<DeviceOrientation>? allowedOrientations,
@Default(AutoNextType.smart) AutoNextType nextVideoType,
@Default(Bitrate.original) Bitrate maxHomeBitrate,
@Default(Bitrate.original) Bitrate maxInternetBitrate,
String? audioDevice,
}) = _VideoPlayerSettingsModel;

View file

@ -31,6 +31,8 @@ mixin _$VideoPlayerSettingsModel {
Set<DeviceOrientation>? get allowedOrientations =>
throw _privateConstructorUsedError;
AutoNextType get nextVideoType => throw _privateConstructorUsedError;
Bitrate get maxHomeBitrate => throw _privateConstructorUsedError;
Bitrate get maxInternetBitrate => throw _privateConstructorUsedError;
String? get audioDevice => throw _privateConstructorUsedError;
/// Serializes this VideoPlayerSettingsModel to a JSON map.
@ -59,6 +61,8 @@ abstract class $VideoPlayerSettingsModelCopyWith<$Res> {
double internalVolume,
Set<DeviceOrientation>? allowedOrientations,
AutoNextType nextVideoType,
Bitrate maxHomeBitrate,
Bitrate maxInternetBitrate,
String? audioDevice});
}
@ -87,6 +91,8 @@ class _$VideoPlayerSettingsModelCopyWithImpl<$Res,
Object? internalVolume = null,
Object? allowedOrientations = freezed,
Object? nextVideoType = null,
Object? maxHomeBitrate = null,
Object? maxInternetBitrate = null,
Object? audioDevice = freezed,
}) {
return _then(_value.copyWith(
@ -126,6 +132,14 @@ class _$VideoPlayerSettingsModelCopyWithImpl<$Res,
? _value.nextVideoType
: nextVideoType // ignore: cast_nullable_to_non_nullable
as AutoNextType,
maxHomeBitrate: null == maxHomeBitrate
? _value.maxHomeBitrate
: maxHomeBitrate // ignore: cast_nullable_to_non_nullable
as Bitrate,
maxInternetBitrate: null == maxInternetBitrate
? _value.maxInternetBitrate
: maxInternetBitrate // ignore: cast_nullable_to_non_nullable
as Bitrate,
audioDevice: freezed == audioDevice
? _value.audioDevice
: audioDevice // ignore: cast_nullable_to_non_nullable
@ -153,6 +167,8 @@ abstract class _$$VideoPlayerSettingsModelImplCopyWith<$Res>
double internalVolume,
Set<DeviceOrientation>? allowedOrientations,
AutoNextType nextVideoType,
Bitrate maxHomeBitrate,
Bitrate maxInternetBitrate,
String? audioDevice});
}
@ -180,6 +196,8 @@ class __$$VideoPlayerSettingsModelImplCopyWithImpl<$Res>
Object? internalVolume = null,
Object? allowedOrientations = freezed,
Object? nextVideoType = null,
Object? maxHomeBitrate = null,
Object? maxInternetBitrate = null,
Object? audioDevice = freezed,
}) {
return _then(_$VideoPlayerSettingsModelImpl(
@ -219,6 +237,14 @@ class __$$VideoPlayerSettingsModelImplCopyWithImpl<$Res>
? _value.nextVideoType
: nextVideoType // ignore: cast_nullable_to_non_nullable
as AutoNextType,
maxHomeBitrate: null == maxHomeBitrate
? _value.maxHomeBitrate
: maxHomeBitrate // ignore: cast_nullable_to_non_nullable
as Bitrate,
maxInternetBitrate: null == maxInternetBitrate
? _value.maxInternetBitrate
: maxInternetBitrate // ignore: cast_nullable_to_non_nullable
as Bitrate,
audioDevice: freezed == audioDevice
? _value.audioDevice
: audioDevice // ignore: cast_nullable_to_non_nullable
@ -241,6 +267,8 @@ class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
this.internalVolume = 100,
final Set<DeviceOrientation>? allowedOrientations,
this.nextVideoType = AutoNextType.smart,
this.maxHomeBitrate = Bitrate.original,
this.maxInternetBitrate = Bitrate.original,
this.audioDevice})
: _allowedOrientations = allowedOrientations,
super._();
@ -282,11 +310,17 @@ class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
@JsonKey()
final AutoNextType nextVideoType;
@override
@JsonKey()
final Bitrate maxHomeBitrate;
@override
@JsonKey()
final Bitrate maxInternetBitrate;
@override
final String? audioDevice;
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return 'VideoPlayerSettingsModel(screenBrightness: $screenBrightness, videoFit: $videoFit, fillScreen: $fillScreen, hardwareAccel: $hardwareAccel, useLibass: $useLibass, playerOptions: $playerOptions, internalVolume: $internalVolume, allowedOrientations: $allowedOrientations, nextVideoType: $nextVideoType, audioDevice: $audioDevice)';
return 'VideoPlayerSettingsModel(screenBrightness: $screenBrightness, videoFit: $videoFit, fillScreen: $fillScreen, hardwareAccel: $hardwareAccel, useLibass: $useLibass, playerOptions: $playerOptions, internalVolume: $internalVolume, allowedOrientations: $allowedOrientations, nextVideoType: $nextVideoType, maxHomeBitrate: $maxHomeBitrate, maxInternetBitrate: $maxInternetBitrate, audioDevice: $audioDevice)';
}
@override
@ -303,6 +337,8 @@ class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
..add(DiagnosticsProperty('internalVolume', internalVolume))
..add(DiagnosticsProperty('allowedOrientations', allowedOrientations))
..add(DiagnosticsProperty('nextVideoType', nextVideoType))
..add(DiagnosticsProperty('maxHomeBitrate', maxHomeBitrate))
..add(DiagnosticsProperty('maxInternetBitrate', maxInternetBitrate))
..add(DiagnosticsProperty('audioDevice', audioDevice));
}
@ -334,6 +370,8 @@ abstract class _VideoPlayerSettingsModel extends VideoPlayerSettingsModel {
final double internalVolume,
final Set<DeviceOrientation>? allowedOrientations,
final AutoNextType nextVideoType,
final Bitrate maxHomeBitrate,
final Bitrate maxInternetBitrate,
final String? audioDevice}) = _$VideoPlayerSettingsModelImpl;
_VideoPlayerSettingsModel._() : super._();
@ -359,6 +397,10 @@ abstract class _VideoPlayerSettingsModel extends VideoPlayerSettingsModel {
@override
AutoNextType get nextVideoType;
@override
Bitrate get maxHomeBitrate;
@override
Bitrate get maxInternetBitrate;
@override
String? get audioDevice;
/// Create a copy of VideoPlayerSettingsModel

View file

@ -24,6 +24,12 @@ _$VideoPlayerSettingsModelImpl _$$VideoPlayerSettingsModelImplFromJson(
nextVideoType:
$enumDecodeNullable(_$AutoNextTypeEnumMap, json['nextVideoType']) ??
AutoNextType.smart,
maxHomeBitrate:
$enumDecodeNullable(_$BitrateEnumMap, json['maxHomeBitrate']) ??
Bitrate.original,
maxInternetBitrate:
$enumDecodeNullable(_$BitrateEnumMap, json['maxInternetBitrate']) ??
Bitrate.original,
audioDevice: json['audioDevice'] as String?,
);
@ -41,6 +47,8 @@ Map<String, dynamic> _$$VideoPlayerSettingsModelImplToJson(
?.map((e) => _$DeviceOrientationEnumMap[e]!)
.toList(),
'nextVideoType': _$AutoNextTypeEnumMap[instance.nextVideoType]!,
'maxHomeBitrate': _$BitrateEnumMap[instance.maxHomeBitrate]!,
'maxInternetBitrate': _$BitrateEnumMap[instance.maxInternetBitrate]!,
'audioDevice': instance.audioDevice,
};
@ -71,3 +79,22 @@ const _$AutoNextTypeEnumMap = {
AutoNextType.smart: 'smart',
AutoNextType.static: 'static',
};
const _$BitrateEnumMap = {
Bitrate.original: 'original',
Bitrate.auto: 'auto',
Bitrate.b120Mbps: 'b120Mbps',
Bitrate.b80Mbps: 'b80Mbps',
Bitrate.b60Mbps: 'b60Mbps',
Bitrate.b40Mbps: 'b40Mbps',
Bitrate.b20Mbps: 'b20Mbps',
Bitrate.b15Mbps: 'b15Mbps',
Bitrate.b10Mbps: 'b10Mbps',
Bitrate.b8Mbps: 'b8Mbps',
Bitrate.b6Mbps: 'b6Mbps',
Bitrate.b4Mbps: 'b4Mbps',
Bitrate.b3Mbps: 'b3Mbps',
Bitrate.b1_5Mbps: 'b1_5Mbps',
Bitrate.b420Kbps: 'b420Kbps',
Bitrate.b720Kbps: 'b720Kbps',
};