#399 keep manually un/muted state for following autoplayed videos
This commit is contained in:
parent
ee6ee1b320
commit
f3bee6ec7e
7 changed files with 42 additions and 19 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ abstract class AvesVideoController {
|
|||
|
||||
Future<Uint8List> captureFrame();
|
||||
|
||||
Future<void> toggleMute();
|
||||
Future<void> mute(bool muted);
|
||||
|
||||
Widget buildPlayerWidget(BuildContext context);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue