From 4a3b0e4a4e4f175117a2fe6997a8b1aa4adc45de Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Wed, 15 Mar 2023 00:17:51 +0100 Subject: [PATCH] refactor --- lib/model/entry/entry.dart | 2 +- lib/model/entry/extensions/catalog.dart | 1 - lib/model/entry/extensions/info.dart | 21 +- .../entry/extensions/metadata_edition.dart | 1 - lib/model/query.dart | 2 +- lib/model/settings/settings.dart | 2 +- lib/model/source/collection_lens.dart | 2 +- lib/model/video/metadata.dart | 14 +- lib/services/media/media_session_service.dart | 2 +- lib/widgets/aves_app.dart | 2 +- lib/widgets/common/map/geo_map.dart | 2 +- .../video_stream_selection_dialog.dart | 40 ++-- .../common/quick_actions/editor_page.dart | 2 +- .../viewer/action/video_action_delegate.dart | 6 +- lib/widgets/viewer/entry_viewer_stack.dart | 2 +- lib/widgets/viewer/video/fijkplayer.dart | 50 +++-- .../viewer/video/flutter_vlc_player.dart | 2 +- lib/widgets/viewer/video/video_player.dart | 2 +- plugins/aves_model/analysis_options.yaml | 5 +- plugins/aves_model/lib/aves_model.dart | 4 +- .../src/{entry_base.dart => entry/base.dart} | 0 .../aves_model/lib/src}/video/keys.dart | 0 .../lib/src/video/stream_types.dart | 9 + plugins/aves_utils/.gitignore | 30 +++ plugins/aves_utils/.metadata | 10 + plugins/aves_utils/analysis_options.yaml | 1 + plugins/aves_utils/lib/aves_utils.dart | 4 + .../aves_utils/lib/src}/change_notifier.dart | 0 .../lib/src}/optional_event_channel.dart | 0 plugins/aves_utils/pubspec.lock | 181 ++++++++++++++++++ plugins/aves_utils/pubspec.yaml | 15 ++ plugins/aves_video/lib/aves_video.dart | 1 + plugins/aves_video/lib/src/controller.dart | 28 +-- plugins/aves_video/lib/src/stream.dart | 22 +++ pubspec.lock | 7 + pubspec.yaml | 2 + 36 files changed, 360 insertions(+), 114 deletions(-) rename plugins/aves_model/lib/src/{entry_base.dart => entry/base.dart} (100%) rename {lib/model => plugins/aves_model/lib/src}/video/keys.dart (100%) create mode 100644 plugins/aves_model/lib/src/video/stream_types.dart create mode 100644 plugins/aves_utils/.gitignore create mode 100644 plugins/aves_utils/.metadata create mode 100644 plugins/aves_utils/analysis_options.yaml create mode 100644 plugins/aves_utils/lib/aves_utils.dart rename {lib/utils => plugins/aves_utils/lib/src}/change_notifier.dart (100%) rename {lib/services/common => plugins/aves_utils/lib/src}/optional_event_channel.dart (100%) create mode 100644 plugins/aves_utils/pubspec.lock create mode 100644 plugins/aves_utils/pubspec.yaml create mode 100644 plugins/aves_video/lib/src/stream.dart diff --git a/lib/model/entry/entry.dart b/lib/model/entry/entry.dart index cfa81b453..268357e2a 100644 --- a/lib/model/entry/entry.dart +++ b/lib/model/entry/entry.dart @@ -11,7 +11,7 @@ import 'package:aves/model/source/trash.dart'; import 'package:aves/ref/mime_types.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/format.dart'; -import 'package:aves/utils/change_notifier.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/utils/time_utils.dart'; import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; diff --git a/lib/model/entry/extensions/catalog.dart b/lib/model/entry/extensions/catalog.dart index 897f017a8..6a7aa331e 100644 --- a/lib/model/entry/extensions/catalog.dart +++ b/lib/model/entry/extensions/catalog.dart @@ -6,7 +6,6 @@ import 'package:aves/model/video/metadata.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/services/metadata/svg_metadata_service.dart'; -// TODO TLAD [split] need props extension ExtraAvesEntryCatalog on AvesEntry { Future catalog({required bool background, required bool force, required bool persist}) async { if (isCatalogued && !force) return; diff --git a/lib/model/entry/extensions/info.dart b/lib/model/entry/extensions/info.dart index 4087d10ac..46649a95f 100644 --- a/lib/model/entry/extensions/info.dart +++ b/lib/model/entry/extensions/info.dart @@ -4,7 +4,6 @@ import 'dart:collection'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/extensions/multipage.dart'; import 'package:aves/model/entry/extensions/props.dart'; -import 'package:aves/model/video/keys.dart'; import 'package:aves/model/video/metadata.dart'; import 'package:aves/ref/mime_types.dart'; import 'package:aves/services/common/services.dart'; @@ -12,11 +11,11 @@ import 'package:aves/services/metadata/svg_metadata_service.dart'; import 'package:aves/theme/colors.dart'; import 'package:aves/utils/constants.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_dir.dart'; +import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -// TODO TLAD [split] need props/multipage extension ExtraAvesEntryInfo on AvesEntry { // directory names may contain the name of their parent directory (as prefix + '/') // directory names may contain an index (as suffix in '[]') @@ -82,27 +81,27 @@ extension ExtraAvesEntryInfo on AvesEntry { if (mediaInfo.containsKey(Keys.streams)) { String getTypeText(Map stream) { - final type = stream[Keys.streamType] ?? StreamTypes.unknown; + final type = stream[Keys.streamType] ?? MediaStreamTypes.unknown; switch (type) { - case StreamTypes.attachment: + case MediaStreamTypes.attachment: return 'Attachment'; - case StreamTypes.audio: + case MediaStreamTypes.audio: return 'Audio'; - case StreamTypes.metadata: + case MediaStreamTypes.metadata: return 'Metadata'; - case StreamTypes.subtitle: - case StreamTypes.timedText: + case MediaStreamTypes.subtitle: + case MediaStreamTypes.timedText: return 'Text'; - case StreamTypes.video: + case MediaStreamTypes.video: return stream.containsKey(Keys.fpsDen) ? 'Video' : 'Image'; - case StreamTypes.unknown: + case MediaStreamTypes.unknown: default: return 'Unknown'; } } final allStreams = (mediaInfo[Keys.streams] as List).cast(); - final attachmentStreams = allStreams.where((stream) => stream[Keys.streamType] == StreamTypes.attachment).toList(); + final attachmentStreams = allStreams.where((stream) => stream[Keys.streamType] == MediaStreamTypes.attachment).toList(); final knownStreams = allStreams.whereNot(attachmentStreams.contains); // display known streams as separate directories (e.g. video, audio, subs) diff --git a/lib/model/entry/extensions/metadata_edition.dart b/lib/model/entry/extensions/metadata_edition.dart index c283b873f..eaa156585 100644 --- a/lib/model/entry/extensions/metadata_edition.dart +++ b/lib/model/entry/extensions/metadata_edition.dart @@ -21,7 +21,6 @@ import 'package:latlong2/latlong.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:xml/xml.dart'; -// TODO TLAD [split] need props/catalog extension ExtraAvesEntryMetadataEdition on AvesEntry { Future> editDate(DateModifier userModifier) async { final dataTypes = {}; diff --git a/lib/model/query.dart b/lib/model/query.dart index df48d2206..82be471d9 100644 --- a/lib/model/query.dart +++ b/lib/model/query.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:aves/utils/change_notifier.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:flutter/foundation.dart'; class Query extends ChangeNotifier { diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index 0856b3c3e..ea63e38e3 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -14,7 +14,7 @@ import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/enums/map_style.dart'; import 'package:aves/model/source/enums/enums.dart'; import 'package:aves/services/accessibility_service.dart'; -import 'package:aves/services/common/optional_event_channel.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/common/search/page.dart'; diff --git a/lib/model/source/collection_lens.dart b/lib/model/source/collection_lens.dart index 194236e83..801763194 100644 --- a/lib/model/source/collection_lens.dart +++ b/lib/model/source/collection_lens.dart @@ -19,7 +19,7 @@ import 'package:aves/model/source/events.dart'; import 'package:aves/model/source/location/location.dart'; import 'package:aves/model/source/section_keys.dart'; import 'package:aves/model/source/tag.dart'; -import 'package:aves/utils/change_notifier.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/utils/collection_utils.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; diff --git a/lib/model/video/metadata.dart b/lib/model/video/metadata.dart index 73c38abae..2691bb6fe 100644 --- a/lib/model/video/metadata.dart +++ b/lib/model/video/metadata.dart @@ -4,7 +4,6 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/metadata/catalog.dart'; import 'package:aves/model/video/channel_layouts.dart'; import 'package:aves/model/video/codecs.dart'; -import 'package:aves/model/video/keys.dart'; import 'package:aves/model/video/profiles/aac.dart'; import 'package:aves/model/video/profiles/h264.dart'; import 'package:aves/model/video/profiles/hevc.dart'; @@ -17,6 +16,7 @@ import 'package:aves/utils/math_utils.dart'; import 'package:aves/utils/string_utils.dart'; import 'package:aves/utils/time_utils.dart'; import 'package:aves/widgets/viewer/video/fijkplayer.dart'; +import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; import 'package:fijkplayer/fijkplayer.dart'; import 'package:flutter/foundation.dart'; @@ -230,7 +230,7 @@ class VideoMetadataFormatter { } break; case Keys.codecPixelFormat: - if (streamType == StreamTypes.video) { + if (streamType == MediaStreamTypes.video) { // this is just a short name used by FFmpeg // user-friendly descriptions for related enums are defined in libavutil/pixfmt.h save('Pixel Format', (value as String).toUpperCase()); @@ -425,13 +425,3 @@ class VideoMetadataFormatter { return '${(size / divider / divider).toStringAsFixed(round)} M$unit'; } } - -class StreamTypes { - static const attachment = 'attachment'; - static const audio = 'audio'; - static const metadata = 'metadata'; - static const subtitle = 'subtitle'; - static const timedText = 'timedtext'; - static const unknown = 'unknown'; - static const video = 'video'; -} diff --git a/lib/services/media/media_session_service.dart b/lib/services/media/media_session_service.dart index ed645eadb..8280965c7 100644 --- a/lib/services/media/media_session_service.dart +++ b/lib/services/media/media_session_service.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:aves/model/entry/entry.dart'; -import 'package:aves/services/common/optional_event_channel.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves_video/aves_video.dart'; import 'package:equatable/equatable.dart'; diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 17f89b8d4..85fd93fae 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -18,7 +18,7 @@ import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/media_store_source.dart'; import 'package:aves/services/accessibility_service.dart'; -import 'package:aves/services/common/optional_event_channel.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/colors.dart'; import 'package:aves/theme/durations.dart'; diff --git a/lib/widgets/common/map/geo_map.dart b/lib/widgets/common/map/geo_map.dart index e18bda838..af2a37f98 100644 --- a/lib/widgets/common/map/geo_map.dart +++ b/lib/widgets/common/map/geo_map.dart @@ -11,7 +11,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/utils/change_notifier.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/utils/constants.dart'; import 'package:aves/utils/math_utils.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; diff --git a/lib/widgets/dialogs/video_stream_selection_dialog.dart b/lib/widgets/dialogs/video_stream_selection_dialog.dart index e5154ddf4..fe14da528 100644 --- a/lib/widgets/dialogs/video_stream_selection_dialog.dart +++ b/lib/widgets/dialogs/video_stream_selection_dialog.dart @@ -13,7 +13,7 @@ import 'aves_dialog.dart'; class VideoStreamSelectionDialog extends StatefulWidget { static const routeName = '/dialog/select_video_stream'; - final Map streams; + final Map streams; const VideoStreamSelectionDialog({ super.key, @@ -25,23 +25,23 @@ class VideoStreamSelectionDialog extends StatefulWidget { } class _VideoStreamSelectionDialogState extends State { - late List _videoStreams, _audioStreams, _textStreams; - StreamSummary? _currentVideo, _currentAudio, _currentText; + late List _videoStreams, _audioStreams, _textStreams; + MediaStreamSummary? _currentVideo, _currentAudio, _currentText; @override void initState() { super.initState(); - final byType = groupBy(widget.streams.keys, (v) => v.type); + final byType = groupBy(widget.streams.keys, (v) => v.type); // check width/height to exclude image streams (that are included among video streams) - _videoStreams = (byType[StreamType.video] ?? []).where((v) => v.width != null && v.height != null).toList(); - _audioStreams = (byType[StreamType.audio] ?? []); - _textStreams = [null, ...byType[StreamType.text] ?? []]; + _videoStreams = (byType[MediaStreamType.video] ?? []).where((v) => v.width != null && v.height != null).toList(); + _audioStreams = (byType[MediaStreamType.audio] ?? []); + _textStreams = [null, ...byType[MediaStreamType.text] ?? []]; final streamEntries = widget.streams.entries; - _currentVideo = streamEntries.firstWhereOrNull((kv) => kv.key.type == StreamType.video && kv.value)?.key; - _currentAudio = streamEntries.firstWhereOrNull((kv) => kv.key.type == StreamType.audio && kv.value)?.key; - _currentText = streamEntries.firstWhereOrNull((kv) => kv.key.type == StreamType.text && kv.value)?.key; + _currentVideo = streamEntries.firstWhereOrNull((kv) => kv.key.type == MediaStreamType.video && kv.value)?.key; + _currentAudio = streamEntries.firstWhereOrNull((kv) => kv.key.type == MediaStreamType.audio && kv.value)?.key; + _currentText = streamEntries.firstWhereOrNull((kv) => kv.key.type == MediaStreamType.text && kv.value)?.key; } @override @@ -97,7 +97,7 @@ class _VideoStreamSelectionDialogState extends State return language?.native ?? value; } - String _commonStreamName(StreamSummary? stream) { + String _commonStreamName(MediaStreamSummary? stream) { if (stream == null) return context.l10n.videoStreamSelectionDialogOff; final title = stream.title; final language = stream.language; @@ -111,9 +111,9 @@ class _VideoStreamSelectionDialogState extends State } } - String _streamName(StreamSummary? stream) { + String _streamName(MediaStreamSummary? stream) { final common = _commonStreamName(stream); - if (stream != null && stream.type == StreamType.video) { + if (stream != null && stream.type == MediaStreamType.video) { final w = stream.width; final h = stream.height; if (w != null && h != null) { @@ -126,9 +126,9 @@ class _VideoStreamSelectionDialogState extends State List _buildSection({ required IconData icon, required String title, - required List streams, - required StreamSummary? current, - required ValueSetter setter, + required List streams, + required MediaStreamSummary? current, + required ValueSetter setter, }) { return [ Padding( @@ -143,7 +143,7 @@ class _VideoStreamSelectionDialogState extends State ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), - child: TextDropdownButton( + child: TextDropdownButton( values: streams.whereNotNull().toList(), valueText: _streamName, value: current, @@ -156,8 +156,8 @@ class _VideoStreamSelectionDialogState extends State } void _submit(BuildContext context) => Navigator.maybeOf(context)?.pop({ - StreamType.video: _currentVideo, - StreamType.audio: _currentAudio, - StreamType.text: _currentText, + MediaStreamType.video: _currentVideo, + MediaStreamType.audio: _currentAudio, + MediaStreamType.text: _currentText, }); } diff --git a/lib/widgets/settings/common/quick_actions/editor_page.dart b/lib/widgets/settings/common/quick_actions/editor_page.dart index 4736dd4d4..120e2e55d 100644 --- a/lib/widgets/settings/common/quick_actions/editor_page.dart +++ b/lib/widgets/settings/common/quick_actions/editor_page.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/utils/change_notifier.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/utils/constants.dart'; import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; diff --git a/lib/widgets/viewer/action/video_action_delegate.dart b/lib/widgets/viewer/action/video_action_delegate.dart index 81d91e871..df67b5a91 100644 --- a/lib/widgets/viewer/action/video_action_delegate.dart +++ b/lib/widgets/viewer/action/video_action_delegate.dart @@ -144,10 +144,10 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix Future _showStreamSelectionDialog(BuildContext context, AvesVideoController controller) async { final streams = controller.streams; - final currentSelectedStreams = await Future.wait(StreamType.values.map(controller.getSelectedStream)); + final currentSelectedStreams = await Future.wait(MediaStreamType.values.map(controller.getSelectedStream)); final currentSelectedIndices = currentSelectedStreams.whereNotNull().map((v) => v.index).toSet(); - final userSelectedStreams = await showDialog>( + final userSelectedStreams = await showDialog>( context: context, builder: (context) => VideoStreamSelectionDialog( streams: Map.fromEntries(streams.map((stream) => MapEntry(stream, currentSelectedIndices.contains(stream.index)))), @@ -156,7 +156,7 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix ); if (userSelectedStreams == null || userSelectedStreams.isEmpty) return; - await Future.forEach>( + await Future.forEach>( userSelectedStreams.entries, (kv) => controller.selectStream(kv.key, kv.value), ); diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index 876ef773b..900943741 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -15,7 +15,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/durations.dart'; -import 'package:aves/utils/change_notifier.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart'; diff --git a/lib/widgets/viewer/video/fijkplayer.dart b/lib/widgets/viewer/video/fijkplayer.dart index 1ee9b2a92..bd373c087 100644 --- a/lib/widgets/viewer/video/fijkplayer.dart +++ b/lib/widgets/viewer/video/fijkplayer.dart @@ -2,10 +2,8 @@ import 'dart:async'; import 'package:aves/model/settings/enums/video_loop_mode.dart'; import 'package:aves/model/settings/settings.dart'; -import 'package:aves/model/video/keys.dart'; -import 'package:aves/model/video/metadata.dart'; -import 'package:aves/services/common/optional_event_channel.dart'; -import 'package:aves/utils/change_notifier.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:aves_video/aves_video.dart'; import 'package:collection/collection.dart'; import 'package:fijkplayer/fijkplayer.dart'; @@ -23,7 +21,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController { final StreamController _speedStreamController = StreamController.broadcast(); final AChangeNotifier _completedNotifier = AChangeNotifier(); Offset _macroBlockCrop = Offset.zero; - final List _streams = []; + final List _streams = []; Timer? _initialPlayTimer; double _speed = 1; double _volume = 1; @@ -257,7 +255,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController { if (type != null) { final width = stream[Keys.width] as int?; final height = stream[Keys.height] as int?; - _streams.add(StreamSummary( + _streams.add(MediaStreamSummary( type: type, index: stream[Keys.index], codecName: stream[Keys.codecName], @@ -267,16 +265,16 @@ class IjkPlayerAvesVideoController extends AvesVideoController { height: height, )); switch (type) { - case StreamType.video: + case MediaStreamType.video: // check width/height to exclude image streams (that are included among video streams) if (width != null && height != null) { videoStreamCount++; } break; - case StreamType.audio: + case MediaStreamType.audio: audioStreamCount++; break; - case StreamType.text: + case MediaStreamType.text: textStreamCount++; break; } @@ -285,7 +283,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController { canSelectStreamNotifier.value = videoStreamCount > 1 || audioStreamCount > 1 || textStreamCount > 0; - final selectedVideo = await getSelectedStream(StreamType.video); + final selectedVideo = await getSelectedStream(MediaStreamType.video); if (selectedVideo != null) { final streamIndex = selectedVideo.index; final streamInfo = allStreams.firstWhereOrNull((stream) => stream[Keys.index] == streamIndex); @@ -435,7 +433,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController { // 1) prevent video stream acceleration to catch up with audio // 2) apply timed text stream @override - Future selectStream(StreamType type, StreamSummary? selected) async { + Future selectStream(MediaStreamType type, MediaStreamSummary? selected) async { final current = await getSelectedStream(type); if (current != selected) { if (selected != null) { @@ -446,7 +444,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController { } else if (current != null) { await _instance.deselectTrack(current.index!); } - if (type == StreamType.text) { + if (type == MediaStreamType.text) { _timedTextStreamController.add(null); } await seekTo(currentPosition); @@ -454,13 +452,13 @@ class IjkPlayerAvesVideoController extends AvesVideoController { } @override - Future getSelectedStream(StreamType type) async { + Future getSelectedStream(MediaStreamType type) async { final currentIndex = await _instance.getSelectedTrack(type.code); return currentIndex != -1 ? _streams.firstWhereOrNull((v) => v.index == currentIndex) : null; } @override - List get streams => _streams; + List get streams => _streams; @override Future captureFrame() { @@ -556,16 +554,16 @@ extension ExtraFijkPlayer on FijkPlayer { } } -extension ExtraStreamType on StreamType { - static StreamType? fromTypeString(String? type) { +extension ExtraStreamType on MediaStreamType { + static MediaStreamType? fromTypeString(String? type) { switch (type) { - case StreamTypes.video: - return StreamType.video; - case StreamTypes.audio: - return StreamType.audio; - case StreamTypes.subtitle: - case StreamTypes.timedText: - return StreamType.text; + case MediaStreamTypes.video: + return MediaStreamType.video; + case MediaStreamTypes.audio: + return MediaStreamType.audio; + case MediaStreamTypes.subtitle: + case MediaStreamTypes.timedText: + return MediaStreamType.text; default: return null; } @@ -574,11 +572,11 @@ extension ExtraStreamType on StreamType { int get code { // codes from ijkplayer ITrackInfo.java switch (this) { - case StreamType.video: + case MediaStreamType.video: return 1; - case StreamType.audio: + case MediaStreamType.audio: return 2; - case StreamType.text: + case MediaStreamType.text: // TIMEDTEXT = 3, SUBTITLE = 4 return 3; default: diff --git a/lib/widgets/viewer/video/flutter_vlc_player.dart b/lib/widgets/viewer/video/flutter_vlc_player.dart index df28f0ffc..f9de65fbe 100644 --- a/lib/widgets/viewer/video/flutter_vlc_player.dart +++ b/lib/widgets/viewer/video/flutter_vlc_player.dart @@ -2,7 +2,7 @@ // import 'dart:io'; // // import 'package:aves/model/entry.dart'; -// import 'package:aves/utils/change_notifier.dart'; +// import 'package:aves_utils/aves_utils.dart'; // import 'package:aves_video/aves_video.dart'; // import 'package:flutter/material.dart'; // import 'package:flutter/src/foundation/change_notifier.dart'; diff --git a/lib/widgets/viewer/video/video_player.dart b/lib/widgets/viewer/video/video_player.dart index b3b4a663c..0aa9cf8c1 100644 --- a/lib/widgets/viewer/video/video_player.dart +++ b/lib/widgets/viewer/video/video_player.dart @@ -1,7 +1,7 @@ // import 'dart:async'; // // import 'package:aves/model/entry.dart'; -// import 'package:aves/utils/change_notifier.dart'; +// import 'package:aves_utils/aves_utils.dart'; // import 'package:aves_video/aves_video.dart'; // import 'package:flutter/src/foundation/change_notifier.dart'; // import 'package:flutter/src/widgets/framework.dart'; diff --git a/plugins/aves_model/analysis_options.yaml b/plugins/aves_model/analysis_options.yaml index a5744c1cf..f04c6cf0f 100644 --- a/plugins/aves_model/analysis_options.yaml +++ b/plugins/aves_model/analysis_options.yaml @@ -1,4 +1 @@ -include: package:flutter_lints/flutter.yaml - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +include: ../../analysis_options.yaml diff --git a/plugins/aves_model/lib/aves_model.dart b/plugins/aves_model/lib/aves_model.dart index 4f604ce32..d892a954c 100644 --- a/plugins/aves_model/lib/aves_model.dart +++ b/plugins/aves_model/lib/aves_model.dart @@ -1,3 +1,5 @@ library aves_model; -export 'src/entry_base.dart'; +export 'src/entry/base.dart'; +export 'src/video/keys.dart'; +export 'src/video/stream_types.dart'; diff --git a/plugins/aves_model/lib/src/entry_base.dart b/plugins/aves_model/lib/src/entry/base.dart similarity index 100% rename from plugins/aves_model/lib/src/entry_base.dart rename to plugins/aves_model/lib/src/entry/base.dart diff --git a/lib/model/video/keys.dart b/plugins/aves_model/lib/src/video/keys.dart similarity index 100% rename from lib/model/video/keys.dart rename to plugins/aves_model/lib/src/video/keys.dart diff --git a/plugins/aves_model/lib/src/video/stream_types.dart b/plugins/aves_model/lib/src/video/stream_types.dart new file mode 100644 index 000000000..d2be820f3 --- /dev/null +++ b/plugins/aves_model/lib/src/video/stream_types.dart @@ -0,0 +1,9 @@ +class MediaStreamTypes { + static const attachment = 'attachment'; + static const audio = 'audio'; + static const metadata = 'metadata'; + static const subtitle = 'subtitle'; + static const timedText = 'timedtext'; + static const unknown = 'unknown'; + static const video = 'video'; +} diff --git a/plugins/aves_utils/.gitignore b/plugins/aves_utils/.gitignore new file mode 100644 index 000000000..28124a571 --- /dev/null +++ b/plugins/aves_utils/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +#/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/plugins/aves_utils/.metadata b/plugins/aves_utils/.metadata new file mode 100644 index 000000000..ad910f56c --- /dev/null +++ b/plugins/aves_utils/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 2ad6cd72c040113b47ee9055e722606a490ef0da + channel: stable + +project_type: package diff --git a/plugins/aves_utils/analysis_options.yaml b/plugins/aves_utils/analysis_options.yaml new file mode 100644 index 000000000..f04c6cf0f --- /dev/null +++ b/plugins/aves_utils/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options.yaml diff --git a/plugins/aves_utils/lib/aves_utils.dart b/plugins/aves_utils/lib/aves_utils.dart new file mode 100644 index 000000000..1921022e4 --- /dev/null +++ b/plugins/aves_utils/lib/aves_utils.dart @@ -0,0 +1,4 @@ +library aves_utils; + +export 'src/change_notifier.dart'; +export 'src/optional_event_channel.dart'; diff --git a/lib/utils/change_notifier.dart b/plugins/aves_utils/lib/src/change_notifier.dart similarity index 100% rename from lib/utils/change_notifier.dart rename to plugins/aves_utils/lib/src/change_notifier.dart diff --git a/lib/services/common/optional_event_channel.dart b/plugins/aves_utils/lib/src/optional_event_channel.dart similarity index 100% rename from lib/services/common/optional_event_channel.dart rename to plugins/aves_utils/lib/src/optional_event_channel.dart diff --git a/plugins/aves_utils/pubspec.lock b/plugins/aves_utils/pubspec.lock new file mode 100644 index 000000000..b61cdad6b --- /dev/null +++ b/plugins/aves_utils/pubspec.lock @@ -0,0 +1,181 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" + source: hosted + version: "2.10.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" + source: hosted + version: "1.17.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" + source: hosted + version: "2.0.1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + lints: + dependency: transitive + description: + name: lints + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" + source: hosted + version: "0.12.13" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + path: + dependency: transitive + description: + name: path + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" + source: hosted + version: "1.8.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" + source: hosted + version: "0.4.16" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" +sdks: + dart: ">=2.19.4 <3.0.0" + flutter: ">=1.17.0" diff --git a/plugins/aves_utils/pubspec.yaml b/plugins/aves_utils/pubspec.yaml new file mode 100644 index 000000000..3828c7ab0 --- /dev/null +++ b/plugins/aves_utils/pubspec.yaml @@ -0,0 +1,15 @@ +name: aves_utils +version: 0.0.1 +publish_to: none + +environment: + sdk: '>=2.19.4 <3.0.0' + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_lints: + +flutter: diff --git a/plugins/aves_video/lib/aves_video.dart b/plugins/aves_video/lib/aves_video.dart index 90e236285..6c308814d 100644 --- a/plugins/aves_video/lib/aves_video.dart +++ b/plugins/aves_video/lib/aves_video.dart @@ -1,3 +1,4 @@ library aves_video; export 'src/controller.dart'; +export 'src/stream.dart'; diff --git a/plugins/aves_video/lib/src/controller.dart b/plugins/aves_video/lib/src/controller.dart index 94330e789..3d658ecb8 100644 --- a/plugins/aves_video/lib/src/controller.dart +++ b/plugins/aves_video/lib/src/controller.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:aves_model/aves_model.dart'; +import 'package:aves_video/src/stream.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; @@ -86,11 +87,11 @@ abstract class AvesVideoController { set speed(double speed); - Future selectStream(StreamType type, StreamSummary? selected); + Future selectStream(MediaStreamType type, MediaStreamSummary? selected); - Future getSelectedStream(StreamType type); + Future getSelectedStream(MediaStreamType type); - List get streams; + List get streams; Future captureFrame(); @@ -108,27 +109,6 @@ enum VideoStatus { error, } -enum StreamType { video, audio, text } - -class StreamSummary { - final StreamType type; - final int? index, width, height; - final String? codecName, language, title; - - const StreamSummary({ - required this.type, - required this.index, - required this.codecName, - required this.language, - required this.title, - required this.width, - required this.height, - }); - - @override - String toString() => '$runtimeType#${shortHash(this)}{type: type, index: $index, codecName: $codecName, language: $language, title: $title, width: $width, height: $height}'; -} - abstract class PlaybackStateHandler { Future getResumeTime({required int entryId, required BuildContext context}); diff --git a/plugins/aves_video/lib/src/stream.dart b/plugins/aves_video/lib/src/stream.dart new file mode 100644 index 000000000..93c4bb05b --- /dev/null +++ b/plugins/aves_video/lib/src/stream.dart @@ -0,0 +1,22 @@ +import 'package:flutter/foundation.dart'; + +enum MediaStreamType { video, audio, text } + +class MediaStreamSummary { + final MediaStreamType type; + final int? index, width, height; + final String? codecName, language, title; + + const MediaStreamSummary({ + required this.type, + required this.index, + required this.codecName, + required this.language, + required this.title, + required this.width, + required this.height, + }); + + @override + String toString() => '$runtimeType#${shortHash(this)}{type: type, index: $index, codecName: $codecName, language: $language, title: $title, width: $width, height: $height}'; +} diff --git a/pubspec.lock b/pubspec.lock index c894bb047..26c878c58 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -105,6 +105,13 @@ packages: relative: true source: path version: "0.0.1" + aves_utils: + dependency: "direct main" + description: + path: "plugins/aves_utils" + relative: true + source: path + version: "0.0.1" aves_video: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 74b0dc351..5357ab73f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,6 +43,8 @@ dependencies: path: plugins/aves_video aves_ui: path: plugins/aves_ui + aves_utils: + path: plugins/aves_utils charts_flutter: git: url: https://github.com/fzyzcjy/charts.git