Track progress Flutter video player - flutter

Hi I'm using the flutter video player plugin, I have something similar like this [{phrase:"something", startAt: 1039}, {phrase:"other somthing", startAt: 26500}] is there a way to change in ui the phrase based on the start time while the video is playing.
I have try to use a timer with a duration of 100 ms but I retrieve no exact time from the Flutter video player plugin.

You probably want to take a look at stateful widgets as they allow you to do exactly this. In short, you can set phrase to be some variable and once the video starts you can call setState and change the variable. Flutter will automatically redraw the widget and the text will be updated.
To determine if the video player is playing you can add a listener to your video controller.
_controller = VideoPlayerController.network(
'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4',
)
..addListener(() {
final bool isPlaying = _controller.value.isPlaying;
if (isPlaying != _isPlaying) {
setState(() {
_isPlaying = isPlaying;
});
}
})
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {});
});

Related

How can I get the details of currently playing song in miniplayer?

I am working on a music player app in flutter.
I fetch the songs from devices using on_audio_query package and display them in listview. When I click on a song, i set the plylist of all songs and play the one thats clicked using just_audio package like this.
await player.setAudioSource(
ConcatenatingAudioSource(
useLazyPreparation: true,
shuffleOrder: DefaultShuffleOrder(),
children: allSongsList! // allSongsList is the list of
songs(on_audio_query)
.map((songModel) =>
AudioSource.uri(Uri.parse(songModel.data)))
.toList(),
),
initialIndex: index, // Listview Index
initialPosition: Duration.zero);
await item.player.play();
I want to show miniplayer at the bottom only when there is a song playing(paused),refresh the song descriptions,how do I get the song description(Artist/song)?
I will let you the implementation of the mini player widget for you, however, I will consider that I have a shouldMiniPlayerBeVisible, in the Scaffold of your page:
First, declare and initialize a shouldMiniPlayerBeVisible variable that will manage the show/hide of the mini player:
bool shouldMiniPlayerBeVisible = false;
and a currentAudio which will take the song and pass it in the mini player.
YourAudioModel currentAudio = YourAudioModel();
Here, I supposed that I have a simple YourAudioModel which will hold information about audio such as title, description, length, URL (or local) path ...
I recommend not setting it to null initially , you can initialize it with a placeholder YourAudioModel audio model that has some dummy data, or loading data information for example...
now in your Scaffold:
Scaffold(
floatingActionButton: Visibility(
visible: shouldMiniPlayerBeVisible,
child: shouldMiniPlayerBeVisible(songToPlay: currentAudio),
),
),
I will consider that you are using a StatefulWidget, but the steps are the same as you need just to get the idea of it to implement it in other state management solutions.
in the initState, you need to listen to the playerStateStream stream like this:
player.playerStateStream.listen((state) {
if (state.playing) {
shouldMiniPlayerBeVisible = true;
} else {
shouldMiniPlayerBeVisible = false;
}
setState(() {});
});
this basically will track if any audio is playing or not, then show the mini player based on it.
now before your run the await item.player.play();, set your currentAudio variable to the new audio which is running, you can do it with a function like this:
Future<void> playCurrentAudioANdShowItInMiniPlayer(YourAudioModel audio) async {
currentAudio = YourAudioModel;
await item.player.play();
}
now from your UI, for each item in ListView, you can just call the playCurrentAudioANdShowItInMiniPlayer method with its YourAudioModeland expect it to work fine.
from here, you should implement the actual mini player widget, and you will need also a custom Navigator widget so that mini player will be on the screen even if you navigated to other screens, well I faced this issue before and the miniplayer worked just really fine and good as I expected, I recommend you to use it.

i am actually making flappy bird as my first project in flutter. how can i add an asset audio in gesturedetector?

