I'm creating a mobile application where users will select the video from the list and play. So I have built two widgets in a flutter, one for displaying a video list from a certain URL and the other one for playing a video when the user clicks the video from the list. I'm stacking on the way of dynamic picking URL from the list widget, I have tried to setState in the BuildContext method but does not seem to work. I have tried to initialize the video player inside a build method but does not work instead I get "(HTTPLog)-Static: isSBSettingEnabled false" and continue looping without ending I'm looking for anyways of getting these variables I sent through the "Navigator pushNamed" method from the video list page before the player initialized. or anything else which can help
I saw this answer 'https://stackoverflow.com/questions/56262655/flutter-get-passed-arguments-from-navigator-in-widgets-states-initstate' but I could not understand since I'm new to a flutter, i decided to ask again my be I can get a good answer
Thanks in advance!
I use the video_player flutter package and below are my code:
**video_players**
class PlayerWidget extends StatefulWidget {
const PlayerWidget({Key? key}) : super(key: key);
@override
_PlayerWidgetState createState() => _PlayerWidgetState();
}
class _PlayerWidgetState extends State<PlayerWidget> {
late VideoPlayerController _controller;
dynamic videoData={};
String vidUrl='https://videos.pond5.com/sunset-woman-running-ocean-reflection-footage-027692108_main_xxl.mp4';
Duration? _duration;
Duration? _position;
@override
void initState() {
super.initState();
//change screen orientation method
setScreenOrientations();
}
//orientations monitor
Future setScreenOrientations() async{
//change the screen orientation
await SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeRight,DeviceOrientation.landscapeLeft,]);
//remove status bar when on landscape mode
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
// The following line will enable the Android and iOS wakelock.
await Wakelock.enable();
}
Future removeOrientation() async{
await SystemChrome.setPreferredOrientations(DeviceOrientation.values);
//setback status bar
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom,SystemUiOverlay.top]);
//let screen sleep if there is no activities
Wakelock.disable();
}
//video progress bar
Widget buildIndicator() => Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
VideoProgressIndicator(
_controller,
allowScrubbing: true,
colors: const VideoProgressColors(
playedColor: Color(0xfff49043),
bufferedColor: Colors.grey,
backgroundColor: Colors.white30,
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Expanded(child: Text('${_printDuration(_position)} / ${_printDuration(_duration)}',style: const TextStyle(color: Colors.white),),),
Expanded(child: Align(
alignment: Alignment.center,
child: GestureDetector(
onTap: (){},
child: RichText(text: TextSpan(children: [const WidgetSpan(child: Icon(Icons.speed_outlined,color: Colors.white, size: 16),),TextSpan(text: " Speed (${_controller.value.playbackSpeed})",style: const TextStyle(fontSize: 14)),],),),
),
),),
Expanded(child: Align(
alignment: Alignment.center,
child: GestureDetector(
onTap: (){Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=> const Home()));},
child: RichText(text: const TextSpan(children: [WidgetSpan(child: Icon(Icons.video_library,color: Colors.white, size: 14),),TextSpan(text: " View Video",style: TextStyle(fontSize: 14)),],),),
),
),),
],
),
)
],
),
);
//convert time to the human readable format
String _printDuration(duration) {
if(duration==null){ return '00:00'; }
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
if(_duration?.inHours == 00){return "$twoDigitMinutes:$twoDigitSeconds";}
else{return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";}
}
@override
void dispose() {super.dispose();_controller.dispose();removeOrientation();}
@override
Widget build(BuildContext context) {
//get all value sent from the video widget route and hold them
videoData = ModalRoute.of(context)!.settings.arguments;
setState((){ vidUrl = videoData['videoUrl'];});
_controller = VideoPlayerController.network("${videoData['videoUrl']}")
..addListener(() {
Timer.run(() {setState((){ _position = _controller.value.position;}); });
setState(() {_duration = _controller.value.duration;});
})
..initialize()
.then((_) {});
//play pause state listener to toggle the button
Widget playPauseBtn() => _controller.value.isPlaying ? Container(alignment: Alignment.center,color: Colors.black26, child: const Icon(Icons.pause, color: Colors.white, size: 80),)
: Container(alignment: Alignment.center,color: Colors.black26, child: const Icon(Icons.play_arrow, color: Colors.white, size: 80),);
//overlay on the video player
videoOverlay(){
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {setState(() {_controller.value.isPlaying ? _controller.pause() : _controller.play();});},
child: Stack(children: <Widget>[playPauseBtn(),Positioned(bottom: 0,left: 0,right: 0,child: buildIndicator(),),],
),
);
}
//video player stack
Widget videoStack() => Stack(fit: StackFit.expand,children:[ AspectRatio(aspectRatio: _controller.value.aspectRatio,child: VideoPlayer(_controller),),]);
//complete player
Widget completePlayer() => Stack(children: <Widget>[videoStack(),Positioned.fill(child: videoOverlay()),],);
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: Text(videoData['videoName']),
centerTitle: true,
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
onPressed: () async {await SystemChrome.setPreferredOrientations(DeviceOrientation.values);Navigator.pop(context);},
icon: const Icon(Icons.arrow_back_ios_outlined),
),
),
backgroundColor: const Color(0xff121212),
body: _controller.value.isInitialized ? Container(alignment: Alignment.topCenter, child: completePlayer()) : const Center(child: CircularProgressIndicator(),),
);
}
}
Use Navigator.push
instead.
Follow these steps:
1. Add videoData
to the parameters of your widget and use widget.videoData
to read in initState
class PlayerWidget extends StatefulWidget {
final Map<String, dynamic> videoData;
const PlayerWidget({Key? key, required this.videoData}) : super(key: key);
@override
_PlayerWidgetState createState() => _PlayerWidgetState();
}
class _PlayerWidgetState extends State<PlayerWidget> {
late VideoPlayerController _controller;
dynamic videoData={};
String vidUrl='https://videos.pond5.com/sunset-woman-running-ocean-reflection-footage-027692108_main_xxl.mp4';
Duration? _duration;
Duration? _position;
@override
void initState() {
super.initState();
//change screen orientation method
videoData = widget.videoData;
setState((){});
setScreenOrientations();
}
2. Use Navigator.push
to navigate.
Navigator.push(context, MaterialPageRoute(builder: (_) => PlayerWidget(videoData: {'videoName': videoName,'videoUrl':videoUrl,'posterUrl':posterUrl}));
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments