Android MediaPlayer takes long time to prepare and buffer - java

My application takes a long time to prepare and buffer an audio stream. I have read this question Why does it take so long for Android's MediaPlayer to prepare some live streams for playback?, however it just says people have experienced this issue, it does not state how to improve the problem.
I am experiencing this in all versions of Android, tested from 2.2 - 4.1.2.
The streams are in a suitable bit-rate for mobile and 3G connection. The same stream takes less than a second to start buffering in the equivalent iOS app.
Is there a way to specify the amount of time that should be buffered? I know that the Tune In radio application offers this feature ( https://play.google.com/store/apps/details?id=tunein.player ).
Thanks.
Edit: I've tested again and found that it only happens on devices running Gingerbread and above (>=2.3). I know that Android changed the underlying framework from OpenCore to StageFright. So how can I optimise the media framework? It just seems wrong that the old HTC Wildfire can prepare, stream and play, literally 10x faster than the brand new HTC One X and Nexus 7.

I have struggled with this question for months. Finally i found the solution.
The real problem is in the implementation of the MediaPlayer class. Particularly with the way MediaPlayer buffers the data. This is why the solution is to create your own buffering, save it to a temp file and feed that to MediaPlayer.
This tutorial and source code explain exactly how. http://androidstreamingtut.blogspot.nl/2012/08/custom-progressive-audio-streaming-with.html
By adapting this code, it is easy to create a much better streaming player.
Google Developers really screwed up here.
EDIT : This answer is rather old. Nowdays i would recommend not using MediaPlayer and use ExoPlayer instead. It is extendable, stable and can play many different types of media. You can find it here: https://github.com/google/ExoPlayer/

There really isn't much you can do since the Android MediaPlayer class doesn't provide access to lower level settings such as buffer size. The only alternative would be to make your own player using AudioTrack and a library like FFmpeg to do the decoding.

The one thing I'd recommend is to play around with encoding. For instance, for MP4s, ensure that the MOOV Atom is located at the beginning of the file (there are enough questions on S/O regarding how to do this with ffmpeg, etc). With MP3s, you can look at different codecs or bitrates for instance.
You can, for instance, try a number of audio files you find online, and if you see one that doesn't take a long time to buffer, try to encode your files in the same way.

Related

mediaRecoder.reset() while recording a video CAMERA2 API

Can we reset all the values that hold in mediaRecorder while recording video?
I've tried just using mediaRecorder.reset() while recording video. But it won't work. I don't know is it possible or not. If it is possible please any references will appreciate.
I've read this and also google developers, mediaRecorder in developers. But any of references didn't mention my issue.
EDIT :
What I want is while recording a video set mediaRecorder.reset() and mediaRecorder.start(). The problem occurs when I'm doing this. I need to chunk of video clips while recording the same video. Need those process in parallel. While I'm trying to stop and restart the camera capturing methods it will miss many frames. Bcoz handling camera is somewhat cost for the processor. I tried this and it occurs some errors that telling session configuration failed. Now I'm stuck in here. Need help!
Thank you for your valuable time.
Edit in response to clarifications:
Ok, so you want to split the video file into multiple separate files.
You'll need to use the lower-level APIs (MediaCodec, MediaMuxer) to implement this yourself; the higher-level MediaRecorder does not support this without losing frames.
Original:
So you're trying to pause the video recording temporarily.
Unfortunately, there's no support for this before API level 24, which added MediaRecorder.pause(). You can't call MediaRecorder.reset() mid-video and have it work.
All you can really do is to record the full video and then post-process it to crop sections you don't want.

Two instances of Android mediaplayer cause odd issues

I was hoping someone can help me understand an issue I am seeing with the Mediaplayer class.
I am creating a music app that needs to play two music files at the same time. In one of the use case scenarios I want to be able to play an MP3 track and then initiate another MP3 to start playing at a differnt volume over the top of the first.
I have found that the Android mediaplayer class offers this functionality and have created a test application to do this by simply creating two instances of mediaplayer.
For example...
MediaPlayer mMediaPlayer1,mMediaPlayer2;
mMediaPlayer1 = new MediaPlayer();
mMediaPlayer2= new MediaPlayer();
The problem I am having is that in the emulator it works fine and on most devices I try it works fine but on a few test devices I get odd results when I try to start the second mediaplayer/track.
What happens is that the volume of either the second or the first audio track suddenly reduces to nothing. I can see that the mediaplayer is still "playing" as I have several progress bars setup to track its progress but you can't hear anything.
I've seen this on both a OnePlus One and a OnePlus X phone. On my Asus Tablet and a Smasung A3 phone it works fine though. Its not related to the OS version either as I've tried it on 4.4.2, 5, 6 and 7 with mixed results. It definitly seems to be hardware related.
I've also seen related posts describing this issue but none so far with an answer as to what is causing it.
Can anyone explain this or shed any light on the problem? Even if it is only to understand the limitation of what I am doing?
FYI - I did look at Soundpool but can't use it becuase the clips I am using are bigger than 1Mb.
Thanks in advance...
For your goal mixing music you can develop your own "mixer" which will work with raw audio data.
Steps are:
extracting encoded audio data from a music file by MediaExtractor
decoding these ByteBuffers by Decoder (MediaCodec)
mixing one decoded buffer from first audio with one decoded buffer form second audio to get one mixed buffer, here is algorithm
playing the mixed buffer by AudioTrack
Here is a lot of work but it will work anywhere!
Thanks for the suggestion. In the end found a way round it. If you use the newer AudioAttributes option (API 21 and above) and set the FLAG_AUDIBILITY_ENFORCED flag it then seems to force the devices I was having issues with to play the streams.... thanks for looking folks!

Android progressive resource sound playback

I'm attempting to use both progressive and cached sound files in my android app. Tthe soundpool works great for preloading small files, but obviously sometimes you need to play a 15-30sec sound file. I don't want to preload those (and can't due to memory constraints), but i'm at a loss to discover how to progressively stream resource sounds. Every tutorial about progressive sound streaming is for HTTP streams.
The sounds are in /res/raw/ and are oggs.
How do i progressively stream local resource sounds?
Since it's been some time from this question's being asked, i figure i'll mark it as answered with the method i went with.
I decided to make a jni wrapper over libvorbis and include the library with the app so that it can stream sounds using native libvorbis code. It's a pain, and it really shouldn't be necessary with all the decoding capability that android has, but i can't find any convenience methods.
So, for future googlers, sorry for the bad news.

Only video plays not the sound. Why is that ?

I read this code to play video files using xuggler as a library.When i run this code , the video without sound plays.Why is that ?
If not what should i do to play audio with video.?
Quite simply, it's because that code doesn't play any audio. It was never written to do so!
If you want to play audio and video, check out the example here:
http://xuggle.googlecode.com/svn/trunk/java/xuggle-xuggler/src/com/xuggle/xuggler/demos/DecodeAndPlayAudioAndVideo.java
The question to me suggests that you've just grabbed the source without looking at the tutorials - I'd strongly suggest doing so so you can understand the code behind what's going on rather than just throwing it in there and expecting it to work - especially if you're planning on using Xuggler in any great depth!
As a further note, if all you want to do is play videos I probably wouldn't advise using Xuggler because it's just not really designed for that sort of thing. Sure it will play them, but you have to manage all the sync issues yourself (which the above example doesn't do a great job of), it will only use your CPU and therefore really eat into its consumption especially if you're doing things like HD video, and the sheer amount of background code is just overkill (getting the streams, finding the stream IDs, extracting each packet, determining the type of the packet, dealing with it appropriately, managing errors, etc. etc.) It's a great piece of software, but if you're only using it to play stuff then it'll probably give you far more trouble than its worth.
Instead I'd advocate having a play with VLCJ - it's a bit complicated to get set up to work reliably (out of process players are required for rock solid stability) but when you've got that far it plays near any file type under the sun and manages all the issues above for you much, much better than you'll ever cope with by hand!
My guess is that you have a missing audio codec. I've had this same issue but vice versa; the sound played but the video didn't.

Getting PCM data from MP3 on Android

I am interested in doing some music analysis on the Android platform. To do this, I want to parse an arbitrary MP3 into PCM data. I've looked around and there doesn't seem to be an easy way to do this. One solution I've tried is using jLayer. This works, but it is incredibly slow, decoding the song in the same time it takes to play it.
I know there exists an MP3 decoder on Android, Google says so itself under supported media types. Does anyone know how to use the Android decoder to decode an MP3 without actually playing it? All I want to do is divert the bits away from the DAC and store them in some buffer instead.
Alternatively, has anyone had any success using the NDK and something like MAD? Are the performance gains that good?
You can compile and use LAME decoder. It works fine on ARM. And since its C/C++, performance would be better.
Hardware decoder on most ARM platforms are geared towards playback. So would not give you perfect PCM. E.g., to avoid jitter it would skip some data if load is high.
Instructions on compiling LAME are:
Lame MP3 Encoder compile for Android

Categories