This commit is contained in:
Thibault Deckers 2023-03-15 00:17:51 +01:00
parent dc936ee7c5
commit 4a3b0e4a4e
36 changed files with 360 additions and 114 deletions

View file

@ -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';

View file

@ -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<void> catalog({required bool background, required bool force, required bool persist}) async {
if (isCatalogued && !force) return;

View file

@ -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<Map>();
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)

View file

@ -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<Set<EntryDataType>> editDate(DateModifier userModifier) async {
final dataTypes = <EntryDataType>{};

View file

@ -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 {

View file

@ -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';

View file

@ -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';

View file

@ -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';
}

View file

@ -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';

View file

@ -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';

View file

@ -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';

View file

@ -13,7 +13,7 @@ import 'aves_dialog.dart';
class VideoStreamSelectionDialog extends StatefulWidget {
static const routeName = '/dialog/select_video_stream';
final Map<StreamSummary, bool> streams;
final Map<MediaStreamSummary, bool> streams;
const VideoStreamSelectionDialog({
super.key,
@ -25,23 +25,23 @@ class VideoStreamSelectionDialog extends StatefulWidget {
}
class _VideoStreamSelectionDialogState extends State<VideoStreamSelectionDialog> {
late List<StreamSummary?> _videoStreams, _audioStreams, _textStreams;
StreamSummary? _currentVideo, _currentAudio, _currentText;
late List<MediaStreamSummary?> _videoStreams, _audioStreams, _textStreams;
MediaStreamSummary? _currentVideo, _currentAudio, _currentText;
@override
void initState() {
super.initState();
final byType = groupBy<StreamSummary, StreamType>(widget.streams.keys, (v) => v.type);
final byType = groupBy<MediaStreamSummary, MediaStreamType>(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<VideoStreamSelectionDialog>
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<VideoStreamSelectionDialog>
}
}
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<VideoStreamSelectionDialog>
List<Widget> _buildSection({
required IconData icon,
required String title,
required List<StreamSummary?> streams,
required StreamSummary? current,
required ValueSetter<StreamSummary?> setter,
required List<MediaStreamSummary?> streams,
required MediaStreamSummary? current,
required ValueSetter<MediaStreamSummary?> setter,
}) {
return [
Padding(
@ -143,7 +143,7 @@ class _VideoStreamSelectionDialogState extends State<VideoStreamSelectionDialog>
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: TextDropdownButton<StreamSummary>(
child: TextDropdownButton<MediaStreamSummary>(
values: streams.whereNotNull().toList(),
valueText: _streamName,
value: current,
@ -156,8 +156,8 @@ class _VideoStreamSelectionDialogState extends State<VideoStreamSelectionDialog>
}
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,
});
}

View file

@ -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';

View file

@ -144,10 +144,10 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
Future<void> _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<Map<StreamType, StreamSummary?>>(
final userSelectedStreams = await showDialog<Map<MediaStreamType, MediaStreamSummary?>>(
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<MapEntry<StreamType, StreamSummary?>>(
await Future.forEach<MapEntry<MediaStreamType, MediaStreamSummary?>>(
userSelectedStreams.entries,
(kv) => controller.selectStream(kv.key, kv.value),
);

View file

@ -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';

View file

@ -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<double> _speedStreamController = StreamController.broadcast();
final AChangeNotifier _completedNotifier = AChangeNotifier();
Offset _macroBlockCrop = Offset.zero;
final List<StreamSummary> _streams = [];
final List<MediaStreamSummary> _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<void> selectStream(StreamType type, StreamSummary? selected) async {
Future<void> 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<StreamSummary?> getSelectedStream(StreamType type) async {
Future<MediaStreamSummary?> getSelectedStream(MediaStreamType type) async {
final currentIndex = await _instance.getSelectedTrack(type.code);
return currentIndex != -1 ? _streams.firstWhereOrNull((v) => v.index == currentIndex) : null;
}
@override
List<StreamSummary> get streams => _streams;
List<MediaStreamSummary> get streams => _streams;
@override
Future<Uint8List> 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:

View file

@ -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';

View file

@ -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';

View file

@ -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

View file

@ -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';

View file

@ -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';
}

30
plugins/aves_utils/.gitignore vendored Normal file
View file

@ -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/

View file

@ -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

View file

@ -0,0 +1 @@
include: ../../analysis_options.yaml

View file

@ -0,0 +1,4 @@
library aves_utils;
export 'src/change_notifier.dart';
export 'src/optional_event_channel.dart';

View file

@ -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"

View file

@ -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:

View file

@ -1,3 +1,4 @@
library aves_video;
export 'src/controller.dart';
export 'src/stream.dart';

View file

@ -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<void> selectStream(StreamType type, StreamSummary? selected);
Future<void> selectStream(MediaStreamType type, MediaStreamSummary? selected);
Future<StreamSummary?> getSelectedStream(StreamType type);
Future<MediaStreamSummary?> getSelectedStream(MediaStreamType type);
List<StreamSummary> get streams;
List<MediaStreamSummary> get streams;
Future<Uint8List> 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<int?> getResumeTime({required int entryId, required BuildContext context});

View file

@ -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}';
}

View file

@ -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:

View file

@ -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