سؤال

Is it possible to make MediaPlayer output into a raw buffer instead of playback device?

There's an internet radio providing media files for direct download. Example: http://fresh.moskva.fm/files/2004/mp4/2013/11/13/203112.mp4 - channel 2004, 2013-11-13 20:31:12 http://fresh.moskva.fm/files/2004/mp4/2013/11/13/203113.mp4 - channel 2004, 2013-11-13 20:31:13

Each file has length: 1:02 (2 seconds overlap).

The current solution is to use 2 instances of MediaPlayer, call prepare() for one instance while the other is playing and seekTo() to skip 2 seconds. But gaps can still be heard sometimes.

Instead, I want to decode the audio into raw sound and then combine it.

هل كانت مفيدة؟

المحلول

Gapless playback with 2 media players is not possible, mostly because of unpredictable delay between entering pausedPlayer.start() and actual playback. The delay can even be negative, because an unpaused player skips some milliseconds.

I tried to squeeze the most from 2 media players here: https://github.com/basinilya/piterfm/blob/7e1f62a2303d1a32f617eee629ab514bc6019437/src/ru/piter/fm/player/SmoothMediaPlayer.java

  • getCurrentPosition() step on mp4 AAC fils is to rough: ~46 or ~92ms. So to get real position I wait in a loop until the value changes.
  • I don't call seek(2000) on next player, but instead warm it up by silencing and running for some time
  • When it's about time to switch to the next player, I get the precisest possible positions, then sleep, then resume the muted player, sleep again, and unmute it.
  • time to sleep is calculated from both positions and average resume delay.

On real devices the clicks stay, but not so noticeable

نصائح أخرى

My first question would be is the 2 seconds EXACTLY 2 seconds to the sample level or is it something less than that? In other words, once the audio is decompressed and playable, for 1 second you should end up with 44,100 samples if sampled at 44.1KHz. Therefore, 2 seconds would be 88,200 samples. So, if when you finish with the one file and start the next...can you skip the last 88,200 samples of one and start playing the next and it will be seamless? If not, then you may never get it to perfectly sync up like you would want without a glitch, etc.

My suggestion would be to download each file individually and look at the raw data (once decompressed) in an audio editor to figure out if this is the case. If so, then it should work fine in code once you decide how you want to implement it. There are many ways - you could use two media players but probably the better way is to use one circular buffer that you fill with samples from the files and play from at the same time. The odds are the media players themselves are simply not "immediate" enough when seeking or beginning to play - you need sample-accuracy to get truly seamless playback.

To summarize: step 1 is make sure the data is what you think it is. Step 2 is to implement the mechanism to manage it once you know the answer to step 1.

Note that this technique is generic to any platform.

Hope this helps.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top