Flutter audio_service play audio in background when mobile screen is locked - flutter

I made a radio player app with the code below. Everything works fine when the mobile screen is turned on. But when i turn off my mobile screen the radio stops playing at about 5-8 minutes. I got some tips about using flutter audio_service. (https://pub.dev/packages/audio_service) But i am confused from where should i start. Should i recode again or i can modify this code. Somebody please help me. It would be a grace. Thankyou in advance.
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
class Radio1 extends StatefulWidget {
#override
_Radio1State createState() => _Radio1State();
}
class _Radio1State extends State<Radio1> {
AudioPlayer audioPlayer = AudioPlayer();
#override
void initState() {
super.initState();
AudioPlayer.logEnabled = true;
}
bool _isPlaying = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
//new
SizedBox(
height: 50,
),
//Icon(
// Icons.arrow_drop_down,
//size: 40,
//),
//new
Container(
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 50),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Color(0x46000000),
offset: Offset(0, 20),
spreadRadius: 0,
blurRadius: 30,
),
BoxShadow(
color: Color(0x11000000),
offset: Offset(0, 10),
spreadRadius: 0,
blurRadius: 30,
),
],
),
//new
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image(
image: AssetImage("assets/radiologo.jpg"),
width: MediaQuery.of(context).size.width * 0.7,
height: MediaQuery.of(context).size.width * 0.7,
fit: BoxFit.cover,
),
),
),
Text(
"sample text",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
),
Text(
"(sample text)",
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
),
/* Slider(
value: 10,
onChanged: (v) {},
max: 170,
min: 0,
activeColor: Color(0xFF5E35B1),
), */
Text(
"sample text.",
style: TextStyle(fontSize: 10, fontWeight: FontWeight.w500),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: _isPlaying == false
? Icon(Icons.play_circle_outline)
: Icon(Icons.pause_circle_outline),
iconSize: 60.0,
onPressed: () {
getAudio();
},
),
IconButton(
icon: Icon(Icons.stop),
iconSize: 40,
onPressed: () {
stopAudio();
},
),
//new line
],
),
],
),
),
),
);
}
void getAudio() async {
var url = "http://ia802708.us.archive.org/3/items/count_monte_cristo_0711_librivox/count_of_monte_cristo_001_dumas.mp3";
if (_isPlaying) {
var res = await audioPlayer.pause();
if (res == 1) {
setState(() {
_isPlaying = false;
});
}
} else {
var res = await audioPlayer.play(url);
if (res == 1) {
setState(() {
_isPlaying = true;
});
}
}
}
void stopAudio() async {
int res = await audioPlayer.stop();
if (res == 1) {
setState(() {
_isPlaying = false;
});
}
}
void releaseAUdio() async {
await audioPlayer.stop();
await audioPlayer.release();
}
#override
void dispose() {
super.dispose();
releaseAUdio();
}
}

So as you use the audioplayers package, you'll need to implement the audio_service one to achieve what you want (playing audio in background). Indeed, the audioplayers package is only responsible for playing audio files, and does not handle the background behaviours.
The audio_service is designed to be the only source of truth in your application. So you'll need to re-architecture your code to fit.
But don't delete your code, you might not need many changes in it for the audio.
The package is cut in multiple parts. For example, one for the background tasks, one for the UI to tell the background tasks what you want to do (play, pause, seekTo, ...), so the only changes you might need to do in your code will be to call this part, called AudioService (check the API reference for more informations: https://pub.dev/documentation/audio_service/latest/audio_service/AudioService-class.html).
Once you did that, of course you'll have to implement your background task to achieve your needs.
In summary:
Your code is good, but does not handle the background behaviours.
You may need to implement the audio_service package (or a similar one) to handle the background behaviours.
Please take a look at the audio_session package too to handle the interactions between your app and the different audio interactions on the phone. (For example, handle the notifications received and decrease the volume of your app in consequence).
Hope this answer is helpful for you, good luck :)

Related

'(callback function) can`t be accessed in an initializer' Error

