#399 keep manually un/muted state for following autoplayed videos

This commit is contained in:
Thibault Deckers 2022-11-23 10:52:11 +01:00
parent ee6ee1b320
commit f3bee6ec7e
7 changed files with 42 additions and 19 deletions

View file

@ -13,8 +13,9 @@ All notable changes to this project will be documented in this file.
### Changed
- No default map style for `izzy` and `libre` flavors
- allow setting default editor
- Map: no default map style for `izzy` and `libre` flavors
- Viewer: allow setting default editor
- Viewer: keep manually un/muted state for following autoplayed videos
### Fixed

View file

@ -1,6 +1,7 @@
import 'dart:math';
import 'package:aves/app_mode.dart';
import 'package:aves/model/actions/entry_actions.dart';
import 'package:aves/model/actions/move_type.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart';
@ -255,7 +256,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
} else if (notification is VideoActionNotification) {
final controller = notification.controller;
final action = notification.action;
_videoActionDelegate.onActionSelected(context, controller, action);
_onVideoAction(context, controller, action);
} else {
return false;
}
@ -396,7 +397,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
scale: _overlayVideoControlScale,
onActionSelected: (action) {
if (videoController != null) {
_videoActionDelegate.onActionSelected(context, videoController, action);
_onVideoAction(context, videoController, action);
}
},
onActionMenuOpened: () {
@ -482,6 +483,15 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
);
}
Future<void> _onVideoAction(BuildContext context, AvesVideoController controller, EntryAction action) async {
await _videoActionDelegate.onActionSelected(context, controller, action);
if (action == EntryAction.videoToggleMute) {
final override = controller.isMuted;
videoMutedOverride = override;
await context.read<VideoConductor>().muteAll(override);
}
}
void _onVerticalPageControllerChange() {
if (!_isEntryTracked && _verticalPager.hasClients && _verticalPager.page?.floor() == transitionPage) {
_trackEntry();

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:aves/model/entry.dart';
import 'package:aves/widgets/viewer/video/controller.dart';
import 'package:aves/widgets/viewer/video/fijkplayer.dart';
@ -34,5 +36,9 @@ class VideoConductor {
return _controllers.firstWhereOrNull((c) => c.entry.uri == entry.uri && c.entry.pageId == entry.pageId);
}
Future<void> pauseAll() => Future.forEach<AvesVideoController>(_controllers, (controller) => controller.pause());
Future<void> _applyToAll(FutureOr Function(AvesVideoController controller) action) => Future.forEach<AvesVideoController>(_controllers, action);
Future<void> pauseAll() => _applyToAll((controller) => controller.pause());
Future<void> muteAll(bool muted) => _applyToAll((controller) => controller.mute(muted));
}

View file

@ -144,7 +144,7 @@ abstract class AvesVideoController {
Future<Uint8List> captureFrame();
Future<void> toggleMute();
Future<void> mute(bool muted);
Widget buildPlayerWidget(BuildContext context);
}

View file

@ -363,8 +363,8 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
bool get isMuted => _volume == 0;
@override
Future<void> toggleMute() async {
_volume = isMuted ? 1 : 0;
Future<void> mute(bool muted) async {
_volume = muted ? 0 : 1;
_volumeStreamController.add(_volume);
await _applyVolume();
}

View file

@ -35,39 +35,39 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
stopOverlayHidingTimer();
}
void onActionSelected(BuildContext context, AvesVideoController controller, EntryAction action) {
Future<void> onActionSelected(BuildContext context, AvesVideoController controller, EntryAction action) async {
// make sure overlay is not disappearing when selecting an action
stopOverlayHidingTimer();
const ToggleOverlayNotification(visible: true).dispatch(context);
switch (action) {
case EntryAction.videoCaptureFrame:
_captureFrame(context, controller);
await _captureFrame(context, controller);
break;
case EntryAction.videoToggleMute:
controller.toggleMute();
await controller.mute(!controller.isMuted);
break;
case EntryAction.videoSelectStreams:
_showStreamSelectionDialog(context, controller);
await _showStreamSelectionDialog(context, controller);
break;
case EntryAction.videoSetSpeed:
_showSpeedDialog(context, controller);
await _showSpeedDialog(context, controller);
break;
case EntryAction.videoSettings:
_showSettings(context, controller);
await _showSettings(context, controller);
break;
case EntryAction.videoTogglePlay:
_togglePlayPause(context, controller);
await _togglePlayPause(context, controller);
break;
case EntryAction.videoReplay10:
controller.seekTo(controller.currentPosition - 10000);
await controller.seekTo(controller.currentPosition - 10000);
break;
case EntryAction.videoSkip10:
controller.seekTo(controller.currentPosition + 10000);
await controller.seekTo(controller.currentPosition + 10000);
break;
case EntryAction.open:
final entry = controller.entry;
androidAppService.open(entry.uri, entry.mimeTypeAnySubtype).then((success) {
await androidAppService.open(entry.uri, entry.mimeTypeAnySubtype).then((success) {
if (!success) showNoMatchingAppDialog(context);
});
break;

View file

@ -17,6 +17,8 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
final Map<AvesEntry, VoidCallback> _metadataChangeListeners = {};
final Map<MultiPageController, Future<void> Function()> _multiPageControllerPageListeners = {};
bool? videoMutedOverride;
bool get isViewingImage;
ValueNotifier<AvesEntry?> get entryNotifier;
@ -89,6 +91,10 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
}
bool get shouldAutoPlayVideoMuted {
if (videoMutedOverride != null) {
return videoMutedOverride!;
}
switch (videoPlaybackOverride) {
case SlideshowVideoPlayback.skip:
case SlideshowVideoPlayback.playWithSound:
@ -189,7 +195,7 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
await Future.delayed(const Duration(milliseconds: 300) * timeDilation);
if (!videoController.isMuted && shouldAutoPlayVideoMuted) {
await videoController.toggleMute();
await videoController.mute(true);
}
if (resumeTimeMillis != null) {