From a7c0fcf6f0d120d743a469841a82c436f02f13ef Mon Sep 17 00:00:00 2001 From: MohammadTaha Basiri Date: Mon, 4 Apr 2022 18:16:03 +0430 Subject: [PATCH] new video player complete version --- lib/models/overview_data.dart | 9 +- lib/models/slider_data.dart | 7 +- lib/models/studio_details_data.dart | 10 +- lib/routes/route_generator.dart | 9 +- lib/utils/action_sheet.dart | 4 +- lib/views/home/studio/studio.dart | 2 +- .../studio_details/studio_details.mobile.dart | 85 +++++++------ .../studio_details/studio_details.web.dart | 112 ++++++------------ .../studio_details/studio_details_state.dart | 2 +- .../widgets/details_tab_bar.dart | 59 +++++---- .../widgets/studio_details_widget.dart | 106 +++++++++-------- .../widgets/audio/audio_player_widget.dart | 2 +- lib/views/home/widgets/overview/podcast.dart | 6 +- lib/views/widgets/didvan/bnb.dart | 2 +- 14 files changed, 198 insertions(+), 217 deletions(-) diff --git a/lib/models/overview_data.dart b/lib/models/overview_data.dart index beba572..f4995b0 100644 --- a/lib/models/overview_data.dart +++ b/lib/models/overview_data.dart @@ -9,7 +9,8 @@ class OverviewData { final int? timeToRead; final int? duration; final String? reference; - final String? media; + final String? link; + final String? iframe; final bool forManagers; final String createdAt; final String type; @@ -27,7 +28,8 @@ class OverviewData { required this.marked, required this.comments, required this.forManagers, - this.media, + this.link, + this.iframe, this.duration, this.timeToRead, this.reference, @@ -51,7 +53,8 @@ class OverviewData { duration: json['duration'], type: json['type'] ?? '', marked: json['marked'] ?? true, - media: json['media'], + link: json['link'], + iframe: json['iframe'], categories: json['categories'] != null ? List.from( json['categories'].map( diff --git a/lib/models/slider_data.dart b/lib/models/slider_data.dart index a99c52d..c6ff0ed 100644 --- a/lib/models/slider_data.dart +++ b/lib/models/slider_data.dart @@ -2,26 +2,25 @@ class SliderData { final int id; final String title; final String image; - final String media; + final String link; const SliderData({ required this.id, required this.title, required this.image, - required this.media, + required this.link, }); factory SliderData.fromJson(Map json) => SliderData( id: json['id'], title: json['title'], image: json['image'], - media: json['media'], + link: json['link'], ); Map toJson() => { 'id': id, 'title': title, 'image': image, - 'media': media, }; } diff --git a/lib/models/studio_details_data.dart b/lib/models/studio_details_data.dart index b83722e..334b4b2 100644 --- a/lib/models/studio_details_data.dart +++ b/lib/models/studio_details_data.dart @@ -7,7 +7,8 @@ class StudioDetailsData { final String title; final String description; final String image; - final String media; + final String link; + final String? iframe; final String createdAt; final int order; bool marked; @@ -21,7 +22,8 @@ class StudioDetailsData { required this.title, required this.description, required this.image, - required this.media, + required this.link, + required this.iframe, required this.createdAt, required this.order, required this.marked, @@ -36,7 +38,8 @@ class StudioDetailsData { title: json['title'], description: json['description'], image: json['image'], - media: json['media'], + link: json['link'], + iframe: json['iframe'], createdAt: json['createdAt'], order: json['order'], marked: json['marked'], @@ -51,7 +54,6 @@ class StudioDetailsData { 'title': title, 'description': description, 'image': image, - 'media': media, 'createdAt': createdAt, 'order': order, 'marked': marked, diff --git a/lib/routes/route_generator.dart b/lib/routes/route_generator.dart index b70afa5..308bc61 100644 --- a/lib/routes/route_generator.dart +++ b/lib/routes/route_generator.dart @@ -180,8 +180,15 @@ class RouteGenerator { final shortestSide = MediaQuery.of(context).size.shortestSide; final bool useMobileLayout = shortestSide < 600; if (kIsWeb && !useMobileLayout) { + final deviceSize = MediaQuery.of(context).size; return MediaQuery( - data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), + data: MediaQuery.of(context).copyWith( + textScaleFactor: 1.0, + size: Size( + deviceSize.width / 16 * 9, + deviceSize.height, + ), + ), child: Container( color: Theme.of(context).colorScheme.background, alignment: Alignment.center, diff --git a/lib/utils/action_sheet.dart b/lib/utils/action_sheet.dart index b8c1ad0..bbb3c2c 100644 --- a/lib/utils/action_sheet.dart +++ b/lib/utils/action_sheet.dart @@ -80,7 +80,9 @@ class ActionSheetUtils { isScrollControlled: true, context: context, builder: (context) => Container( - padding: data.hasPadding ? const EdgeInsets.all(20) : EdgeInsets.zero, + padding: data.hasPadding + ? const EdgeInsets.all(20).copyWith(top: 0) + : EdgeInsets.zero, decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical( diff --git a/lib/views/home/studio/studio.dart b/lib/views/home/studio/studio.dart index 79619e8..296a552 100644 --- a/lib/views/home/studio/studio.dart +++ b/lib/views/home/studio/studio.dart @@ -126,7 +126,7 @@ class _StudioState extends State { emptyState: EmptyResult( onNewSearch: () => _focusNode.requestFocus(), ), - centerEmptyState: false, + centerEmptyState: true, enableEmptyState: state.studios.isEmpty, placeholder: state.videosSelected ? VideoOverview.placeHolder diff --git a/lib/views/home/studio/studio_details/studio_details.mobile.dart b/lib/views/home/studio/studio_details/studio_details.mobile.dart index ea72e90..5d89fca 100644 --- a/lib/views/home/studio/studio_details/studio_details.mobile.dart +++ b/lib/views/home/studio/studio_details/studio_details.mobile.dart @@ -1,10 +1,7 @@ -import 'dart:io'; - import 'package:better_player/better_player.dart'; import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart'; -import 'package:didvan/views/home/studio/studio_details/widgets/details_tab_bar.dart'; import 'package:didvan/views/home/studio/studio_details/widgets/studio_details_widget.dart'; import 'package:didvan/views/home/widgets/bookmark_button.dart'; import 'package:didvan/views/widgets/didvan/app_bar.dart'; @@ -12,8 +9,6 @@ import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:webview_flutter/webview_flutter.dart'; - class StudioDetails extends StatefulWidget { final Map pageData; @@ -24,7 +19,8 @@ class StudioDetails extends StatefulWidget { } class _StudioDetailsState extends State { - final _scrollController = ScrollController(); + int _currentlyPlayingId = 0; + late BetterPlayerController _betterPlayerController; @override void initState() { @@ -34,15 +30,12 @@ class _StudioDetailsState extends State { Duration.zero, () => state.getStudioDetails(widget.pageData['id']), ); - - if (Platform.isAndroid) WebView.platform = AndroidWebView(); super.initState(); } @override Widget build(BuildContext context) { final d = MediaQuery.of(context); - return Consumer( builder: (context, state, child) => StateHandler( state: state, @@ -54,6 +47,32 @@ class _StudioDetailsState extends State { } }, builder: (context, state) { + if (_currentlyPlayingId != state.studio.id) { + BetterPlayerDataSource betterPlayerDataSource = + BetterPlayerDataSource( + BetterPlayerDataSourceType.network, + state.studio.link, + ); + _betterPlayerController = BetterPlayerController( + BetterPlayerConfiguration( + aspectRatio: 16 / 9, + showPlaceholderUntilPlay: true, + controlsConfiguration: BetterPlayerControlsConfiguration( + enablePlaybackSpeed: false, + enableSubtitles: false, + enableAudioTracks: false, + progressBarPlayedColor: + Theme.of(context).colorScheme.secondary, + progressBarHandleColor: + Theme.of(context).colorScheme.secondary, + ), + fit: BoxFit.contain, + fullScreenAspectRatio: 16 / 9, + ), + betterPlayerDataSource: betterPlayerDataSource, + ); + _currentlyPlayingId = state.studio.id; + } return WillPopScope( onWillPop: () async { if (MediaService.currentPodcast != null) { @@ -63,7 +82,6 @@ class _StudioDetailsState extends State { }, child: SafeArea( child: Scaffold( - key: ValueKey(state.studio.id), backgroundColor: Theme.of(context).colorScheme.surface, appBar: PreferredSize( preferredSize: const Size.fromHeight(56), @@ -84,37 +102,22 @@ class _StudioDetailsState extends State { ), ), ), - body: Column( - children: [ - Directionality( - textDirection: TextDirection.ltr, - child: BetterPlayer.network( - 'https://studio-didvan.arvanvod.com/Vz01Bxq2bQ/nylPWJ4B63/h_,144_200,240_400,360_800,480_1215,720_1215,k.mp4.list/master.m3u8', - betterPlayerConfiguration: - const BetterPlayerConfiguration( - aspectRatio: 16 / 9, - controlsConfiguration: - BetterPlayerControlsConfiguration( - enablePlaybackSpeed: false, - enableSubtitles: false, - enableAudioTracks: false, + body: SingleChildScrollView( + physics: const NeverScrollableScrollPhysics(), + child: SizedBox( + height: d.size.height - d.padding.top - 56, + child: Column( + children: [ + BetterPlayer(controller: _betterPlayerController), + Expanded( + child: StudioDetailsWidget( + onMarkChanged: (id, value) => widget + .pageData['onMarkChanged'](id, value, true), ), - autoDetectFullscreenAspectRatio: true, - autoDetectFullscreenDeviceOrientation: true, - fullScreenAspectRatio: 16 / 9, ), - ), + ], ), - const DetailsTabBar( - isVideo: true, - ), - Expanded( - child: StudioDetailsWidget( - onMarkChanged: (id, value) => - widget.pageData['onMarkChanged'](id, value, true), - ), - ), - ], + ), ), ), ), @@ -123,4 +126,10 @@ class _StudioDetailsState extends State { ), ); } + + // @override + // void dispose() { + // _betterPlayerController.dispose(); + // super.dispose(); + // } } diff --git a/lib/views/home/studio/studio_details/studio_details.web.dart b/lib/views/home/studio/studio_details/studio_details.web.dart index a1409c2..b944905 100644 --- a/lib/views/home/studio/studio_details/studio_details.web.dart +++ b/lib/views/home/studio/studio_details/studio_details.web.dart @@ -1,16 +1,13 @@ import 'dart:ui' as ui; -import 'package:didvan/config/design_config.dart'; import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart'; -import 'package:didvan/views/home/studio/studio_details/widgets/details_tab_bar.dart'; import 'package:didvan/views/home/studio/studio_details/widgets/studio_details_widget.dart'; import 'package:didvan/views/home/widgets/bookmark_button.dart'; -import 'package:didvan/views/widgets/didvan/scaffold.dart'; +import 'package:didvan/views/widgets/didvan/app_bar.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:universal_html/html.dart' as html; @@ -24,8 +21,6 @@ class StudioDetails extends StatefulWidget { } class _StudioDetailsState extends State { - bool _isFullScreen = false; - @override void initState() { final state = context.read(); @@ -34,42 +29,12 @@ class _StudioDetailsState extends State { Duration.zero, () => state.getStudioDetails(widget.pageData['id']), ); - super.initState(); } - Future _changeFullSceen(bool value) async { - if (value) { - await SystemChrome.setEnabledSystemUIMode( - SystemUiMode.manual, - overlays: [], - ); - SystemChrome.setSystemUIOverlayStyle( - const SystemUiOverlayStyle( - systemNavigationBarColor: Colors.black, - ), - ); - await SystemChrome.setPreferredOrientations( - [DeviceOrientation.landscapeLeft], - ); - } else { - await SystemChrome.setEnabledSystemUIMode( - SystemUiMode.manual, - overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top], - ); - await SystemChrome.setPreferredOrientations( - [DeviceOrientation.portraitUp], - ); - DesignConfig.updateSystemUiOverlayStyle(); - } - setState(() { - _isFullScreen = value; - }); - } - @override Widget build(BuildContext context) { - final ds = MediaQuery.of(context).size; + final d = MediaQuery.of(context); return Consumer( builder: (context, state, child) => StateHandler( state: state, @@ -82,66 +47,61 @@ class _StudioDetailsState extends State { ..allowFullscreen = true ..src = Uri.dataFromString( '' + - state.studio.media, + state.studio.iframe!, mimeType: 'text/html', ).toString() ..style.border = 'none', ); return WillPopScope( onWillPop: () async { - if (_isFullScreen) { - await _changeFullSceen(false); - return false; - } if (MediaService.currentPodcast != null) { state.studio = MediaService.currentPodcast!; } return true; }, - child: DidvanScaffold( - padding: EdgeInsets.zero, - appBarData: _isFullScreen - ? null - : AppBarData( - isSmall: true, - title: state.studio.title, + child: SafeArea( + child: Scaffold( + backgroundColor: Theme.of(context).colorScheme.surface, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(56), + child: DidvanAppBar( + appBarData: AppBarData( trailing: BookmarkButton( itemId: state.studio.id, type: 'video', value: state.studio.marked, - onMarkChanged: (value) => widget - .pageData['onMarkChanged'](state.studio.id, value), + onMarkChanged: (value) { + widget.pageData['onMarkChanged']( + state.studio.id, value); + }, gestureSize: 48, ), + isSmall: true, + title: state.studio.title, ), - showSliversFirst: true, - slivers: [ - SliverAppBar( - automaticallyImplyLeading: false, - pinned: true, - elevation: 0, - toolbarHeight: - (_isFullScreen ? ds.height : ds.width * 9 / 16) + - 72 - - MediaQuery.of(context).padding.top, - flexibleSpace: Column( - children: const [ - AspectRatio( - aspectRatio: 16 / 9, - child: HtmlElementView(viewType: 'video'), - ), - DetailsTabBar( - isVideo: true, - ), - ], ), ), - ], - children: [ - StudioDetailsWidget( - onMarkChanged: widget.pageData['onMarkChanged'], + body: SingleChildScrollView( + physics: const NeverScrollableScrollPhysics(), + child: SizedBox( + height: d.size.height - d.padding.top - 56, + child: Column( + children: [ + const AspectRatio( + aspectRatio: 16 / 9, + child: HtmlElementView(viewType: 'video'), + ), + Expanded( + child: StudioDetailsWidget( + onMarkChanged: (id, value) => widget + .pageData['onMarkChanged'](id, value, true), + ), + ), + ], + ), + ), ), - ], + ), ), ); }, diff --git a/lib/views/home/studio/studio_details/studio_details_state.dart b/lib/views/home/studio/studio_details/studio_details_state.dart index bf7f5c8..b9aaf7a 100644 --- a/lib/views/home/studio/studio_details/studio_details_state.dart +++ b/lib/views/home/studio/studio_details/studio_details_state.dart @@ -111,7 +111,7 @@ class StudioDetailsState extends CoreProvier { MediaService.currentPodcast = studio; MediaService.podcastPlaylistArgs = args; await MediaService.handleAudioPlayback( - audioSource: studio.media, + audioSource: studio.link, id: studio.id, isVoiceMessage: false, ); diff --git a/lib/views/home/studio/studio_details/widgets/details_tab_bar.dart b/lib/views/home/studio/studio_details/widgets/details_tab_bar.dart index f5ef4d3..a16754a 100644 --- a/lib/views/home/studio/studio_details/widgets/details_tab_bar.dart +++ b/lib/views/home/studio/studio_details/widgets/details_tab_bar.dart @@ -16,7 +16,7 @@ class DetailsTabBar extends StatelessWidget { @override Widget build(BuildContext context) { - final state = context.read(); + final state = context.watch(); return WillPopScope( onWillPop: () async { state.selectedDetailsIndex = 0; @@ -35,38 +35,32 @@ class DetailsTabBar extends StatelessWidget { ) ], ), - child: FittedBox( - fit: BoxFit.scaleDown, - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: Row( - children: [ - _TabItem( - icon: DidvanIcons.description_solid, - title: 'توضیحات', - onTap: () => state.selectedDetailsIndex = 0, - isSelected: state.selectedDetailsIndex == 0, - isVideo: isVideo, - ), - _TabItem( - icon: DidvanIcons.chats_solid, - title: 'نظرات', - onTap: () { - state.selectedDetailsIndex = 1; - }, - isSelected: state.selectedDetailsIndex == 1, - isVideo: isVideo, - ), - _TabItem( - icon: DidvanIcons.puzzle_solid, - title: 'مطالب مرتبط', - onTap: () => state.selectedDetailsIndex = 2, - isSelected: state.selectedDetailsIndex == 2, - isVideo: isVideo, - ), - ], + child: Row( + children: [ + _TabItem( + icon: DidvanIcons.description_solid, + title: 'توضیحات', + onTap: () => state.selectedDetailsIndex = 0, + isSelected: state.selectedDetailsIndex == 0, + isVideo: isVideo, ), - ), + _TabItem( + icon: DidvanIcons.chats_solid, + title: 'نظرات', + onTap: () { + state.selectedDetailsIndex = 1; + }, + isSelected: state.selectedDetailsIndex == 1, + isVideo: isVideo, + ), + _TabItem( + icon: DidvanIcons.puzzle_solid, + title: 'مطالب مرتبط', + onTap: () => state.selectedDetailsIndex = 2, + isSelected: state.selectedDetailsIndex == 2, + isVideo: isVideo, + ), + ], ), ), ); @@ -106,6 +100,7 @@ class _TabItem extends StatelessWidget { child: Container( color: Colors.transparent, child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( icon, diff --git a/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart b/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart index bdfc44e..268309f 100644 --- a/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart +++ b/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart @@ -1,4 +1,5 @@ -import 'package:didvan/config/design_config.dart'; +import 'dart:math'; + import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/enums.dart'; @@ -28,38 +29,34 @@ class StudioDetailsWidget extends StatelessWidget { @override Widget build(BuildContext context) { final ds = MediaQuery.of(context).size; + return SafeArea( bottom: true, child: Consumer( builder: (context, state, child) { - bool isVideo = state.studio.media.contains('iframe'); + bool isVideo = state.studio.iframe != null; return Container( + height: max( + ds.height - + ds.width * 9 / 16 - + 72 - + MediaQuery.of(context).padding.top, + 0), color: Theme.of(context).colorScheme.surface, - child: Column( - mainAxisSize: MainAxisSize.min, + child: Stack( children: [ - if (!isVideo) - DetailsTabBar( - isVideo: isVideo, - ), - const SizedBox(height: 16), - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: isVideo - ? double.infinity - : ds.height - - ds.width * 9 / 16 - - 144 - - MediaQuery.of(context).padding.top, - ), + Positioned( + top: 72, + left: 0, + right: 0, + bottom: 0, child: StateHandler( onRetry: () {}, state: state, builder: (context, state) { if (state.selectedDetailsIndex == 0) { return SingleChildScrollView( - physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.symmetric(horizontal: 16), + padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -128,50 +125,57 @@ class StudioDetailsWidget extends StatelessWidget { if (state.selectedDetailsIndex == 1) { return ChangeNotifierProvider( create: (context) => CommentsState(), - child: Comments( - pageData: { - 'id': state.studio.id, - 'type': 'studio', - 'title': state.studio.title, - 'onCommentsChanged': state.onCommentsChanged, - 'isPage': false, - }, + child: SizedBox( + height: ds.height - + ds.width * 9 / 16 - + 172 - + MediaQuery.of(context).padding.top, + child: Comments( + pageData: { + 'id': state.studio.id, + 'type': 'studio', + 'title': state.studio.title, + 'onCommentsChanged': state.onCommentsChanged, + 'isPage': false, + }, + ), ), ); } - return SingleChildScrollView( - child: Column( - children: [ - if (state.studio.relatedContents.isEmpty) - for (var i = 0; i < 3; i++) - Padding( - padding: const EdgeInsets.only( - bottom: 8, - left: 16, - right: 16, - ), - child: MultitypeOverview.placeholder, - ), - for (var i = 0; - i < state.studio.relatedContents.length; - i++) + return Column( + children: [ + if (state.studio.relatedContents.isEmpty) + for (var i = 0; i < 3; i++) Padding( padding: const EdgeInsets.only( bottom: 8, left: 16, right: 16, ), - child: MultitypeOverview( - item: state.studio.relatedContents[i], - onMarkChanged: (id, value) {}, - ), + child: MultitypeOverview.placeholder, ), - ], - ), + for (var i = 0; + i < state.studio.relatedContents.length; + i++) + Padding( + padding: const EdgeInsets.only( + bottom: 8, + left: 16, + right: 16, + ), + child: MultitypeOverview( + item: state.studio.relatedContents[i], + onMarkChanged: (id, value) {}, + ), + ), + ], ); }, ), ), + DetailsTabBar( + isVideo: isVideo, + ), ], ), ); @@ -202,7 +206,7 @@ class _StudioPreview extends StatelessWidget { }) : super(key: key); String get _previewTitle { - if (studio.media.contains('iframe')) { + if (studio.iframe != null) { return 'ویدئو ${isNext ? 'بعدی' : 'قبلی'} '; } return 'پادکست ${isNext ? 'بعدی' : 'قبلی'} '; diff --git a/lib/views/home/widgets/audio/audio_player_widget.dart b/lib/views/home/widgets/audio/audio_player_widget.dart index 0b95eba..5012e47 100644 --- a/lib/views/home/widgets/audio/audio_player_widget.dart +++ b/lib/views/home/widgets/audio/audio_player_widget.dart @@ -129,7 +129,7 @@ class AudioPlayerWidget extends StatelessWidget { stream: MediaService.audioPlayer.playingStream, builder: (context, snapshot) { return _PlayPouseAnimatedIcon( - audioSource: podcast.media, + audioSource: podcast.link, id: podcast.id, ); }, diff --git a/lib/views/home/widgets/overview/podcast.dart b/lib/views/home/widgets/overview/podcast.dart index 94cd330..24ce673 100644 --- a/lib/views/home/widgets/overview/podcast.dart +++ b/lib/views/home/widgets/overview/podcast.dart @@ -83,7 +83,7 @@ class PodcastOverview extends StatelessWidget { const Spacer(), if (!kIsWeb) ...[ if (state.appState == AppState.idle || - !state.downloadQueue.contains(podcast.media)) + !state.downloadQueue.contains(podcast.link)) DidvanIconButton( gestureSize: 28, color: _isDownloaded @@ -97,11 +97,11 @@ class PodcastOverview extends StatelessWidget { : () => state.download( fileName: 'podcast-${podcast.id}.mp3', isVideo: false, - url: podcast.media!, + url: podcast.link!, ), ), if (state.appState == AppState.busy && - state.downloadQueue.contains(podcast.media)) + state.downloadQueue.contains(podcast.link)) const SizedBox( width: 18, height: 18, diff --git a/lib/views/widgets/didvan/bnb.dart b/lib/views/widgets/didvan/bnb.dart index 28c2d61..bcc6682 100644 --- a/lib/views/widgets/didvan/bnb.dart +++ b/lib/views/widgets/didvan/bnb.dart @@ -248,7 +248,7 @@ class _PlayerNavBar extends StatelessWidget { ); } MediaService.handleAudioPlayback( - audioSource: MediaService.currentPodcast!.media, + audioSource: MediaService.currentPodcast!.link, id: MediaService.currentPodcast!.id, isVoiceMessage: false, );