mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 21:48:14 -08:00
feature: Version selection (#235)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
935d6fe176
commit
f0414439f3
13 changed files with 142 additions and 60 deletions
|
|
@ -173,8 +173,7 @@ class EpisodeModel extends ItemStreamModel with EpisodeModelMappable {
|
|||
parentImages: ImagesData.fromBaseItemParent(item, ref),
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
mediaStreams:
|
||||
MediaStreamsModel.fromMediaStreamsList(item.mediaSources?.firstOrNull, item.mediaStreams ?? [], ref),
|
||||
mediaStreams: MediaStreamsModel.fromMediaStreamsList(item.mediaSources, ref),
|
||||
jellyType: item.type,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
|
|
@ -7,9 +10,6 @@ import 'package:fladder/models/items/item_shared_models.dart';
|
|||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/movie_model.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'item_stream_model.mapper.dart';
|
||||
|
||||
|
|
@ -55,8 +55,7 @@ class ItemStreamModel extends ItemBaseModel with ItemStreamModelMappable {
|
|||
parentImages: ImagesData.fromBaseItemParent(item, ref),
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
mediaStreams:
|
||||
MediaStreamsModel.fromMediaStreamsList(item.mediaSources?.firstOrNull, item.mediaStreams ?? [], ref),
|
||||
mediaStreams: MediaStreamsModel.fromMediaStreamsList(item.mediaSources, ref),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,19 +12,23 @@ import 'package:fladder/util/localization_helper.dart';
|
|||
import 'package:fladder/util/video_properties.dart';
|
||||
|
||||
class MediaStreamsModel {
|
||||
final int? versionStreamIndex;
|
||||
final int? defaultAudioStreamIndex;
|
||||
final int? defaultSubStreamIndex;
|
||||
final List<VideoStreamModel> videoStreams;
|
||||
final List<AudioStreamModel> audioStreams;
|
||||
final List<SubStreamModel> subStreams;
|
||||
final List<VersionStreamModel> versionStreams;
|
||||
MediaStreamsModel({
|
||||
this.versionStreamIndex,
|
||||
this.defaultAudioStreamIndex,
|
||||
this.defaultSubStreamIndex,
|
||||
required this.videoStreams,
|
||||
required this.audioStreams,
|
||||
required this.subStreams,
|
||||
required this.versionStreams,
|
||||
});
|
||||
|
||||
VersionStreamModel? get currentVersionStream => versionStreams.elementAtOrNull(versionStreamIndex ?? 0);
|
||||
|
||||
List<VideoStreamModel> get videoStreams => currentVersionStream?.videoStreams ?? [];
|
||||
List<AudioStreamModel> get audioStreams => currentVersionStream?.audioStreams ?? [];
|
||||
List<SubStreamModel> get subStreams => currentVersionStream?.subStreams ?? [];
|
||||
|
||||
bool get isNull {
|
||||
return defaultAudioStreamIndex == null ||
|
||||
defaultSubStreamIndex == null ||
|
||||
|
|
@ -92,44 +96,61 @@ class MediaStreamsModel {
|
|||
}
|
||||
|
||||
static MediaStreamsModel fromMediaStreamsList(
|
||||
dto.MediaSourceInfo? mediaSource, List<dto.MediaStream> streams, Ref ref) {
|
||||
List<dto.MediaSourceInfo>? mediaSource,
|
||||
Ref ref,
|
||||
) {
|
||||
return MediaStreamsModel(
|
||||
defaultAudioStreamIndex: mediaSource?.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: mediaSource?.defaultSubtitleStreamIndex,
|
||||
videoStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.video)
|
||||
.map(
|
||||
(e) => VideoStreamModel.fromMediaStream(e),
|
||||
)
|
||||
.sortByExternal(),
|
||||
audioStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.audio)
|
||||
.map(
|
||||
(e) => AudioStreamModel.fromMediaStream(e),
|
||||
)
|
||||
.sortByExternal(),
|
||||
subStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.subtitle)
|
||||
.map(
|
||||
(sub) => SubStreamModel.fromMediaStream(sub, ref),
|
||||
)
|
||||
.sortByExternal(),
|
||||
);
|
||||
defaultAudioStreamIndex: mediaSource?.firstOrNull?.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: mediaSource?.firstOrNull?.defaultSubtitleStreamIndex,
|
||||
versionStreams: mediaSource?.mapIndexed(
|
||||
(index, element) {
|
||||
final streams = element.mediaStreams ?? [];
|
||||
return VersionStreamModel(
|
||||
name: element.name ?? "",
|
||||
index: index,
|
||||
id: element.id,
|
||||
defaultAudioStreamIndex: element.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: element.defaultSubtitleStreamIndex,
|
||||
videoStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.video)
|
||||
.map(
|
||||
(e) => VideoStreamModel.fromMediaStream(e),
|
||||
)
|
||||
.sortByExternal(),
|
||||
audioStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.audio)
|
||||
.map(
|
||||
(e) => AudioStreamModel.fromMediaStream(e),
|
||||
)
|
||||
.sortByExternal(),
|
||||
subStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.subtitle)
|
||||
.map(
|
||||
(sub) => SubStreamModel.fromMediaStream(sub, ref),
|
||||
)
|
||||
.sortByExternal());
|
||||
},
|
||||
).toList() ??
|
||||
[]);
|
||||
}
|
||||
|
||||
MediaStreamsModel copyWith({
|
||||
int? versionStreamIndex,
|
||||
int? defaultAudioStreamIndex,
|
||||
int? defaultSubStreamIndex,
|
||||
List<VideoStreamModel>? videoStreams,
|
||||
List<AudioStreamModel>? audioStreams,
|
||||
List<SubStreamModel>? subStreams,
|
||||
List<VersionStreamModel>? versionStreams,
|
||||
}) {
|
||||
final streamIndexChanged = versionStreamIndex != this.versionStreamIndex && versionStreamIndex != null;
|
||||
final currentVersionStreams = versionStreams ?? this.versionStreams;
|
||||
return MediaStreamsModel(
|
||||
defaultAudioStreamIndex: defaultAudioStreamIndex ?? this.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: defaultSubStreamIndex ?? this.defaultSubStreamIndex,
|
||||
videoStreams: videoStreams ?? this.videoStreams,
|
||||
audioStreams: audioStreams ?? this.audioStreams,
|
||||
subStreams: subStreams ?? this.subStreams,
|
||||
versionStreamIndex: versionStreamIndex ?? this.versionStreamIndex,
|
||||
defaultAudioStreamIndex: streamIndexChanged
|
||||
? currentVersionStreams.elementAtOrNull(versionStreamIndex)?.defaultAudioStreamIndex
|
||||
: defaultAudioStreamIndex ?? this.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: streamIndexChanged
|
||||
? currentVersionStreams.elementAtOrNull(versionStreamIndex)?.defaultSubStreamIndex
|
||||
: defaultSubStreamIndex ?? this.defaultSubStreamIndex,
|
||||
versionStreams: versionStreams ?? this.versionStreams,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +175,28 @@ class StreamModel {
|
|||
});
|
||||
}
|
||||
|
||||
class VersionStreamModel {
|
||||
final String name;
|
||||
final int index;
|
||||
final String? id;
|
||||
final int? defaultAudioStreamIndex;
|
||||
final int? defaultSubStreamIndex;
|
||||
final List<VideoStreamModel> videoStreams;
|
||||
final List<AudioStreamModel> audioStreams;
|
||||
final List<SubStreamModel> subStreams;
|
||||
|
||||
VersionStreamModel({
|
||||
required this.name,
|
||||
required this.index,
|
||||
this.id,
|
||||
required this.defaultAudioStreamIndex,
|
||||
required this.defaultSubStreamIndex,
|
||||
required this.videoStreams,
|
||||
required this.audioStreams,
|
||||
required this.subStreams,
|
||||
});
|
||||
}
|
||||
|
||||
class VideoStreamModel extends StreamModel {
|
||||
final int width;
|
||||
final int height;
|
||||
|
|
|
|||
|
|
@ -96,8 +96,7 @@ class MovieModel extends ItemStreamModel with MovieModelMappable {
|
|||
parentImages: ImagesData.fromBaseItemParent(item, ref),
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
mediaStreams:
|
||||
MediaStreamsModel.fromMediaStreamsList(item.mediaSources?.firstOrNull, item.mediaStreams ?? [], ref),
|
||||
mediaStreams: MediaStreamsModel.fromMediaStreamsList(item.mediaSources, ref),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ class PlaybackModelHelper {
|
|||
enableDirectPlay: type != PlaybackType.transcode,
|
||||
enableDirectStream: type != PlaybackType.transcode,
|
||||
maxStreamingBitrate: qualityOptions.enabledFirst.keys.firstOrNull?.bitRate,
|
||||
mediaSourceId: firstItemToPlay.id,
|
||||
mediaSourceId: streamModel?.currentVersionStream?.id,
|
||||
),
|
||||
);
|
||||
|
||||
|
|
@ -219,9 +219,7 @@ class PlaybackModelHelper {
|
|||
|
||||
final mediaSource = playbackInfo.mediaSources?.first;
|
||||
|
||||
final mediaStreamsWithUrls = MediaStreamsModel.fromMediaStreamsList(
|
||||
playbackInfo.mediaSources?.firstOrNull, playbackInfo.mediaSources?.firstOrNull?.mediaStreams ?? [], ref)
|
||||
.copyWith(
|
||||
final mediaStreamsWithUrls = MediaStreamsModel.fromMediaStreamsList(playbackInfo.mediaSources, ref).copyWith(
|
||||
defaultAudioStreamIndex: streamModel?.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: streamModel?.defaultSubStreamIndex,
|
||||
);
|
||||
|
|
@ -352,9 +350,7 @@ class PlaybackModelHelper {
|
|||
|
||||
final mediaSource = playbackInfo.mediaSources?.first;
|
||||
|
||||
final mediaStreamsWithUrls = MediaStreamsModel.fromMediaStreamsList(
|
||||
playbackInfo.mediaSources?.firstOrNull, playbackInfo.mediaSources?.firstOrNull?.mediaStreams ?? [], ref)
|
||||
.copyWith(
|
||||
final mediaStreamsWithUrls = MediaStreamsModel.fromMediaStreamsList(playbackInfo.mediaSources, ref).copyWith(
|
||||
defaultAudioStreamIndex: audioIndex,
|
||||
defaultSubStreamIndex: subIndex,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -199,8 +199,7 @@ class VideoStream {
|
|||
playbackUrl: playbackUrl,
|
||||
playbackType: playType,
|
||||
playSessionId: info.playSessionId ?? "",
|
||||
mediaStreamsModel: MediaStreamsModel.fromMediaStreamsList(
|
||||
info.mediaSources?.firstOrNull, info.mediaSources?.firstOrNull?.mediaStreams ?? [], ref),
|
||||
mediaStreamsModel: MediaStreamsModel.fromMediaStreamsList(info.mediaSources, ref),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue