/*
* Copyright (C) 2016 Google Inc. All Rights Reserved.
*
* 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 com.google.android.apps.santatracker.doodles.shared.sound;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.util.Log;
/**
* A wrapper around a MediaPlayer which allows for a gapless, looping track.
*/
public class LoopingMediaPlayer implements PineappleMediaPlayer {
private static final String TAG = LoopingMediaPlayer.class.getSimpleName();
private MediaPlayer currentPlayer;
private MediaPlayer nextPlayer;
private AssetFileDescriptor soundFileDescriptor;
private float volume;
public static LoopingMediaPlayer create(Context context, int resId) {
return new LoopingMediaPlayer(context, resId);
}
private LoopingMediaPlayer(Context context, int resId) {
soundFileDescriptor = context.getResources().openRawResourceFd(resId);
currentPlayer = MediaPlayer.create(context, resId);
nextPlayer = MediaPlayer.create(context, resId);
currentPlayer.setNextMediaPlayer(nextPlayer);
currentPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
try {
currentPlayer.reset();
currentPlayer.setDataSource(soundFileDescriptor.getFileDescriptor(),
soundFileDescriptor.getStartOffset(), soundFileDescriptor.getLength());
currentPlayer.prepare();
nextPlayer.setNextMediaPlayer(currentPlayer);
} catch (Exception e) {
Log.w(TAG, "onCompletion: unexpected exception", e);
}
}
});
nextPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
try {
nextPlayer.reset();
nextPlayer.setDataSource(soundFileDescriptor.getFileDescriptor(),
soundFileDescriptor.getStartOffset(), soundFileDescriptor.getLength());
nextPlayer.prepare();
currentPlayer.setNextMediaPlayer(nextPlayer);
} catch (Exception e) {
Log.w(TAG, "onCompletion: unexpected exception", e);
}
}
});
}
@Override
public void start() {
try {
currentPlayer.start();
} catch (IllegalStateException e) {
Log.w(TAG, "start() failed: " + e.toString());
}
}
@Override
public boolean isPlaying() {
return currentPlayer.isPlaying() || nextPlayer.isPlaying();
}
@Override
public void pause() {
try {
currentPlayer.pause();
nextPlayer.pause();
} catch (Exception e) {
Log.w(TAG, "pause() failed: " + e.toString());
}
}
@Override
public MediaPlayer getMediaPlayer() {
return currentPlayer;
}
@Override
public void setNextMediaPlayer(MediaPlayer mediaPlayer) {
try {
currentPlayer.setNextMediaPlayer(mediaPlayer);
} catch (Exception e) {
Log.w(TAG, "setNextMediaPlayer() failed: ", e);
}
}
@Override
public void setVolume(float volume) {
this.volume = volume;
try {
currentPlayer.setVolume(volume, volume);
nextPlayer.setVolume(volume, volume);
} catch (Exception e) {
Log.w(TAG, "setVolume() failed: ", e);
}
}
@Override
public void mute() {
try {
currentPlayer.setVolume(0, 0);
nextPlayer.setVolume(0, 0);
} catch (Exception e) {
Log.w(TAG, "mute() failed: ", e);
}
}
@Override
public void unmute() {
try {
currentPlayer.setVolume(volume, volume);
nextPlayer.setVolume(volume, volume);
} catch (Exception e) {
Log.w(TAG, "unmute() failed: ", e);
}
}
@Override
public void release() {
try {
currentPlayer.release();
nextPlayer.release();
soundFileDescriptor.close();
} catch (Exception e) {
Log.w(TAG, "release() failed: ", e);
}
}
}