mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 13:38:13 -08:00
193 lines
6.7 KiB
Dart
193 lines
6.7 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
|
|
import 'package:fladder/models/items/media_segments_model.dart';
|
|
import 'package:fladder/models/settings/key_combinations.dart';
|
|
import 'package:fladder/util/bitrate_helper.dart';
|
|
import 'package:fladder/util/localization_helper.dart';
|
|
|
|
part 'video_player_settings.freezed.dart';
|
|
part 'video_player_settings.g.dart';
|
|
|
|
enum VideoHotKeys {
|
|
playPause,
|
|
seekForward,
|
|
seekBack,
|
|
mute,
|
|
volumeUp,
|
|
volumeDown,
|
|
nextVideo,
|
|
prevVideo,
|
|
nextChapter,
|
|
prevChapter,
|
|
fullScreen,
|
|
skipMediaSegment,
|
|
exit;
|
|
|
|
const VideoHotKeys();
|
|
|
|
String label(BuildContext context) {
|
|
return switch (this) {
|
|
VideoHotKeys.playPause => context.localized.playPause,
|
|
VideoHotKeys.seekForward => context.localized.seekForward,
|
|
VideoHotKeys.seekBack => context.localized.seekBack,
|
|
VideoHotKeys.mute => context.localized.mute,
|
|
VideoHotKeys.volumeUp => context.localized.volumeUp,
|
|
VideoHotKeys.volumeDown => context.localized.volumeDown,
|
|
VideoHotKeys.nextVideo => context.localized.nextVideo,
|
|
VideoHotKeys.prevVideo => context.localized.prevVideo,
|
|
VideoHotKeys.nextChapter => context.localized.nextChapter,
|
|
VideoHotKeys.prevChapter => context.localized.prevChapter,
|
|
VideoHotKeys.fullScreen => context.localized.fullScreen,
|
|
VideoHotKeys.skipMediaSegment => context.localized.skipMediaSegment,
|
|
VideoHotKeys.exit => context.localized.exit,
|
|
};
|
|
}
|
|
}
|
|
|
|
@Freezed(copyWith: true)
|
|
abstract class VideoPlayerSettingsModel with _$VideoPlayerSettingsModel {
|
|
const VideoPlayerSettingsModel._();
|
|
|
|
factory VideoPlayerSettingsModel({
|
|
double? screenBrightness,
|
|
@Default(BoxFit.contain) BoxFit videoFit,
|
|
@Default(false) bool fillScreen,
|
|
@Default(true) bool hardwareAccel,
|
|
@Default(false) bool useLibass,
|
|
@Default(32) int bufferSize,
|
|
PlayerOptions? playerOptions,
|
|
@Default(100) double internalVolume,
|
|
Set<DeviceOrientation>? allowedOrientations,
|
|
@Default(AutoNextType.smart) AutoNextType nextVideoType,
|
|
@Default(Bitrate.original) Bitrate maxHomeBitrate,
|
|
@Default(Bitrate.original) Bitrate maxInternetBitrate,
|
|
String? audioDevice,
|
|
@Default(defaultSegmentSkipValues) Map<MediaSegmentType, SegmentSkip> segmentSkipSettings,
|
|
@Default({}) Map<VideoHotKeys, KeyCombination> hotKeys,
|
|
}) = _VideoPlayerSettingsModel;
|
|
|
|
double get volume => switch (defaultTargetPlatform) {
|
|
TargetPlatform.android || TargetPlatform.iOS => 100,
|
|
_ => internalVolume,
|
|
};
|
|
|
|
factory VideoPlayerSettingsModel.fromJson(Map<String, dynamic> json) => _$VideoPlayerSettingsModelFromJson(json);
|
|
|
|
PlayerOptions get wantedPlayer => playerOptions ?? PlayerOptions.platformDefaults;
|
|
|
|
Map<VideoHotKeys, KeyCombination> get currentShortcuts =>
|
|
_defaultVideoHotKeys.map((key, value) => MapEntry(key, hotKeys[key] ?? value));
|
|
|
|
Map<VideoHotKeys, KeyCombination> get defaultShortCuts => _defaultVideoHotKeys;
|
|
|
|
bool playerSame(VideoPlayerSettingsModel other) {
|
|
return other.hardwareAccel == hardwareAccel &&
|
|
other.useLibass == useLibass &&
|
|
other.bufferSize == bufferSize &&
|
|
other.wantedPlayer == wantedPlayer;
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is VideoPlayerSettingsModel &&
|
|
other.screenBrightness == screenBrightness &&
|
|
other.videoFit == videoFit &&
|
|
other.fillScreen == fillScreen &&
|
|
other.hardwareAccel == hardwareAccel &&
|
|
other.useLibass == useLibass &&
|
|
other.bufferSize == bufferSize &&
|
|
other.internalVolume == internalVolume &&
|
|
other.playerOptions == playerOptions &&
|
|
other.audioDevice == audioDevice;
|
|
}
|
|
|
|
@override
|
|
int get hashCode {
|
|
return screenBrightness.hashCode ^
|
|
videoFit.hashCode ^
|
|
fillScreen.hashCode ^
|
|
hardwareAccel.hashCode ^
|
|
useLibass.hashCode ^
|
|
bufferSize.hashCode ^
|
|
internalVolume.hashCode ^
|
|
audioDevice.hashCode;
|
|
}
|
|
}
|
|
|
|
enum PlayerOptions {
|
|
libMDK,
|
|
libMPV;
|
|
|
|
const PlayerOptions();
|
|
|
|
static Iterable<PlayerOptions> get available => kIsWeb ? {PlayerOptions.libMPV} : PlayerOptions.values;
|
|
|
|
static PlayerOptions get platformDefaults {
|
|
if (kIsWeb) return PlayerOptions.libMPV;
|
|
return switch (defaultTargetPlatform) {
|
|
_ => PlayerOptions.libMPV,
|
|
};
|
|
}
|
|
|
|
String label(BuildContext context) => switch (this) {
|
|
PlayerOptions.libMDK => "MDK",
|
|
PlayerOptions.libMPV => "MPV",
|
|
};
|
|
}
|
|
|
|
enum AutoNextType {
|
|
off,
|
|
smart,
|
|
static;
|
|
|
|
const AutoNextType();
|
|
|
|
String label(BuildContext context) => switch (this) {
|
|
AutoNextType.off => context.localized.off,
|
|
AutoNextType.smart => context.localized.autoNextOffSmartTitle,
|
|
AutoNextType.static => context.localized.autoNextOffStaticTitle,
|
|
};
|
|
|
|
String desc(BuildContext context) => switch (this) {
|
|
AutoNextType.off => context.localized.off,
|
|
AutoNextType.smart => context.localized.autoNextOffSmartDesc,
|
|
AutoNextType.static => context.localized.autoNextOffStaticDesc,
|
|
};
|
|
}
|
|
|
|
Map<VideoHotKeys, KeyCombination> get _defaultVideoHotKeys => {
|
|
for (var hotKey in VideoHotKeys.values)
|
|
hotKey: switch (hotKey) {
|
|
VideoHotKeys.playPause => KeyCombination(
|
|
key: LogicalKeyboardKey.space,
|
|
altKey: LogicalKeyboardKey.keyK,
|
|
),
|
|
VideoHotKeys.seekForward => KeyCombination(
|
|
key: LogicalKeyboardKey.arrowRight,
|
|
altKey: LogicalKeyboardKey.keyL,
|
|
),
|
|
VideoHotKeys.seekBack => KeyCombination(
|
|
key: LogicalKeyboardKey.arrowLeft,
|
|
altKey: LogicalKeyboardKey.keyJ,
|
|
),
|
|
VideoHotKeys.mute => KeyCombination(key: LogicalKeyboardKey.keyM),
|
|
VideoHotKeys.volumeUp => KeyCombination(key: LogicalKeyboardKey.arrowUp),
|
|
VideoHotKeys.volumeDown => KeyCombination(key: LogicalKeyboardKey.arrowDown),
|
|
VideoHotKeys.prevVideo =>
|
|
KeyCombination(key: LogicalKeyboardKey.keyP, modifier: LogicalKeyboardKey.shiftLeft),
|
|
VideoHotKeys.nextVideo =>
|
|
KeyCombination(key: LogicalKeyboardKey.keyN, modifier: LogicalKeyboardKey.shiftLeft),
|
|
VideoHotKeys.nextChapter => KeyCombination(key: LogicalKeyboardKey.pageUp),
|
|
VideoHotKeys.prevChapter => KeyCombination(key: LogicalKeyboardKey.pageDown),
|
|
VideoHotKeys.fullScreen => KeyCombination(key: LogicalKeyboardKey.keyF),
|
|
VideoHotKeys.skipMediaSegment => KeyCombination(key: LogicalKeyboardKey.keyS),
|
|
VideoHotKeys.exit => KeyCombination(key: LogicalKeyboardKey.escape),
|
|
},
|
|
};
|