I am able to load the video initially but when I setState to change the youtube link on tap it doesn't work, don't know why. what is the approach to changing the video on button press?
I am using the Pod Player plugin.
Just like Load Video Button Functionality in this image
import 'package:flutter/material.dart';
import 'package:pod_player/pod_player.dart';
class VideoPlayer extends StatefulWidget {
const VideoPlayer({Key? key}) : super(key: key);
#override
State<VideoPlayer> createState() => _VideoPlayerState();
}
class _VideoPlayerState extends State<VideoPlayer> {
String YTLink = "https://youtu.be/A3ltMaM6noM";
late final PodPlayerController controller;
#override
void initState() {
controller = PodPlayerController(
playVideoFrom: PlayVideoFrom.youtube(YTLink),
)..initialise();
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView(
children: [
PodVideoPlayer(controller: controller),
OutlinedButton(
onPressed: () {
setState(() {
YTLink =
"https://www.youtube.com/watch?v=Q98aCklzCBE&ab_channel=DWDocumentary";
});
},
child: Text("Play Another Video")),
OutlinedButton(
onPressed: () {
setState(() {
YTLink =
"https://www.youtube.com/watch?v=AnYsa_c4GxU&ab_channel=FreeDocumentary";
});
},
child: Text("Play Another Video 2")),
],
)),
);
}
}
Instead of using setState, use controllers changeVideo method.
Add this to onPressed of Button:
//1
`controller.changeVideo(
playVideoFrom: PlayVideoFrom.youtube(
"https://www.youtube.com/watch?v=Q98aCklzCBE&ab_channel=DWDocumentary"));`
//2
`controller.changeVideo(
playVideoFrom: PlayVideoFrom.youtube(
"https://www.youtube.com/watch?v=AnYsa_c4GxU&ab_channel=FreeDocumentary"));`
Related
i have two screens A and B.In screen A iam calling a function periodically(i.e every 5 seconds).At the time of navigating to screen B i need to stop the function calling and when its back to screen A, the function call should be resumed.
Is there any way to do it?
Navigator doesn't expose the current route.
What you can do instead is use Navigator.popUntil(callback) as popUtil pass to the callback the current Route, which includes it's name and stuff.
final newRouteName = "/NewRoute";
bool isNewRouteSameAsCurrent = false;
Navigator.popUntil(context, (route) {
if (route.settings.name == newRouteName) {
isNewRouteSameAsCurrent = true;
}
return true;
});
if (!isNewRouteSameAsCurrent) {
Navigator.pushNamed(context, newRouteName);
}
Use This bool to check current screen and toggle your function .
From what i see is you can use the Timer class in the widget and manupulate based on your needs, I have created a sample example for you.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: PageOne()
);
}
}
class PageOne extends StatefulWidget {
const PageOne({Key? key}) : super(key: key);
#override
_PageOneState createState() => _PageOneState();
}
class _PageOneState extends State<PageOne> {
Timer? timer;
#override
void initState() {
// TODO: implement initState
super.initState();
timer = Timer.periodic(const Duration(seconds: 2), (timer) {
printMethod("init");
});
}
printMethod(String type){
print("This is the $type print statement ");
}
#override
void dispose() {
super.dispose();
timer?.cancel();
print("First Page timer cancelled");
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextButton(onPressed: () async {
timer?.cancel();
var result = await Navigator.push(context, MaterialPageRoute(builder: (context)=> const PageTwo() ));
if(result)
{
timer = Timer.periodic(const Duration(seconds: 2), (timer) {
printMethod("init");
});
}
}, child: const Text("go to next page"),),
),
);
}
}
class PageTwo extends StatefulWidget {
const PageTwo({Key? key}) : super(key: key);
#override
_PageTwoState createState() => _PageTwoState();
}
class _PageTwoState extends State<PageTwo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Page two"),),
body: Center(
child: TextButton(onPressed: () async {
Navigator.of(context).pop(true);
}, child: const Text("go to prev page"),),
),
);
}
}
Let me know if it works
You can simply use bool to handle this case as follows :
class _ScreenAState extends State<ScreenA> {
bool runPeriodicFun = true;
void periodicFun() {
if (runPeriodicFun) {
//write your periodic logic
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: () {
setState(() {
runPeriodicFun = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => ScreenB()))
.then((value) {
setState(() {
runPeriodicFun = true;
});
periodicFun();
});
},
child: Container()),
);
}
}
when you go to Screen B then runPeriodicFun set to false and coming back to Screen A runPeriodicFun set to true. So it will use periodicFun block only when runPeriodicFun is true.
You will receive callback in then block in the Navigator.push method.
what i did is that, in timer function i checked the current page is at top of stack by
ModalRoute.of(context)!.isCurrent
what it did is that it will check the page by context which we pass if the page is at top it will continue the timer, if it navigates to another page then the above code will return false.
In false, i just stop the timer.
if(ModalRoute.of(context)!.isCurrent){
//timer running
}else{
_timer?.cancel();
}
so if the page is same timer will perform otherwise it will stop the timer.
Now for resuming the timer, under the build in screen where you called i just called the function from where timer get activated.
Widget build(BuildContext context) {
//call timer function
return SafeArea()}
i think this might solve the problem. if anyone identify any problem please comment it.
I have problem with assest audio player package when I try to play two songs inside one page
both are playing !
The way I want when I press first button,first song play and when I press second button the first song stop and the second song start playing .
I used this code but it doesn't work
HomePage
import 'package:flutter/material.dart';
import 'package:mp3player/playpausebutton.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mp3 Player'),
),
body: Container(
color: Colors.white,
child: Column(
children: [
PlayPauseButton(
mp3name: 'song1',
),
PlayPauseButton(
mp3name: 'song2',
)
],
),
),
);
}
}
PlayPauseButton
class PlayPauseButton extends StatefulWidget {
PlayPauseButton({this.mp3name});
final String mp3name;
#override
_PlayPauseButtonState createState() => _PlayPauseButtonState();
}
class _PlayPauseButtonState extends State<PlayPauseButton> {
final assetsAudioPlayer = AssetsAudioPlayer();
bool ispresed = false;
#override
void dispose() {
// TODO: implement dispose
super.dispose();
assetsAudioPlayer.dispose();
}
#override
Widget build(BuildContext context) {
return FlatButton(
child: Icon(ispresed ? Icons.pause : Icons.play_arrow),
onPressed: () {
assetsAudioPlayer.open(Audio("assets/audios/${widget.mp3name}.mp3"));
setState(() {
if (ispresed == false) {
assetsAudioPlayer.play();
ispresed = true;
} else if (ispresed == false) {
assetsAudioPlayer.pause();
ispresed = false;
}
});
},
);
}
}
I used this package for playing audio
https://pub.dev/packages/assets_audio_player
and also is there any way to toggle button Icon when player is finish ?
My problem is solved by changing
final assetsAudioPlayer = AssetsAudioPlayer();
to
final assetsAudioPlayer = AssetsAudioPlayer.withId("0");
you can check if the player is done playing by adding listener to it.
assetsAudioPlayer.playlistAudioFinished.listen((event){if(event) {//carry out another action you want } });
the callback response is a bool type, return false when the audio start and return true when it finished
I am trying to create a background video splash screen for my app.
Currently, I am achieving a blank screen by running this code.
void main() => runApp(WalkThrough());
class WalkThrough extends StatefulWidget {
#override
_WalkThroughState createState() => _WalkThroughState();
}
class _WalkThroughState extends State<WalkThrough> {
VideoPlayerController _controller;
#override
void initState() {
super.initState();
// Pointing the video controller to our local asset.
_controller = VideoPlayerController.asset('assets/video.mp4')
..initialize().then((_) {
// Once the video has been loaded we play the video and set looping to true.
_controller.play();
_controller.setLooping(true);
_controller.setVolume(0.0);
_controller.play();
// Ensure the first frame is shown after the video is initialized.
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
I suspect the problem may be here and have based my research off this Full screen video background in Flutter on Login as I am trying to achieve a similar result.
SizedBox.expand(
child: FittedBox(
// If your background video doesn't look right, try changing the BoxFit property.
// BoxFit.fill created the look I was going for.
fit: BoxFit.fill,
child: SizedBox(
width: _controller.value.size?.width ?? 0,
height: _controller.value.size?.height ?? 0,
child: VideoPlayer(_controller),
),
),
),
I think the video player package has an issue to show video in the Ios simulator. I had the same issue and search for it and find out this issue in Github. until now this issue is open. I tested the video player on a real device and there were no problems.
Use this video player video_player plugin
& Save your mp4 file in assets/videos location
Try the below code
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
import 'HomePage.dart';
class SplashPage extends StatefulWidget {
SplashPage({Key key}) : super(key: key);
#override
State<StatefulWidget> createState() => _SplashPageState();
}
class _SplashPageState extends State<SplashPage> {
VideoPlayerController _controller;
bool _visible = false;
#override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
_controller = VideoPlayerController.asset("assets/video/splash_video.mp4");
_controller.initialize().then((_) {
_controller.setLooping(true);
Timer(Duration(milliseconds: 100), () {
setState(() {
_controller.play();
_visible = true;
});
});
});
Future.delayed(Duration(seconds: 4), () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => HomePage(param_homepage: 'Welcome Home')),
(e) => false);
});
}
#override
void dispose() {
super.dispose();
if (_controller != null) {
_controller.dispose();
_controller = null;
}
}
_getVideoBackground() {
return AnimatedOpacity(
opacity: _visible ? 1.0 : 0.0,
duration: Duration(milliseconds: 1000),
child: VideoPlayer(_controller),
);
}
_getBackgroundColor() {
return Container(color: Colors.transparent //.withAlpha(120),
);
}
_getContent() {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Stack(
children: <Widget>[
_getVideoBackground(),
],
),
),
);
}
}
I would like to use this plugin (https://pub.dev/packages/youtube_native_player) because it has minimal buttons, but if I push the back button it continuous playing in background. I can go back but the video starting again with the previous sound's in background etc.
I do not know how to reach it's controller. Can I get some help?
My code:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:uhu/common/widgets/base_stateless_widget.dart';
import 'package:youtube_native_player/android/constrant.dart';
import 'package:youtube_native_player/android/video_player_controller.dart';
import 'package:youtube_native_player/youtube_native_player.dart';
class YoutubeIosWidget extends StatefulWidget {
YoutubeIosWidget({Key key}) : super(key: key);
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<YoutubeIosWidget> {
String position = "Get Current Position";
String status = "Get Player Status";
String videoDuration = "Get Video Duration";
String _source = CommonThings.videoId;
bool isMute = false;
VideoPlayerController _controller;
#override
void initState() {
super.initState();
}
#override
void dispose() {
// This pauses video while navigating to next page.
// super.dispose();
}
#override
Widget build(BuildContext context) {
CommonThings.videoId = "";
return new WillPopScope(
onWillPop: () async => false,
child: new Scaffold(
backgroundColor: Colors.black.withOpacity(0.88),
appBar: AppBar(
backgroundColor: Colors.transparent,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () async {
setState(() {});
Navigator.pop(context);
})),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
YoutubeNativePlayer(
context: context,
source: _source,
quality: YoutubeQuality.HD,
aspectRatio: 16 / 9,
autoPlay: true,
loop: false,
reactToOrientationChange: true,
startFullScreen: true,
controlsActiveBackgroundOverlay: false,
controlsTimeOut: Duration(seconds: 1),
playerMode: YoutubePlayerMode.DEFAULT,
switchFullScreenOnLongPress: true,
callbackController: (controller) {
_controller = controller;
},
onError: (error) {
print(error);
},
onVideoEnded: () => Navigator.pop(context))
],
),
));
}
}
You need to uncomment your dispose code and also close (or dispose) your video controller:
void dispose() {
// This pauses video while navigating to next page.
super.dispose();
_controller.close(); // or _controller.dispose();
}
Sorry if the question isn't that straight forward I'm just starting out. Every play video example I see through flutter examples uses a floating action button in the same class as the video player. I want to add a video player instance to my home screen and experiment with different ways to play the video (tapping on different elements, etc. I can't seem to gain access to the instance to access the controller. I'm not sure how to actually create a video player instance and then access the video controller from another place.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoPlayerScreen extends StatefulWidget {
VideoPlayerScreen({Key key}) : super(key: key);
final VideoPlayerScreenState videoState = new VideoPlayerScreenState();
#override
VideoPlayerScreenState createState() => VideoPlayerScreenState();
}
class VideoPlayerScreenState extends State<VideoPlayerScreen> {
VideoPlayerController controller;
Future<void> initializeVideoPlayerFuture;
#override
void initState() {
// Create and store the VideoPlayerController. The VideoPlayerController
// offers several different constructors to play videos from assets, files,
// or the internet.
controller = VideoPlayerController.network('https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
);
// Initialize the controller and store the Future for later use
initializeVideoPlayerFuture = controller.initialize();
// Use the controller to loop the video
controller.setLooping(true);
super.initState();
}
#override
void dispose() {
// Ensure you dispose the VideoPlayerController to free up resources
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container(
// Use a FutureBuilder to display a loading spinner while you wait for the
// VideoPlayerController to finish initializing.
child: FutureBuilder(
future: initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the Aspect Ratio of the Video
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video
child: VideoPlayer(controller),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
//this is the button I'm calling from the app.dart file
Widget playPauseButton(VideoPlayerScreen videoPlayer){
return IconButton(
alignment: Alignment.center,
onPressed: (){
// Wrap the play or pause in a call to `setState`. This ensures the
// correct icon is shown
setState(() {
// If the video is playing, pause it.
if (videoPlayer.videoState.controller.value.isPlaying) {
videoPlayer.videoState.controller.pause();
} else {
// If the video is paused, play it
videoPlayer.videoState.controller.play();
}
});
},
icon: Icon(videoPlayer.videoState.controller.value.isPlaying ? Icons.pause: Icons.play_arrow),
);
}
you can create a class named VideoProvider and put a VideoPlayer widget inside there.
after that, all you need is create a parameter named controller and pass it to your VideoPlayer widget. controller should be a type of VideoPlayerController;
here is an example :
class MySpecificPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MySpecificPageState();
}
}
class _MySpecificPageState extends State<MySpecificPage> {
VideoPlayerController controller;
VoidCallback listener;
#override
void initState() {
listener = () => setState(() {});
videoHandler();
super.initState();
}
void videoHandler() {
if (controller == null) {
controller = VideoPlayerController.network('https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4')
..addListener(listener)
..setVolume(0.5)
..initialize();
} else {
if (controller.value.isPlaying) {
controller.pause();
} else {
controller.play();
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Videop Provider Example'),
),
body:Container(
child: Column(
children: <Widget>[
VideoProvider(controller),
RaisedButton(
child: Text('click here to play & puase the video'),
onPressed: () {
videoHandler();
},
)
],
),
),
);
}
}
class VideoProvider extends StatelessWidget {
final VideoPlayerController controller;
VideoProvider(this.controller);
#override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 16 / 9,
child: VideoPlayer(
controller
),
);
}
}