feature: Add actions for media segments (#236)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2025-02-23 16:56:49 +01:00 committed by GitHub
parent f0414439f3
commit e4b8a050c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 155 additions and 23 deletions

View file

@ -42,6 +42,28 @@ class MediaSegment with _$MediaSegment {
bool forceShow(Duration position) => (position - start).inSeconds < (end - start).inSeconds * 0.20;
}
const Map<MediaSegmentType, SegmentSkip> defaultSegmentSkipValues = {
MediaSegmentType.commercial: SegmentSkip.askToSkip,
MediaSegmentType.preview: SegmentSkip.askToSkip,
MediaSegmentType.recap: SegmentSkip.askToSkip,
MediaSegmentType.outro: SegmentSkip.askToSkip,
MediaSegmentType.intro: SegmentSkip.askToSkip,
};
enum SegmentSkip {
none,
askToSkip,
skip;
const SegmentSkip();
String label(BuildContext context) => switch (this) {
SegmentSkip.none => context.localized.segmentActionNone,
SegmentSkip.askToSkip => context.localized.segmentActionAskToSkip,
SegmentSkip.skip => context.localized.segmentActionSkip,
};
}
enum MediaSegmentType {
unknown,
commercial,

View file

@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:fladder/models/items/media_segments_model.dart';
import 'package:fladder/util/bitrate_helper.dart';
import 'package:fladder/util/localization_helper.dart';
@ -28,6 +29,7 @@ class VideoPlayerSettingsModel with _$VideoPlayerSettingsModel {
@Default(Bitrate.original) Bitrate maxHomeBitrate,
@Default(Bitrate.original) Bitrate maxInternetBitrate,
String? audioDevice,
@Default(defaultSegmentSkipValues) Map<MediaSegmentType, SegmentSkip> segmentSkipSettings,
}) = _VideoPlayerSettingsModel;
double get volume => switch (defaultTargetPlatform) {

View file

@ -34,6 +34,8 @@ mixin _$VideoPlayerSettingsModel {
Bitrate get maxHomeBitrate => throw _privateConstructorUsedError;
Bitrate get maxInternetBitrate => throw _privateConstructorUsedError;
String? get audioDevice => throw _privateConstructorUsedError;
Map<MediaSegmentType, SegmentSkip> get segmentSkipSettings =>
throw _privateConstructorUsedError;
/// Serializes this VideoPlayerSettingsModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@ -63,7 +65,8 @@ abstract class $VideoPlayerSettingsModelCopyWith<$Res> {
AutoNextType nextVideoType,
Bitrate maxHomeBitrate,
Bitrate maxInternetBitrate,
String? audioDevice});
String? audioDevice,
Map<MediaSegmentType, SegmentSkip> segmentSkipSettings});
}
/// @nodoc
@ -94,6 +97,7 @@ class _$VideoPlayerSettingsModelCopyWithImpl<$Res,
Object? maxHomeBitrate = null,
Object? maxInternetBitrate = null,
Object? audioDevice = freezed,
Object? segmentSkipSettings = null,
}) {
return _then(_value.copyWith(
screenBrightness: freezed == screenBrightness
@ -144,6 +148,10 @@ class _$VideoPlayerSettingsModelCopyWithImpl<$Res,
? _value.audioDevice
: audioDevice // ignore: cast_nullable_to_non_nullable
as String?,
segmentSkipSettings: null == segmentSkipSettings
? _value.segmentSkipSettings
: segmentSkipSettings // ignore: cast_nullable_to_non_nullable
as Map<MediaSegmentType, SegmentSkip>,
) as $Val);
}
}
@ -169,7 +177,8 @@ abstract class _$$VideoPlayerSettingsModelImplCopyWith<$Res>
AutoNextType nextVideoType,
Bitrate maxHomeBitrate,
Bitrate maxInternetBitrate,
String? audioDevice});
String? audioDevice,
Map<MediaSegmentType, SegmentSkip> segmentSkipSettings});
}
/// @nodoc
@ -199,6 +208,7 @@ class __$$VideoPlayerSettingsModelImplCopyWithImpl<$Res>
Object? maxHomeBitrate = null,
Object? maxInternetBitrate = null,
Object? audioDevice = freezed,
Object? segmentSkipSettings = null,
}) {
return _then(_$VideoPlayerSettingsModelImpl(
screenBrightness: freezed == screenBrightness
@ -249,6 +259,10 @@ class __$$VideoPlayerSettingsModelImplCopyWithImpl<$Res>
? _value.audioDevice
: audioDevice // ignore: cast_nullable_to_non_nullable
as String?,
segmentSkipSettings: null == segmentSkipSettings
? _value._segmentSkipSettings
: segmentSkipSettings // ignore: cast_nullable_to_non_nullable
as Map<MediaSegmentType, SegmentSkip>,
));
}
}
@ -269,8 +283,11 @@ class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
this.nextVideoType = AutoNextType.smart,
this.maxHomeBitrate = Bitrate.original,
this.maxInternetBitrate = Bitrate.original,
this.audioDevice})
this.audioDevice,
final Map<MediaSegmentType, SegmentSkip> segmentSkipSettings =
defaultSegmentSkipValues})
: _allowedOrientations = allowedOrientations,
_segmentSkipSettings = segmentSkipSettings,
super._();
factory _$VideoPlayerSettingsModelImpl.fromJson(Map<String, dynamic> json) =>
@ -317,10 +334,19 @@ class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
final Bitrate maxInternetBitrate;
@override
final String? audioDevice;
final Map<MediaSegmentType, SegmentSkip> _segmentSkipSettings;
@override
@JsonKey()
Map<MediaSegmentType, SegmentSkip> get segmentSkipSettings {
if (_segmentSkipSettings is EqualUnmodifiableMapView)
return _segmentSkipSettings;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_segmentSkipSettings);
}
@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, maxHomeBitrate: $maxHomeBitrate, maxInternetBitrate: $maxInternetBitrate, 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, segmentSkipSettings: $segmentSkipSettings)';
}
@override
@ -339,7 +365,8 @@ class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
..add(DiagnosticsProperty('nextVideoType', nextVideoType))
..add(DiagnosticsProperty('maxHomeBitrate', maxHomeBitrate))
..add(DiagnosticsProperty('maxInternetBitrate', maxInternetBitrate))
..add(DiagnosticsProperty('audioDevice', audioDevice));
..add(DiagnosticsProperty('audioDevice', audioDevice))
..add(DiagnosticsProperty('segmentSkipSettings', segmentSkipSettings));
}
/// Create a copy of VideoPlayerSettingsModel
@ -361,18 +388,20 @@ class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
abstract class _VideoPlayerSettingsModel extends VideoPlayerSettingsModel {
factory _VideoPlayerSettingsModel(
{final double? screenBrightness,
final BoxFit videoFit,
final bool fillScreen,
final bool hardwareAccel,
final bool useLibass,
final PlayerOptions? playerOptions,
final double internalVolume,
final Set<DeviceOrientation>? allowedOrientations,
final AutoNextType nextVideoType,
final Bitrate maxHomeBitrate,
final Bitrate maxInternetBitrate,
final String? audioDevice}) = _$VideoPlayerSettingsModelImpl;
{final double? screenBrightness,
final BoxFit videoFit,
final bool fillScreen,
final bool hardwareAccel,
final bool useLibass,
final PlayerOptions? playerOptions,
final double internalVolume,
final Set<DeviceOrientation>? allowedOrientations,
final AutoNextType nextVideoType,
final Bitrate maxHomeBitrate,
final Bitrate maxInternetBitrate,
final String? audioDevice,
final Map<MediaSegmentType, SegmentSkip> segmentSkipSettings}) =
_$VideoPlayerSettingsModelImpl;
_VideoPlayerSettingsModel._() : super._();
factory _VideoPlayerSettingsModel.fromJson(Map<String, dynamic> json) =
@ -402,6 +431,8 @@ abstract class _VideoPlayerSettingsModel extends VideoPlayerSettingsModel {
Bitrate get maxInternetBitrate;
@override
String? get audioDevice;
@override
Map<MediaSegmentType, SegmentSkip> get segmentSkipSettings;
/// Create a copy of VideoPlayerSettingsModel
/// with the given fields replaced by the non-null parameter values.

View file

@ -31,6 +31,12 @@ _$VideoPlayerSettingsModelImpl _$$VideoPlayerSettingsModelImplFromJson(
$enumDecodeNullable(_$BitrateEnumMap, json['maxInternetBitrate']) ??
Bitrate.original,
audioDevice: json['audioDevice'] as String?,
segmentSkipSettings:
(json['segmentSkipSettings'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry($enumDecode(_$MediaSegmentTypeEnumMap, k),
$enumDecode(_$SegmentSkipEnumMap, e)),
) ??
defaultSegmentSkipValues,
);
Map<String, dynamic> _$$VideoPlayerSettingsModelImplToJson(
@ -50,6 +56,8 @@ Map<String, dynamic> _$$VideoPlayerSettingsModelImplToJson(
'maxHomeBitrate': _$BitrateEnumMap[instance.maxHomeBitrate]!,
'maxInternetBitrate': _$BitrateEnumMap[instance.maxInternetBitrate]!,
'audioDevice': instance.audioDevice,
'segmentSkipSettings': instance.segmentSkipSettings.map((k, e) =>
MapEntry(_$MediaSegmentTypeEnumMap[k]!, _$SegmentSkipEnumMap[e]!)),
};
const _$BoxFitEnumMap = {
@ -95,6 +103,21 @@ const _$BitrateEnumMap = {
Bitrate.b4Mbps: 'b4Mbps',
Bitrate.b3Mbps: 'b3Mbps',
Bitrate.b1_5Mbps: 'b1_5Mbps',
Bitrate.b420Kbps: 'b420Kbps',
Bitrate.b720Kbps: 'b720Kbps',
Bitrate.b420Kbps: 'b420Kbps',
};
const _$SegmentSkipEnumMap = {
SegmentSkip.none: 'none',
SegmentSkip.askToSkip: 'askToSkip',
SegmentSkip.skip: 'skip',
};
const _$MediaSegmentTypeEnumMap = {
MediaSegmentType.unknown: 'unknown',
MediaSegmentType.commercial: 'commercial',
MediaSegmentType.preview: 'preview',
MediaSegmentType.recap: 'recap',
MediaSegmentType.outro: 'outro',
MediaSegmentType.intro: 'intro',
};