#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 ### Changed
- No default map style for `izzy` and `libre` flavors - Map: no default map style for `izzy` and `libre` flavors
- allow setting default editor - Viewer: allow setting default editor
- Viewer: keep manually un/muted state for following autoplayed videos
### Fixed ### Fixed

View file

@ -1,6 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/app_mode.dart'; 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/actions/move_type.dart';
import 'package:aves/model/entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
@ -255,7 +256,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
} else if (notification is VideoActionNotification) { } else if (notification is VideoActionNotification) {
final controller = notification.controller; final controller = notification.controller;
final action = notification.action; final action = notification.action;
_videoActionDelegate.onActionSelected(context, controller, action); _onVideoAction(context, controller, action);
} else { } else {
return false; return false;
} }
@ -396,7 +397,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
scale: _overlayVideoControlScale, scale: _overlayVideoControlScale,
onActionSelected: (action) { onActionSelected: (action) {
if (videoController != null) { if (videoController != null) {
_videoActionDelegate.onActionSelected(context, videoController, action); _onVideoAction(context, videoController, action);
} }
}, },
onActionMenuOpened: () { 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() { void _onVerticalPageControllerChange() {
if (!_isEntryTracked && _verticalPager.hasClients && _verticalPager.page?.floor() == transitionPage) { if (!_isEntryTracked && _verticalPager.hasClients && _verticalPager.page?.floor() == transitionPage) {
_trackEntry(); _trackEntry();

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:aves/model/entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/widgets/viewer/video/controller.dart'; import 'package:aves/widgets/viewer/video/controller.dart';
import 'package:aves/widgets/viewer/video/fijkplayer.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); 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<Uint8List> captureFrame();
Future<void> toggleMute(); Future<void> mute(bool muted);
Widget buildPlayerWidget(BuildContext context); Widget buildPlayerWidget(BuildContext context);
} }

View file

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

View file

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

View file

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