From fad1bf14ce5bfb1bcee5b1fc44e7d6acedfba07d Mon Sep 17 00:00:00 2001 From: Dushant Date: Sat, 3 Jun 2023 11:09:41 +0530 Subject: [PATCH] Add test and made fixes --- lib/consts.dart | 1 - lib/widgets/previewer.dart | 6 +-- lib/widgets/uint8_audio_player.dart | 76 ++++++++++++++++------------- pubspec.yaml | 2 + test/widgets/previewer_test.dart | 17 +++++++ 5 files changed, 65 insertions(+), 37 deletions(-) diff --git a/lib/consts.dart b/lib/consts.dart index 47891ebe..f6b812a9 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -78,7 +78,6 @@ const kTabHeight = 45.0; const kHeaderHeight = 32.0; const kSegmentHeight = 24.0; const kTextButtonMinWidth = 36.0; -const kSliderWidth = 160.0; const kRandMax = 100000; diff --git a/lib/widgets/previewer.dart b/lib/widgets/previewer.dart index e990d3fd..8cb9c76f 100644 --- a/lib/widgets/previewer.dart +++ b/lib/widgets/previewer.dart @@ -39,9 +39,9 @@ class _PreviewerState extends State { if (widget.type == kTypeAudio) { return Uint8AudioPlayer( bytes: widget.bytes, - type: widget.type, - subtype: widget.subtype, - errorBuilder: (context, _, stacktrace) { + type: widget.type!, + subtype: widget.subtype!, + errorBuilder: (context, error, stacktrace) { return const ErrorMessage(message: kAudioError); }, ); diff --git a/lib/widgets/uint8_audio_player.dart b/lib/widgets/uint8_audio_player.dart index f9f5fcf4..30b751dd 100644 --- a/lib/widgets/uint8_audio_player.dart +++ b/lib/widgets/uint8_audio_player.dart @@ -12,11 +12,10 @@ typedef AudioErrorWidgetBuilder = Widget Function( // Uint8List AudioSource for just_audio class Uint8AudioSource extends StreamAudioSource { - Uint8AudioSource(this.bytes, {this.type = 'audio', this.subtype = 'mpeg'}); + Uint8AudioSource(this.bytes, {required this.contentType}); final List bytes; - final String? type; - final String? subtype; + final String contentType; @override Future request([int? start, int? end]) async { @@ -27,7 +26,7 @@ class Uint8AudioSource extends StreamAudioSource { contentLength: end - start, offset: start, stream: Stream.value(bytes.sublist(start, end)), - contentType: '$type/$subtype', + contentType: contentType, ); } } @@ -37,14 +36,14 @@ class Uint8AudioPlayer extends StatefulWidget { const Uint8AudioPlayer({ super.key, required this.bytes, - this.type, - this.subtype, + required this.type, + required this.subtype, required this.errorBuilder, }); final Uint8List bytes; - final String? type; - final String? subtype; + final String type; + final String subtype; final AudioErrorWidgetBuilder errorBuilder; @override @@ -56,8 +55,10 @@ class _Uint8AudioPlayerState extends State { @override void initState() { - player.setAudioSource(Uint8AudioSource(widget.bytes, - type: widget.type, subtype: widget.subtype)); + player.setAudioSource(Uint8AudioSource( + widget.bytes, + contentType: '${widget.type}/${widget.subtype}', + )); super.initState(); } @@ -85,29 +86,32 @@ class _Uint8AudioPlayerState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ // Audio Player - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // Duration Position Builder (time elapsed) - _buildDuration( - player.positionStream, - maxDuration: player.duration, - ), + Padding( + padding: kPh20v10, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Duration Position Builder (time elapsed) + _buildDuration( + player.positionStream, + maxDuration: player.duration, + ), - // Slider to view & change Duration Position - _buildPositionBar( - player.positionStream, - maxDuration: player.duration, - onChanged: (value) => - player.seek(Duration(seconds: value.toInt())), - ), + // Slider to view & change Duration Position + _buildPositionBar( + player.positionStream, + maxDuration: player.duration, + onChanged: (value) => + player.seek(Duration(seconds: value.toInt())), + ), - // Total Duration - Text( - audioPosition(player.duration), - style: TextStyle(fontFamily: kCodeStyle.fontFamily), - ), - ], + // Total Duration + Text( + audioPosition(player.duration), + style: TextStyle(fontFamily: kCodeStyle.fontFamily), + ), + ], + ), ), // Audio Player Controls @@ -134,6 +138,13 @@ class _Uint8AudioPlayerState extends State { ), ], ); + } else if (processingState == ProcessingState.idle) { + // Error in Loading AudioSource + return widget.errorBuilder( + context, + ErrorDescription('${player.audioSource} Loading Error'), + snapshot.stackTrace, + ); } else { return const Center(child: CircularProgressIndicator()); } @@ -197,8 +208,7 @@ class _Uint8AudioPlayerState extends State { return StreamBuilder( stream: stream, builder: (context, snapshot) { - return SizedBox( - width: kSliderWidth, + return Flexible( child: SliderTheme( data: SliderTheme.of(context).copyWith( trackShape: const RectangularSliderTrackShape(), diff --git a/pubspec.yaml b/pubspec.yaml index a8f25443..efbab17d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,6 +34,8 @@ dependencies: flutter_markdown: ^0.6.14 markdown: ^7.1.0 just_audio: ^0.9.34 + # just_audio_mpv: ^0.1.6 # Uncomment for linux support of just_audio package + # just_audio_windows: ^0.2.0 # Uncomment for windows support of just_audio package dev_dependencies: flutter_test: diff --git a/test/widgets/previewer_test.dart b/test/widgets/previewer_test.dart index 0e83d02d..6ace405b 100644 --- a/test/widgets/previewer_test.dart +++ b/test/widgets/previewer_test.dart @@ -118,4 +118,21 @@ void main() { await tester.pumpAndSettle(); expect(find.text(kImageError), findsOneWidget); }); + + testWidgets('Testing when type/subtype is audio/mpeg corrupted', + (tester) async { + Uint8List bytesAudioCorrupt = + Uint8List.fromList(List.generate(100, (index) => index)); + await tester.pumpWidget( + MaterialApp( + title: 'Previewer', + home: Scaffold( + body: Previewer( + type: 'audio', subtype: 'mpeg', bytes: bytesAudioCorrupt), + ), + ), + ); + await tester.pumpAndSettle(); + expect(find.text(kAudioError), findsOneWidget); + }); }