I am building an app that is successfully displaying an MP4 video file onButtonClick. I want to pre-buffer or preload the video's URI (remote url) so that it doesn't delay the playing of the video once the button is clicked. I want it to click and play right away, so pre-loading or buffering on the app launch splash screen seems like a fitting solution. Only thing is I don't know how. I have tons of Android Books, but hardly any of them cover buffering at all or they only cover audio.
Can anyone let me know how to buffer the video on a previous activity?
Thanks.
Google released ExoPlayer which provides a higher level for media playing : http://developer.android.com/guide/topics/media/exoplayer.html
It supports different state such as buffering in background :
// 1. Instantiate the player.
player = ExoPlayer.Factory.newInstance(RENDERER_COUNT);
// 2. Construct renderers.
MediaCodecVideoTrackRenderer videoRenderer = …
MediaCodecAudioTrackRenderer audioRenderer = ...
// 3. Inject the renderers through prepare.
player.prepare(videoRenderer, audioRenderer);
I used it in my own project and it seems pretty efficient. Also Google made a Full Demo of the player : https://github.com/google/ExoPlayer/tree/master/demo/src/main/java/com/google/android/exoplayer/demo/full which is more powerfull than simple demo.
You can use the MediaPlayer for preparing the video, like this:
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(<implementation of MediaPlayer.OnPreparedListener>);
mediaPlayer.setDataSource(dataSource);
mediaPlayer.prepareAsync();
After the call prepareAsync() the mediaplayer will buffer your video.
The MediaPlayer.OnPreparedListener.onPrepared() will tell you if the mediaplayer is ready to play yet.
Just check the prepared flag and call mediaplayer.start() when you click your button "onButtonClick"
The native Android Browser doesn't buffer the media files (audio or video), so there is no way to do it on HTML5. As #bradenV2 said, you could copy the file to memory (you could use Phonegap if it is an App).
Related
Hopefully my request/question makes sense. im new to audio streaming and the Exoplayer API. as such I'm hoping some Exoplayer guru's can help me out !
what we'd like to do is :
start playing an MP3 track (using progressive download).
after "X" seconds (where "X" differs from song to song) we need to pause the above track and then play a different MP3 file (that contains an ad)
after the audio ad completes, resume playing the track from (1) above
what we are currently doing is this:
a) pause the MP3 track from (1) above <- uses "exoPlayer_1" instance
b) launch a NEW / have a second Exoplayer instance available, which is responsible for playing the ad <- uses "exoPlayer_2" instance
c) resume the MP3 track from (1) above once the ad had finished playing
Or is there a better way to do this using some of the many Exoplayer API's that appear to be available ?
We're using their Kotlin API's. I could post code here but its pretty much the boilerplate from the ExoPlayer code lab at this point.
Really appreciate any help/advice on this, thanks
Has anyone tried using ExoPlayer to achieve this?
I tried looking online with no success.
When I say gapless playback, I am referring to the problem of using the media player to play local videos back to back. After the first video is done playing, there is a noticeable delay of 1 second before the second video starts.
Hoping this question helps in understanding this issue further.
For reference please look at the following question:
Android: MediaPlayer gapless or seamless Video Playing
ExoPlayer 2, which is now officially released, seems to support gapless playback using the ConcatenatingMediaSource class. From its developer guide:
Transitions between sources are seamless. There is no requirement that the sources being concatenated are of the same format (e.g. it’s fine to concatenate a video file containing 480p H264 with one that contains 720p VP9). The sources may even be of different types (e.g. it’s fine to concatenate a video with an audio only stream).
And the example code:
MediaSource firstSource = new ExtractorMediaSource(firstVideoUri, ...);
MediaSource secondSource = new ExtractorMediaSource(secondVideoUri, ...);
// Plays the first video, then the second video.
ConcatenatingMediaSource concatenatedSource =
new ConcatenatingMediaSource(firstSource, secondSource);
EDIT: ExoPlayer 2 supports gapless playback, but as of the time of writing is still unreleased as a stable version.
You will most likely never be able to achieve perfect gapless playback of multiple tracks with ExoPlayer or Android Media Player. Neither have been written to support starting multiple tracks and I imagine it will stay out of scope for both of them.
You can achieve gapless playback by using 2 different player instances, once you have started and played the first, you can load the second and start playback once the first finishes. Using this method you could have a gapless solution, as long as you prepare the second video during playback of the first.
To take it further, you can also use 2 different surface textures for rendering the multiple videos, once the first video reaches the end you could fade out the texture and fade in the new one. Resulting in a nice seamless video effect.
Because of the nature of playing multiple videos at once you will most likely want to create your own timer for incrementing the time and deciding when to switch to the next video, rather than trying to use the callbacks from ExoPlayer or Android Media. This will allow you to keep track of the time in a more accurate fashion, without needing to keep talking to multiple video codecs.
I know this is not the answer you've been looking for, but it's the only reasonable answer. The sole way to ensure no gaps in playback is to download the entire file first and begin playback when it's done. Otherwise, in the event that you lose connectivity before the file is finished downloading, pausing is inescapable.
I just tried switching to ExoPlayer from the standard MediaPlayer implementation and the gap is the same if not worse. However I have used a very simple method of restarting the player when the status changes to ended. I don't know if there's a better proper way to do it, perhaps with 2 different ExoPlayers.
My question is about media player live streaming from the url in my application?
I'm trying to play live stream mp3 audio by media player.
The problem is that when i am using default URL as given in this link , then it works fine. But i changed the following mp3 link ,
then after playing 1 seconds it taking buffering and after completion its play the song, but i need that it plays the song with the buffering as well.
please help.
Thanks in advance.
It is not easy task to accomplish.
You can use this link https://code.google.com/p/mp3tunes/source/browse/
as reference app to develop your own progressive mediaplayer app.
From the above link you will get the whole architecture for your app.Song downloading and playing is happens at the same time.The architecture developed in the reference app is more robust and reusable.
Specially look at following classes
NanoHTTD.java
HttpServer.java
PlaybackService.java
PlaybackQueue.java
TrackDownloader.java
Thank You.
I want to stream an audio mp3 file and then play it through android media player plus I also want to cache this file, so that mediaplayer don't have to stream for recently played tracks.
I have tried using prepareAsync method but it doesn't give me access to buffer content, so I have decided to stream the audio file myself and then pass it to the media player for playing. I have achieved this by following this article here but this approach has a problem i.e. while transferring the file to media player it goes into error mode which causes my player to behave inconsistently.
When media player enters its error mode it doesn't come out of it automatically so I am forced to create a new media player and then re-provide it the downloaded file, this workaround causes the user to experience an undesired pause in the song playing.
So, does any one have improved an version of code given in above link? or do they know a better solution to this problem or is there is actually a library for streaming an audio file in android?
Thanks
The link you provided looks like a less than ideal solution (not to mention outdated). What you probably want is a local proxy server that gives you access to byte data before the MediaPlayer gets it. See my answer here for a little more explanation.
In my application I need to provide the user with a preview on a progressive download (video file).
In order to achieve this, I'm using VideoView component to show the content of the video (.mp4, .3gpp) which is being downloaded.
The problem is that I can't access remote media via http:// or rtsp:// protocol, so I'm forced to use VideoView.setVideoPath to play local copy of the video while downloading.
Unfortunately it seems like on Android devices that can't use StageFright framework (so OpenCore and some Tegra2-based devices in my experience), the VideoView can't handle progressive download correctly: it can play only the portion of the video recognized during the component initialization.
So to be clear: if the user press "play" when only 5% of the video has been downloaded, VideoView will show only that 5% of video, no matter if more video content ha been downloaded in the meantime.
In my experience this issue doesn't affect devices using StageFright framework (e.g.: Nexus One 2.2, Nexus One 2.3.4).
Can anyone point me to a possible solution ?
Thanks in advance
If you are trying to play .h264, You need to move the MOV atoms to the front of the file. These tell the codec the length of the movie among other things.
try qtfaststart
http://ffmpeg.zeranoe.com/builds/
VideoView is a ready to use class in Android Application Framework for video playback use case. It internally uses MediaPlayer class to achieve playback. MediaPlayer uses media frameworks available internally based on certain criteria like file format , origin of content etc.
So the limitation is from underlying framework and not VideoView. If you are still suspecting VideoView then write your own video player activity using media player. You will see the same result.
Also not all versions of Android (read as stagefright) support progressive download.
May be you can use DownloadManager class for downloading content from http server and provide the path to media player / video view for a quick preview.
Shash316