#1086 frame stepping with latest media-kit
This commit is contained in:
parent
0ec2875736
commit
86b06bff7a
12 changed files with 92 additions and 45 deletions
|
@ -138,6 +138,8 @@
|
||||||
"videoActionPlay": "Play",
|
"videoActionPlay": "Play",
|
||||||
"videoActionReplay10": "Seek backward 10 seconds",
|
"videoActionReplay10": "Seek backward 10 seconds",
|
||||||
"videoActionSkip10": "Seek forward 10 seconds",
|
"videoActionSkip10": "Seek forward 10 seconds",
|
||||||
|
"videoActionShowPreviousFrame": "Show previous frame",
|
||||||
|
"videoActionShowNextFrame": "Show next frame",
|
||||||
"videoActionSelectStreams": "Select tracks",
|
"videoActionSelectStreams": "Select tracks",
|
||||||
"videoActionSetSpeed": "Playback speed",
|
"videoActionSetSpeed": "Playback speed",
|
||||||
"videoActionABRepeat": "A-B repeat",
|
"videoActionABRepeat": "A-B repeat",
|
||||||
|
|
|
@ -131,6 +131,8 @@ class AIcons {
|
||||||
static const repeat = Icons.repeat_outlined;
|
static const repeat = Icons.repeat_outlined;
|
||||||
static final repeatOff = MdiIcons.repeatOff;
|
static final repeatOff = MdiIcons.repeatOff;
|
||||||
static const replay10 = Icons.replay_10_outlined;
|
static const replay10 = Icons.replay_10_outlined;
|
||||||
|
static const previousFrame = Icons.skip_previous_outlined;
|
||||||
|
static const nextFrame = Icons.skip_next_outlined;
|
||||||
static final resetBounds = MdiIcons.rayStartEnd;
|
static final resetBounds = MdiIcons.rayStartEnd;
|
||||||
static const reverse = Icons.invert_colors_outlined;
|
static const reverse = Icons.invert_colors_outlined;
|
||||||
static const skip10 = Icons.forward_10_outlined;
|
static const skip10 = Icons.forward_10_outlined;
|
||||||
|
|
|
@ -43,6 +43,8 @@ extension ExtraEntryActionView on EntryAction {
|
||||||
l10n.videoActionPlay,
|
l10n.videoActionPlay,
|
||||||
EntryAction.videoReplay10 => l10n.videoActionReplay10,
|
EntryAction.videoReplay10 => l10n.videoActionReplay10,
|
||||||
EntryAction.videoSkip10 => l10n.videoActionSkip10,
|
EntryAction.videoSkip10 => l10n.videoActionSkip10,
|
||||||
|
EntryAction.videoShowPreviousFrame => l10n.videoActionShowPreviousFrame,
|
||||||
|
EntryAction.videoShowNextFrame => l10n.videoActionShowNextFrame,
|
||||||
// external
|
// external
|
||||||
EntryAction.edit => l10n.entryActionEdit,
|
EntryAction.edit => l10n.entryActionEdit,
|
||||||
EntryAction.open || EntryAction.openVideo => l10n.entryActionOpen,
|
EntryAction.open || EntryAction.openVideo => l10n.entryActionOpen,
|
||||||
|
@ -118,6 +120,8 @@ extension ExtraEntryActionView on EntryAction {
|
||||||
AIcons.play,
|
AIcons.play,
|
||||||
EntryAction.videoReplay10 => AIcons.replay10,
|
EntryAction.videoReplay10 => AIcons.replay10,
|
||||||
EntryAction.videoSkip10 => AIcons.skip10,
|
EntryAction.videoSkip10 => AIcons.skip10,
|
||||||
|
EntryAction.videoShowPreviousFrame => AIcons.previousFrame,
|
||||||
|
EntryAction.videoShowNextFrame => AIcons.nextFrame,
|
||||||
// external
|
// external
|
||||||
EntryAction.edit => AIcons.edit,
|
EntryAction.edit => AIcons.edit,
|
||||||
EntryAction.open || EntryAction.openVideo => AIcons.openOutside,
|
EntryAction.open || EntryAction.openVideo => AIcons.openOutside,
|
||||||
|
|
|
@ -102,6 +102,8 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
case EntryAction.videoTogglePlay:
|
case EntryAction.videoTogglePlay:
|
||||||
case EntryAction.videoReplay10:
|
case EntryAction.videoReplay10:
|
||||||
case EntryAction.videoSkip10:
|
case EntryAction.videoSkip10:
|
||||||
|
case EntryAction.videoShowPreviousFrame:
|
||||||
|
case EntryAction.videoShowNextFrame:
|
||||||
case EntryAction.openVideo:
|
case EntryAction.openVideo:
|
||||||
return targetEntry.isPureVideo;
|
return targetEntry.isPureVideo;
|
||||||
case EntryAction.rotateScreen:
|
case EntryAction.rotateScreen:
|
||||||
|
@ -242,6 +244,8 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
case EntryAction.videoTogglePlay:
|
case EntryAction.videoTogglePlay:
|
||||||
case EntryAction.videoReplay10:
|
case EntryAction.videoReplay10:
|
||||||
case EntryAction.videoSkip10:
|
case EntryAction.videoSkip10:
|
||||||
|
case EntryAction.videoShowPreviousFrame:
|
||||||
|
case EntryAction.videoShowNextFrame:
|
||||||
case EntryAction.openVideo:
|
case EntryAction.openVideo:
|
||||||
final controller = context.read<VideoConductor>().getController(targetEntry);
|
final controller = context.read<VideoConductor>().getController(targetEntry);
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
|
|
|
@ -74,6 +74,10 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
await controller.seekTo(max(controller.currentPosition - 10000, 0));
|
await controller.seekTo(max(controller.currentPosition - 10000, 0));
|
||||||
case EntryAction.videoSkip10:
|
case EntryAction.videoSkip10:
|
||||||
await controller.seekTo(controller.currentPosition + 10000);
|
await controller.seekTo(controller.currentPosition + 10000);
|
||||||
|
case EntryAction.videoShowPreviousFrame:
|
||||||
|
await controller.skipFrames(-1);
|
||||||
|
case EntryAction.videoShowNextFrame:
|
||||||
|
await controller.skipFrames(1);
|
||||||
case EntryAction.openVideo:
|
case EntryAction.openVideo:
|
||||||
await appService.open(entry.uri, entry.mimeTypeAnySubtype, forceChooser: false).then((success) {
|
await appService.open(entry.uri, entry.mimeTypeAnySubtype, forceChooser: false).then((success) {
|
||||||
if (!success) showNoMatchingAppDialog(context);
|
if (!success) showNoMatchingAppDialog(context);
|
||||||
|
|
|
@ -28,6 +28,8 @@ enum EntryAction {
|
||||||
videoTogglePlay,
|
videoTogglePlay,
|
||||||
videoReplay10,
|
videoReplay10,
|
||||||
videoSkip10,
|
videoSkip10,
|
||||||
|
videoShowPreviousFrame,
|
||||||
|
videoShowNextFrame,
|
||||||
// external
|
// external
|
||||||
edit,
|
edit,
|
||||||
open,
|
open,
|
||||||
|
@ -97,6 +99,8 @@ class EntryActions {
|
||||||
EntryAction.videoTogglePlay,
|
EntryAction.videoTogglePlay,
|
||||||
EntryAction.videoReplay10,
|
EntryAction.videoReplay10,
|
||||||
EntryAction.videoSkip10,
|
EntryAction.videoSkip10,
|
||||||
|
EntryAction.videoShowPreviousFrame,
|
||||||
|
EntryAction.videoShowNextFrame,
|
||||||
EntryAction.rotateCCW,
|
EntryAction.rotateCCW,
|
||||||
EntryAction.rotateCW,
|
EntryAction.rotateCW,
|
||||||
EntryAction.flip,
|
EntryAction.flip,
|
||||||
|
@ -113,6 +117,8 @@ class EntryActions {
|
||||||
EntryAction.videoToggleMute,
|
EntryAction.videoToggleMute,
|
||||||
EntryAction.videoSetSpeed,
|
EntryAction.videoSetSpeed,
|
||||||
EntryAction.videoABRepeat,
|
EntryAction.videoABRepeat,
|
||||||
|
EntryAction.videoShowPreviousFrame,
|
||||||
|
EntryAction.videoShowNextFrame,
|
||||||
EntryAction.videoSelectStreams,
|
EntryAction.videoSelectStreams,
|
||||||
EntryAction.videoSettings,
|
EntryAction.videoSettings,
|
||||||
EntryAction.lockViewer,
|
EntryAction.lockViewer,
|
||||||
|
|
|
@ -69,6 +69,8 @@ abstract class AvesVideoController with ABRepeatMixin {
|
||||||
|
|
||||||
Future<void> seekToProgress(double progress) => seekTo((duration * progress.clamp(0, 1)).toInt());
|
Future<void> seekToProgress(double progress) => seekTo((duration * progress.clamp(0, 1)).toInt());
|
||||||
|
|
||||||
|
Future<void> skipFrames(int frameCount);
|
||||||
|
|
||||||
Listenable get playCompletedListenable;
|
Listenable get playCompletedListenable;
|
||||||
|
|
||||||
VideoStatus get status;
|
VideoStatus get status;
|
||||||
|
|
|
@ -59,6 +59,12 @@ class MpvVideoController extends AvesVideoController {
|
||||||
title: entry.bestTitle ?? entry.uri,
|
title: entry.bestTitle ?? entry.uri,
|
||||||
libass: false,
|
libass: false,
|
||||||
logLevel: MPVLogLevel.warn,
|
logLevel: MPVLogLevel.warn,
|
||||||
|
protocolWhitelist: [
|
||||||
|
...const PlayerConfiguration().protocolWhitelist,
|
||||||
|
// Android `content` URIs are considered unsafe by default,
|
||||||
|
// as they are transferred via a custom `fd` protocol
|
||||||
|
'fd',
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
_initController();
|
_initController();
|
||||||
|
@ -206,6 +212,15 @@ class MpvVideoController extends AvesVideoController {
|
||||||
await _instance.seek(Duration(milliseconds: targetMillis));
|
await _instance.seek(Duration(milliseconds: targetMillis));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> skipFrames(int frameCount) async {
|
||||||
|
if (frameCount > 0) {
|
||||||
|
await _instance.frameStep();
|
||||||
|
} else if (frameCount < 0) {
|
||||||
|
await _instance.frameBackStep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Listenable get playCompletedListenable => _completedNotifier;
|
Listenable get playCompletedListenable => _completedNotifier;
|
||||||
|
|
||||||
|
|
|
@ -179,10 +179,11 @@ packages:
|
||||||
media_kit:
|
media_kit:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: media_kit
|
path: media_kit
|
||||||
sha256: "1f1deee148533d75129a6f38251ff8388e33ee05fc2d20a6a80e57d6051b7b62"
|
ref: frame-stepping
|
||||||
url: "https://pub.dev"
|
resolved-ref: "209221d605a0b2c34379e799a8e001cc359e6183"
|
||||||
source: hosted
|
url: "https://github.com/deckerst/media-kit.git"
|
||||||
|
source: git
|
||||||
version: "1.1.11"
|
version: "1.1.11"
|
||||||
media_kit_libs_android_video:
|
media_kit_libs_android_video:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
|
@ -192,21 +193,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.6"
|
version: "1.3.6"
|
||||||
media_kit_native_event_loop:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: media_kit_native_event_loop
|
|
||||||
sha256: "7d82e3b3e9ded5c35c3146c5ba1da3118d1dd8ac3435bac7f29f458181471b40"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.9"
|
|
||||||
media_kit_video:
|
media_kit_video:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: media_kit_video
|
path: media_kit_video
|
||||||
sha256: "2cc3b966679963ba25a4ce5b771e532a521ebde7c6aa20e9802bec95d9916c8f"
|
ref: frame-stepping
|
||||||
url: "https://pub.dev"
|
resolved-ref: "209221d605a0b2c34379e799a8e001cc359e6183"
|
||||||
source: hosted
|
url: "https://github.com/deckerst/media-kit.git"
|
||||||
|
source: git
|
||||||
version: "1.2.5"
|
version: "1.2.5"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
|
@ -260,10 +254,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: safe_local_storage
|
name: safe_local_storage
|
||||||
sha256: ede4eb6cb7d88a116b3d3bf1df70790b9e2038bc37cb19112e381217c74d9440
|
sha256: e9a21b6fec7a8aa62cc2585ff4c1b127df42f3185adbd2aca66b47abe2e80236
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "2.0.1"
|
||||||
screen_brightness:
|
screen_brightness:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -377,10 +371,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: uri_parser
|
name: uri_parser
|
||||||
sha256: "6543c9fd86d2862fac55d800a43e67c0dcd1a41677cb69c2f8edfe73bbcf1835"
|
sha256: ff4d2c720aca3f4f7d5445e23b11b2d15ef8af5ddce5164643f38ff962dcb270
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "3.0.0"
|
||||||
uuid:
|
uuid:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -17,10 +17,21 @@ dependencies:
|
||||||
collection:
|
collection:
|
||||||
media_kit:
|
media_kit:
|
||||||
media_kit_libs_android_video:
|
media_kit_libs_android_video:
|
||||||
media_kit_native_event_loop:
|
|
||||||
media_kit_video:
|
media_kit_video:
|
||||||
path:
|
path:
|
||||||
|
|
||||||
|
dependency_overrides:
|
||||||
|
media_kit:
|
||||||
|
git:
|
||||||
|
url: https://github.com/deckerst/media-kit.git
|
||||||
|
ref: frame-stepping
|
||||||
|
path: media_kit
|
||||||
|
media_kit_video:
|
||||||
|
git:
|
||||||
|
url: https://github.com/deckerst/media-kit.git
|
||||||
|
ref: frame-stepping
|
||||||
|
path: media_kit_video
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
|
|
||||||
|
|
40
pubspec.lock
40
pubspec.lock
|
@ -901,12 +901,13 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.7296"
|
version: "7.0.7296"
|
||||||
media_kit:
|
media_kit:
|
||||||
dependency: transitive
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
name: media_kit
|
path: media_kit
|
||||||
sha256: "1f1deee148533d75129a6f38251ff8388e33ee05fc2d20a6a80e57d6051b7b62"
|
ref: frame-stepping
|
||||||
url: "https://pub.dev"
|
resolved-ref: "209221d605a0b2c34379e799a8e001cc359e6183"
|
||||||
source: hosted
|
url: "https://github.com/deckerst/media-kit.git"
|
||||||
|
source: git
|
||||||
version: "1.1.11"
|
version: "1.1.11"
|
||||||
media_kit_libs_android_video:
|
media_kit_libs_android_video:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
|
@ -916,21 +917,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.6"
|
version: "1.3.6"
|
||||||
media_kit_native_event_loop:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: media_kit_native_event_loop
|
|
||||||
sha256: "7d82e3b3e9ded5c35c3146c5ba1da3118d1dd8ac3435bac7f29f458181471b40"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.9"
|
|
||||||
media_kit_video:
|
media_kit_video:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
name: media_kit_video
|
path: media_kit_video
|
||||||
sha256: "2cc3b966679963ba25a4ce5b771e532a521ebde7c6aa20e9802bec95d9916c8f"
|
ref: frame-stepping
|
||||||
url: "https://pub.dev"
|
resolved-ref: "209221d605a0b2c34379e799a8e001cc359e6183"
|
||||||
source: hosted
|
url: "https://github.com/deckerst/media-kit.git"
|
||||||
|
source: git
|
||||||
version: "1.2.5"
|
version: "1.2.5"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
|
@ -1306,10 +1300,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: safe_local_storage
|
name: safe_local_storage
|
||||||
sha256: ede4eb6cb7d88a116b3d3bf1df70790b9e2038bc37cb19112e381217c74d9440
|
sha256: e9a21b6fec7a8aa62cc2585ff4c1b127df42f3185adbd2aca66b47abe2e80236
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "2.0.1"
|
||||||
sanitize_html:
|
sanitize_html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1322,10 +1316,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: screen_brightness
|
name: screen_brightness
|
||||||
sha256: "970d1cc68f8ed7bf3a539924a3cd51c06af138bbf345b6daa4af8ce4e8527ebf"
|
sha256: a43fdbccd5b90044f68057412dde7715cd7499a4c24f5d5da7e01ed4cf41e0af
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0+1"
|
version: "2.0.0+2"
|
||||||
screen_brightness_android:
|
screen_brightness_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1664,10 +1658,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: uri_parser
|
name: uri_parser
|
||||||
sha256: "6543c9fd86d2862fac55d800a43e67c0dcd1a41677cb69c2f8edfe73bbcf1835"
|
sha256: ff4d2c720aca3f4f7d5445e23b11b2d15ef8af5ddce5164643f38ff962dcb270
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "3.0.0"
|
||||||
url_launcher:
|
url_launcher:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
11
pubspec.yaml
11
pubspec.yaml
|
@ -120,8 +120,17 @@ dependencies:
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
# media_kit_video v1.2.4 depends on a specific old version of screen_brightness
|
# media_kit_video v1.2.4 depends on a specific old version of screen_brightness
|
||||||
media_kit_video: ^1.0.0
|
|
||||||
screen_brightness: ^2.0.0
|
screen_brightness: ^2.0.0
|
||||||
|
media_kit:
|
||||||
|
git:
|
||||||
|
url: https://github.com/deckerst/media-kit.git
|
||||||
|
ref: frame-stepping
|
||||||
|
path: media_kit
|
||||||
|
media_kit_video:
|
||||||
|
git:
|
||||||
|
url: https://github.com/deckerst/media-kit.git
|
||||||
|
ref: frame-stepping
|
||||||
|
path: media_kit_video
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in a new issue