[here is the write and gesture detector code](https://i.stack.imgur.com/RmUfF.png)
I tried adding this
but it didnt work . i just want when i click on the music button it should play the background audio in assets and if click on no music it should stop the background music. but that state should be maintained after applying.
void initState(){
super.initState();
setAudio();
audioPlayer.onPlayerStateChanged.listen((state) {
setState(() {
isPlaying = state == PlayerState.PLAYING;
});
});

How to match scroll controller `animateTo()` scroll duration with the video playing duration

I am creating a small video editing app it uses Flutter for UI development. But now I had a problem developing the video timeline. I created the timeline by extracting thumbnail for each 1 second of the video and wrapping them in a Row and I wrapped the Row again with a SingleChildScrollView. Then I used ScrollController to automatic scroll when the video playing as follows.
void _scrollThumbnails() {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
if (_scrollController.hasClients) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
curve: Curves.linear,
duration: Duration(seconds: widget.videoEntity.videoDuration.inSeconds),
);
}
});
}
But it doesn't match perfectly with the video because sometimes video ends before the scroll ends. So how to solve this issue.

How to identify if the controls has gone or not in flutter chewie video player

I am working on a flutter app and using chewie videoplayer plugin.So when we started playing a video it shows controls at bottom and after few seconds it vanishes and when we move the mouse again it shows again. so is there any method to find when the controls are shown on screen and when its not shown.
actually i am giving close button on the video player. but it doesnt vanishes with those video player controls. it still stay on screen so to hide that close button along with video controls i need to get which process hides the control.
Please help me...
This process is inside the source code of chewie player. So if you need to customize and synchronise your own custom controls and options, either you have to explicitly fetch the source code and edit in that or you need to make your own controllers from scratch using video_player package as the core.
You need to customize the source code of the chewie player.
You can find MaterialControl class inside the source code of this package there is a function called _buildHitArea() just change notifier.hideStuff boolean according to your preference.
Widget _buildHitArea() {
final bool isFinished = _latestValue.position >= _latestValue.duration;
final bool showPlayButton = widget.showPlayButton && !_dragging && !notifier.hideStuff;
return GestureDetector(
onTap: () {
if (_latestValue.isPlaying) {
if (_displayTapped) {
setState(() {
notifier.hideStuff = false;
});
} else {
_cancelAndRestartTimer();
}
} else {
_playPause();
setState(() {
notifier.hideStuff = false;
});
}
},
child: CenterPlayButton(
backgroundColor: Colors.black54,
iconColor: Colors.white,
isFinished: isFinished,
isPlaying: controller.value.isPlaying,
show: showPlayButton,
onPressed: _playPause,
),
);
}

How to jump to frame with flutter video player?

Is it possible to jump to certain timestamp and display the frame without starting the video using flutter video_player?
I was able to change a frame only when I call play immediately after seekTo.
_videoPlayerController.seekTo(Duration(milliseconds: value));
_videoPlayerController.play();
I also tried
_videoPlayerController.seekTo(Duration(milliseconds: value));
_videoPlayerController.play();
_videoPlayerController.pause();
but it does not change displayed frame of video.
This answer probably comes a bit late, and is totally a hack
It shouldn't really be used, but it allowed me to have a similar behaviour
From what I could find, VideoPlayerController doesn't have any way to interact with the video regarding frames, only timestamps with the seekTo method you used. You just need to play and pause with a little delay in between actions and have it wrapped in an async function so that you can wait for the actions to complete, essentially this:
void moveOneFrameForward() async {
//Gets the current time point at where the video is at in a "Duration" type object
var currentTime = await _videoPlayerController.position;
//Seeks to the current time + an interval, in this case 100ms
await _videoPlayerController.seekTo(
Duration(milliseconds: currentTime!.inMilliseconds + 100),
);
//Plays the video so to render a frame
await _videoPlayerController.play();
//Delay so that the frame is rendered
await Future.delayed(Duration(milliseconds: 10));
//Video is paused to display the frame
await _videoPlayerController.pause();
}