I am studying flutter while making a pomodoro app.
After setting this app to 25 minutes, press the middle button to decrease the time by seconds and press the button again to pause.
I am getting the following error while configuring the app using the Timer class.
The Timer class takes a repeating period and a callback function as arguments.
However, the 'tickDown' function receives the Timer class as an argument, but I don't know why the error pops up.
Below is the code I wrote. I'd like to hear your thoughts on what the problem is.
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
var totalSeconds = 1500;
Timer _timer = Timer.periodic(Duration(seconds: 1), tickDown);
bool isRunning = false;
void playTimer() {
setState(() {
isRunning = true;
_timer;
});
}
void pause() {
_timer.cancel();
setState(() {
isRunning = false;
});
}
void tickDown(Timer _timer) {
setState(() {
totalSeconds -= 1;
});
}
String showRemainTime() {
var hour = (totalSeconds ~/ 60).toString();
var minute = (totalSeconds % 60).toString();
String time;
minute.length == 1 ? time = '$hour : 0$minute' : time = '$hour : $minute';
return time;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: Column(
children: [
Flexible(
flex: 3,
fit: FlexFit.tight,
child: Container(
alignment: const Alignment(0, 0),
child: Text(
showRemainTime(),
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).cardColor,
fontSize: 80,
fontWeight: FontWeight.w700,
),
),
),
),
Flexible(
flex: 4,
fit: FlexFit.tight,
child: Container(
alignment: const Alignment(0, -0.5),
child: IconButton(
iconSize: 100,
padding: EdgeInsets.zero,
onPressed: isRunning == true ? pause : playTimer,
icon: Icon(
isRunning == true
? Icons.pause_circle_outline_rounded
: Icons.play_circle_outlined,
color: Theme.of(context).cardColor,
),
),
),
),
Flexible(
flex: 2,
fit: FlexFit.tight,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
color: Theme.of(context).cardColor,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Pomodoro',
style: TextStyle(
fontSize: 23,
color: Theme.of(context).textTheme.headline1!.color,
fontWeight: FontWeight.w700,
),
),
Text(
'0',
style: TextStyle(
fontSize: 52,
color: Theme.of(context).textTheme.headline1!.color,
),
),
],
),
],
),
),
),
],
),
);
}
}
I also searched the flutter official documentation, but I couldn't find anything suitable for my situation. I want to fix this error with minimal modifications to my current code.
tickDown is a method of _HomeScreenState. Object methods cannot be accessed in initializers, because the object has not been fully constructed yet. This includes object properties with assignment definitions (like what you have) as well as initializers specified in constructors.
There are two ways you can overcome this.
Change your declaration of _timer to be late:
late var _timer = Timer.periodic(Duration(seconds: 1), tickDown);
However, for your particular situation, I don't recommend this approach.
Instantiate the timer later. This would look like
Timer? _timer;
void playTimer() {
setState(() {
_timer = Timer.periodic(Duration(seconds: 1), tickDown);
isRunning = true;
});
}
Note: To prevent issues, be sure to cancel the timer in the State's dispose() method.

Toggle switch animation not working in flutter

`I am trying to implement a toggle switch in which when I toggle the switch I display two different things but I'm getting an error while I use setstate with my logic or something like that if I remove the setstate from my code the animation starts working again but the logic does not work and I don't get two different outcomes when i toggle between the switch
the code is :
import 'package:flutter/material.dart';
import 'package:sadapay_clone/screens/homepage.dart';
import 'package:sadapay_clone/widgets/physical_card_item.dart';
import 'package:sadapay_clone/widgets/virtual_card_item.dart';
import 'package:toggle_switch/toggle_switch.dart';
class CardScreen extends StatefulWidget {
const CardScreen({super.key});
#override
State<CardScreen> createState() => _CardScreenState();
}
class _CardScreenState extends State<CardScreen>{
// AnimationController _controller;
bool toggle = false;
// #override
// void initState() {
// _controller = AnimationController(vsync: this);
// super.initState();
// }
// void toggleSwitch(int index) {
// if (index == 0) {
// setState(() {
// toggle = true;
// });
// } else if (index == 1) {
// setState(() {
// toggle = false;
// });
// }
// }
void toggleSwitch(int index) {
if (index == 0) {
setState(() {
toggle = true;
});
} else if (index == 1) {
setState(() {
toggle = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
const SizedBox(height: 75),
SizedBox(
width: double.infinity,
child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Navigator.pop(
context,
MaterialPageRoute(
builder: (context) => const MyHomePage(),
),
);
},
icon: const Icon(Icons.arrow_back_ios),
),
Container(
width: 295,
alignment: Alignment.center,
child: const Text(
'My Cards',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
),
),
],
),
),
const SizedBox(
height: 20,
),
Container(
alignment: Alignment.center,
height: 40,
width: 365,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.grey[300],
),
child: ToggleSwitch(
minHeight: 30,
minWidth: 180.0,
cornerRadius: 20.0,
activeBgColors: const [
[Colors.white],
[Colors.white]
],
activeFgColor: Colors.black,
inactiveBgColor: Colors.grey[300],
inactiveFgColor: Colors.black54,
initialLabelIndex: 0,
totalSwitches: 2,
labels: const ['Virtual', 'Physical'],
radiusStyle: true,
onToggle: (index) {
toggleSwitch(index!);
},
// onToggle: (index) {
// setState(() {
// toggle = index == 0;
// });
// },
),
),
toggle ? VirtualCard() : PhysicalCard(),
],
),
);
}
}
I tried using setstate logic inside the function rather than using it inside the onchanged property but still, the logic was working I was seeing two different outcomes when I pressed the switch but the animation was not working`
The issue is, while we are calling setState, the build method is trigger and setting initialLabelIndex to 0 again, you can do a check here,
class _CardScreenState extends State<CardScreen> {
bool toggle = false;
void toggleSwitch(int index) {
if (index == 0) {
setState(() {
toggle = true;
});
} else if (index == 1) {
setState(() {
toggle = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
alignment: Alignment.center,
height: 40,
width: 365,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.grey[300],
),
child: ToggleSwitch(
minHeight: 30,
minWidth: 180.0,
cornerRadius: 20.0,
activeBgColors: const [
[Colors.white],
[Colors.white]
],
activeFgColor: Colors.black,
inactiveBgColor: Colors.grey[300],
inactiveFgColor: Colors.black54,
initialLabelIndex: toggle ? 0 : 1,
totalSwitches: 2,
labels: ['Virtual', 'Physical'],
radiusStyle: true,
onToggle: (index) {
toggleSwitch(index!);
},
),
),
toggle ? Text("VirtualCard") : Text("PhysicalCard"),
],
),
);
}
}

How to properly play audio file using just_audio - flutter

Am working on a music app were am suppose to stream audio and also play my locally stored files.
Am using flutter and am not good on it, Actually am learning.
What i wanted is to be helped on how i can play a file properly, The intention is to play a file once provided to the player path. bellow is my code.
import 'package:myApp/shared/MusicProgressIndicator.dart';
import 'package:myApp/just_audio.dart';
import 'package:myApp/app.dart';
class SingleSongScreen extends StatefulWidget {
static const String id = "SingleSongScreen";
static var song = {};
SingleSongScreen({Key key}) : super(key: key);
#override
_SingleSongScreenState createState() => _SingleSongScreenState();
}
class _SingleSongScreenState extends State<SingleSongScreen> with TickerProviderStateMixin {
Duration currentDuration = Duration(milliseconds: 1000);
bool showRemaining = false;
AnimationController controller;
#override
void initState() {
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: true);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final player = AudioPlayer();
var song = SingleSongScreen.song;
var songPath = app.base+"play.php?file="+song['song'];
print(song);
print(songPath);
player.stop();
player.setUrl(songPath).then((play){
player.play();
print("Playing now");
});
return Window(
backgroundColor: backgroundColor,
header: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconicButton(
icon: backIcon,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 40,
onClicked: () {
goBack(context);
},
),
Favicon(onClicked: () {
goto(page: MainScreen.id, context: context);
}),
],
),
),
body: [
VerticalSpacer(
h: 20,
),
Container(
height: 250,
child: Carousel(
boxFit: BoxFit.contain,
autoplay: carouselAutoPlay,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 1000),
dotSize: 6.0,
dotIncreasedColor: Color(0xFF33A3FF),
dotBgColor: Colors.transparent,
dotPosition: DotPosition.bottomCenter,
dotVerticalPadding: 10.0,
showIndicator: true,
indicatorBgPadding: 7.0,
images: images(),
),
)
],
footer: Container(
child: Column(
children: [
Container(
child: Marquee(
child: Label(
song['title'],
bold: true,
),
),
),
Container(
child: Marquee(
child: Label(
song['artist'],
bold: true,
color: Colors.grey,
),
),
),
// ACTION ICONS SECTION
VerticalSpacer(
h: 25,
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
VerticalIconicButton(
icon: FontAwesomeIcons.fileDownload,
label: "Download",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
onClicked: (){
var downloadURL = songPath.replaceAll("play.php", "download.php");
app app2 = new app();
toast("Downloading a file "+song['song']);
app2.fetchServer({'method':'download','file':song['song']}).then((fileInfo){
if(fileInfo['status']=="success"){
toast("Download complete "+song['song']);
app2.saveDownload(song['song'],song['artist'],fileInfo['file']);
}else{
toast("There was an error while downloading a file");
}
print("downloaded file is");
print(fileInfo);
});
},
),
VerticalIconicButton(
icon: Icons.favorite_border_outlined,
label: "Favourite",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
),
VerticalIconicButton(
icon: FontAwesomeIcons.readme,
label: "Lyrics",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
onClicked: () {
goto(page: LyricsScreen.id, context: context, args: lyric);
},
),
],
),
),
// SONG PLAY PROGRESS INDICATOR
VerticalSpacer(),
MusicProgressIndicator(
progress: currentDuration,
buffered: Duration(milliseconds: 2000),
total: Duration(milliseconds: 5000),
showTotalRemainingTime: showRemaining,
onSeek: (duration) {
setState(() {
currentDuration = duration;
showRemaining = !showRemaining;
});
// _player.seek(duration);
},
),
// MUSIC PLAY CONTROLLER ACTION BUTTON
VerticalSpacer(
h: 20,
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconicButton(
icon: Icons.repeat_one,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 50,
),
Container(
child: Row(
children: [
Container(
child: Center(
child: IconicButton(
icon: Icons.skip_previous_rounded,
iconColor: Colors.white,
transparent: true,
circledIcon: false,
size: 50,
),
),
),
SizedBox(width: 15),
IconicButton(
icon: Icons.pause,
iconColor: Colors.grey,
iconCircleColor: Colors.blue,
size: 50,
onClicked: (){
toast("Playing file");
player.stop();
player.setUrl(songPath).then((play){
player.play();
print("Playing now");
});
},
),
SizedBox(
width: 15,
),
Container(
child: Center(
child: IconicButton(
icon: Icons.skip_next_rounded,
iconColor: Colors.white,
transparent: true,
circledIcon: false,
size: 50,
),
),
),
],
),
),
IconicButton(
icon: Icons.queue_music_outlined,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 50,
onClicked: () {
goto(page: AllSongsScreen.id, context: context);
},
),
],
),
),
// BOTTTOM SPACE
VerticalSpacer(
h: 30,
),
],
),
),
);
}
void toast(String message){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(message.toString()),
duration: const Duration(seconds: 1),
action: SnackBarAction(
label: 'OK',
onPressed: () { },
),
)
);
}
}
The code which i have used to play sound, is producing
Annoying sound, something a double sounds or waves crossing
It's allowing playing of multiple sounds.
Note: I purchased the template.
Thanks, Please help.
You have called the setState() method in the addListener of controller and directly called the player.stop() and player.play() methods inside the widget build.
Before calling the stop or play methods, check whether the player is not null and is not playing
if(player.playing){
}
And you should not initialize your player inside the widget build. It is not advisable.
For avoid playing multiple audios simultaneously, maybe you need think about making the AudioPlayer a SINGLETON. The code above show me that every time you enter that page, there will be a new AudioPlayer created associate with and you are not dispose it on dispose(). Here's some code I wrote for my flutter podcast open source project.
a podcast case using just audio package

