/**
* Copyright 2011 The ForPlay Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package forplay.android;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import forplay.core.Audio;
import forplay.core.Sound;
class AndroidAudio implements Audio {
private int ordinal;
private List<AndroidSound> sounds = new ArrayList<AndroidSound>();
public AndroidAudio() {
}
Sound getSound(String path, InputStream in) throws IOException {
String extension = path.substring(path.lastIndexOf('.'));
// TODO: This doesn't explicitly clean up these cache files beyond
// deleteOnExit (which I'm not actually sure works on Android). It's
// probably safe to delete them once we hand off the FD to the media player,
// but this needs testing.
File tmp = new File(AndroidPlatform.instance.activity.getCacheDir(), "sound-" + ordinal++
+ extension);
tmp.deleteOnExit();
try {
FileOutputStream out = new FileOutputStream(tmp);
try {
byte[] buffer = new byte[16 * 1024];
while (true) {
int r = in.read(buffer);
if (r < 0)
break;
out.write(buffer, 0, r);
}
} finally {
out.close();
}
} finally {
in.close();
}
// The media player runs in a different process with a different user ID.
// This player may not have access to the play we want to play, so we pass a
// FileDescriptor instead.
FileInputStream ins = new FileInputStream(tmp);
MediaPlayer mp;
try {
mp = new MediaPlayer();
mp.setDataSource(ins.getFD());
// TODO: This blocks until the media is ready to play. Do we even need the
// buffering update listener below?
mp.prepare();
} finally {
ins.close();
}
final AndroidSound sound = new AndroidSound(path, mp);
mp.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
boolean loaded;
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
if (!loaded) {
sound.loaded();
loaded = true;
}
}
});
sounds.add(sound);
return sound;
}
public void destroy() {
for (AndroidSound sound : sounds) {
sound.stop();
}
}
public void pause() {
for (AndroidSound sound : sounds) {
sound.pause();
}
}
public void resume() {
for (AndroidSound sound : sounds) {
sound.resume();
}
}
}