Initial commit
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../core/contracts/library.dart';
|
||||
import '../core/media/media_range_detector.dart';
|
||||
import 'shared/settings_persistence.dart';
|
||||
|
||||
enum VersionPriority {
|
||||
dolbyVision('杜比视界优先'),
|
||||
hdr('HDR 优先'),
|
||||
sdr('SDR 优先'),
|
||||
highBitrate('高码率优先'),
|
||||
lowBitrate('低码率优先'),
|
||||
highFramerate('高帧率优先'),
|
||||
largeFile('大文件优先');
|
||||
|
||||
final String label;
|
||||
const VersionPriority(this.label);
|
||||
}
|
||||
|
||||
class VersionPriorityState {
|
||||
final List<VersionPriority> activePriorities;
|
||||
const VersionPriorityState({this.activePriorities = const []});
|
||||
}
|
||||
|
||||
class VersionPriorityNotifier extends AsyncNotifier<VersionPriorityState>
|
||||
with SettingsPersistence {
|
||||
static const _key = 'smplayer.version_priorities';
|
||||
|
||||
@override
|
||||
Future<VersionPriorityState> build() async {
|
||||
final prefs = await getPrefs();
|
||||
final raw = prefs.getStringList(_key);
|
||||
if (raw == null) return const VersionPriorityState();
|
||||
final priorities = raw
|
||||
.map((name) {
|
||||
try {
|
||||
return VersionPriority.values.byName(name);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.whereType<VersionPriority>()
|
||||
.toList();
|
||||
return VersionPriorityState(activePriorities: priorities);
|
||||
}
|
||||
|
||||
Future<void> _save(List<VersionPriority> list) async {
|
||||
state = AsyncValue.data(VersionPriorityState(activePriorities: list));
|
||||
await persistField(_key, list.map((p) => p.name).toList());
|
||||
}
|
||||
|
||||
Future<void> toggle(VersionPriority p) async {
|
||||
final current = List<VersionPriority>.from(
|
||||
state.value?.activePriorities ?? [],
|
||||
);
|
||||
current.contains(p) ? current.remove(p) : current.add(p);
|
||||
await _save(current);
|
||||
}
|
||||
|
||||
Future<void> setPriorities(List<VersionPriority> list) => _save(list);
|
||||
}
|
||||
|
||||
final versionPriorityProvider =
|
||||
AsyncNotifierProvider<VersionPriorityNotifier, VersionPriorityState>(
|
||||
VersionPriorityNotifier.new,
|
||||
);
|
||||
|
||||
List<EmbyRawMediaSource> sortMediaSources(
|
||||
List<EmbyRawMediaSource> sources,
|
||||
List<VersionPriority> priorities,
|
||||
) {
|
||||
if (priorities.isEmpty || sources.length <= 1) return sources;
|
||||
final sorted = List<EmbyRawMediaSource>.from(sources);
|
||||
sorted.sort((a, b) => compareMediaSourcesByPriority(a, b, priorities));
|
||||
return sorted;
|
||||
}
|
||||
|
||||
|
||||
int compareMediaSourcesByPriority(
|
||||
EmbyRawMediaSource a,
|
||||
EmbyRawMediaSource b,
|
||||
List<VersionPriority> priorities,
|
||||
) {
|
||||
for (final p in priorities) {
|
||||
final cmp = _compareByRule(a, b, p);
|
||||
if (cmp != 0) return cmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _compareByRule(
|
||||
EmbyRawMediaSource a,
|
||||
EmbyRawMediaSource b,
|
||||
VersionPriority rule,
|
||||
) {
|
||||
switch (rule) {
|
||||
case VersionPriority.dolbyVision:
|
||||
return _boolDesc(isDolbyVision(a), isDolbyVision(b));
|
||||
case VersionPriority.hdr:
|
||||
return _boolDesc(isHdr(a), isHdr(b));
|
||||
case VersionPriority.sdr:
|
||||
return _boolDesc(!isHdr(a), !isHdr(b));
|
||||
case VersionPriority.highBitrate:
|
||||
return (b.Bitrate ?? 0).compareTo(a.Bitrate ?? 0);
|
||||
case VersionPriority.lowBitrate:
|
||||
return (a.Bitrate ?? 0).compareTo(b.Bitrate ?? 0);
|
||||
case VersionPriority.highFramerate:
|
||||
return getFrameRate(b).compareTo(getFrameRate(a));
|
||||
case VersionPriority.largeFile:
|
||||
return (b.Size ?? 0).compareTo(a.Size ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
int _boolDesc(bool a, bool b) {
|
||||
if (a == b) return 0;
|
||||
return a ? -1 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user