The radio starts. But it doesn't stop. It doesn't stop when I switch pages in the project

I want the radio to stop when switching between pages. It works the first time I press the stop and start button, but when I press it again when I want to stop it does not stop. The radio is always on and never turns off. When I close the app completely, the radio stops. I want to do both stop and resume operation on the same button, and I want it to stop when I switch between pages. how can i solve?
code here:
import 'package:flutter/material.dart';
import 'package:flutter_radio/flutter_radio.dart';
class RadioSayfasi extends StatefulWidget {
#override
_RadioSayfasiState createState() => _RadioSayfasiState();
}
class _RadioSayfasiState extends State<RadioSayfasi> {
String url= "https://player.web.tr/listen/d695bfdfb2710f7c53feb05550da66ef";
bool isPlaying= false;
bool isVisible= true;
#override
void initState() {
// TODO: implement initState
super.initState();
audioStart();
}
Future <void> audioStart() async {
await FlutterRadio.audioStart();
print("Radio Başladı");
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'IndieXL Online Radio',
debugShowCheckedModeBanner: false,
home: new Scaffold(
appBar: new AppBar(
title: const Text('FM Radio'),
backgroundColor: Colors.blueGrey.shade900,
centerTitle: true,
),
body: Container(
color: Colors.blueGrey.shade900,
child: new Column(
children: <Widget>[
Expanded(
flex: 7,
child: Icon(
Icons.radio, size: 250,
color: Colors.white,
),
),
Expanded(
flex: 2,
child: Padding(
padding: const EdgeInsets.only(right: 40),
child: Align(
alignment: FractionalOffset.center,
child: IconButton(icon: isPlaying? Icon(
Icons.pause_circle_outline,
size: 80,
color: Colors.white,
)
: Icon(
Icons.play_circle_outline,
color: Colors.white,
size: 80,
),
onPressed: (){
setState(() {
FlutterRadio.play(url: url);
isPlaying = !isPlaying;
isVisible = !isVisible;
print("tıkladı");
});
},
),
),
),
),
SizedBox(height: 50,)
],
),
),
));
}
}
I'm guessing the library you mention, https://github.com/thyagoluciano/flutter_radio
To stop radio stream when leaving the screen just override the dispose method
https://github.com/thyagoluciano/flutter_radio/blob/master/lib/flutter_radio.dart#L67
#action
dispose() async {
await FlutterRadio.stop();
}
To start or pause radio stream
https://github.com/thyagoluciano/flutter_radio/blob/master/lib/flutter_radio.dart#L22
onPressed: (){
setState(() {
//FlutterRadio.play(url: url);
FlutterRadio.playOrPause(url: url);
isPlaying = !isPlaying;
isVisible = !isVisible;
print("tıkladı");
});
},

Video freezes when Admob's ad load Flutter

Hy there everyone. I'm new to Flutter. I want to implement Admob ads in my app. Basically my app is about live streaming of News.
Whenever the ads load the audio works fine but there is a lag in video.
Can anyone help me with this??
Hy there everyone. I'm new to Flutter. I want to implement Admob ads in my app. Basically my app is about live streaming of News.
Whenever the ads load the audio works fine but there is a lag in video.
Can anyone help me with this??
Hy there everyone. I'm new to Flutter. I want to implement Admob ads in my app. Basically my app is about live streaming of News.
Whenever the ads load the audio works fine but there is a lag in video.
Can anyone help me with this??
import 'package:better_player/better_player.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
class StreamPlayer extends StatefulWidget {
final String channelURL;
final String channelName;
final String channelImage;
StreamPlayer(
{#required this.channelURL,
#required this.channelName,
#required this.channelImage});
#override
_StreamPlayerState createState() => _StreamPlayerState();
}
class _StreamPlayerState extends State<StreamPlayer> {
BetterPlayerController _controller;
BannerAd _bannerAd;
bool _isBannerAdReady = false;
#override
void initState() {
super.initState();
playerConfig();
getBanner();
}
playerConfig() {
BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network, widget.channelURL,
liveStream: true);
_controller = BetterPlayerController(
BetterPlayerConfiguration(
aspectRatio: 16 / 9,
autoDetectFullscreenDeviceOrientation: true,
autoPlay: true,
),
betterPlayerDataSource: betterPlayerDataSource);
}
getBanner() {
_bannerAd = BannerAd(
adUnitId: 'ca-app-pub-3940256099942544/6300978111', //Ad for Testing
request: AdRequest(),
size: AdSize.banner,
listener: AdListener(
onAdLoaded: (ad) {
setState(() {
_isBannerAdReady = true;
});
},
onAdFailedToLoad: (ad, err) {
print('Failed to load a banner ad: ${err.message}');
_isBannerAdReady = false;
ad.dispose();
},
),
);
return _bannerAd.load();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.transparent,
elevation: 0,
title: Container(
width: 200,
height: 45,
decoration: BoxDecoration(
color: Colors.blueAccent.withOpacity(0.3),
borderRadius: BorderRadius.all(Radius.circular(30))),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CachedNetworkImage(
imageUrl: widget.channelImage,
width: 25,
height: 25,
fit: BoxFit.contain,
placeholder: (context, url) => Icon(
Icons.image,
size: 25,
),
errorWidget: (context, url, error) => Icon(
Icons.image,
size: 50,
)),
SizedBox(
width: 15,
),
Text(widget.channelName,
style: GoogleFonts.teko(
color: Theme.of(context).primaryColor == Colors.blue
? Colors.black54
: Colors.grey[50],
fontSize: 22,
fontWeight: FontWeight.w600,
)),
SizedBox(
width: 5,
),
],
),
)),
body: Container(
child: Column(
children: [
Center(
child: BetterPlayer(
controller: _controller,
),
),
_isBannerAdReady
? Container(
height: 100,
child: AdWidget(ad: _bannerAd),
)
: Container(),
],
),
),
);
}
}
I know its too late. Just posting here to give refernce to others.
As I have wasted lots of hours due to it.
I was also facing the same issue when I was using video player with google_mobile_ads ad library
So I just switch to native_admob_flutter ad library on video page.
And it is working fine.
Hope this will save some hours of others.