Remove resumable playback, fix offline playback in certain scenarios

This commit is contained in:
Joshua Bahnsen 2013-04-18 16:21:24 -07:00
parent 65acf17344
commit ef8bf089c4
6 changed files with 111 additions and 101 deletions

View File

@ -2,8 +2,8 @@
<manifest xmlns:a="http://schemas.android.com/apk/res/android"
package="com.thejoshwa.ultrasonic.androidapp"
a:installLocation="auto"
a:versionCode="5"
a:versionName="1.0.0.29" >
a:versionCode="6"
a:versionName="1.0.0.30" >
<uses-permission a:name="android.permission.INTERNET" />
<uses-permission a:name="android.permission.READ_PHONE_STATE" />

View File

@ -222,7 +222,7 @@
a:summary="@string/settings.show_lockscreen_controls_summary"
a:title="@string/settings.show_lockscreen_controls" />
<CheckBoxPreference
a:defaultValue="true"
a:defaultValue="false"
a:key="useStreamProxy"
a:summary="@string/settings.use_stream_proxy_summary"
a:title="@string/settings.use_stream_proxy" />

View File

@ -28,6 +28,7 @@ import android.content.Context;
import android.os.PowerManager;
import android.util.DisplayMetrics;
import android.util.Log;
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
import com.thejoshwa.ultrasonic.androidapp.util.CancellableTask;
import com.thejoshwa.ultrasonic.androidapp.util.FileUtil;
@ -62,16 +63,22 @@ public class DownloadFile {
this.save = save;
saveFile = FileUtil.getSongFile(context, song);
bitRate = Util.getMaxBitrate(context);
partialFile = new File(saveFile.getParent(), FileUtil.getBaseName(saveFile.getName()) +
"." + bitRate + ".partial." + FileUtil.getExtension(saveFile.getName()));
completeFile = new File(saveFile.getParent(), FileUtil.getBaseName(saveFile.getName()) +
".complete." + FileUtil.getExtension(saveFile.getName()));
partialFile = new File(saveFile.getParent(), FileUtil.getBaseName(saveFile.getName()) + "." + bitRate + ".partial." + FileUtil.getExtension(saveFile.getName()));
completeFile = new File(saveFile.getParent(), FileUtil.getBaseName(saveFile.getName()) + ".complete." + FileUtil.getExtension(saveFile.getName()));
mediaStoreService = new MediaStoreService(context);
}
public MusicDirectory.Entry getSong() {
return song;
}
public boolean isOffline() {
return Util.isOffline(context);
}
public boolean isStreamProxyEnabled() {
return Util.isStreamProxyEnabled(context);
}
/**
* Returns the effective bit rate.
@ -198,6 +205,7 @@ public class DownloadFile {
InputStream in = null;
FileOutputStream out = null;
PowerManager.WakeLock wakeLock = null;
try {
if (Util.isScreenLitOnDownload(context)) {
@ -219,6 +227,10 @@ public class DownloadFile {
}
return;
}
if (isOffline()) {
Log.i(TAG, "We are offline. Skipping.");
return;
}
MusicService musicService = MusicServiceFactory.getMusicService(context);

View File

@ -478,7 +478,6 @@ public class DownloadServiceImpl extends Service implements DownloadService {
{
int current = getCurrentPlayingIndex();
if (current == -1) {
resetProgressBar();
play(0);
} else {
play(current);
@ -543,10 +542,8 @@ public class DownloadServiceImpl extends Service implements DownloadService {
// Restart song if played more than five seconds.
if (getPlayerPosition() > 5000 || index == 0) {
resetProgressBar();
play(index);
} else {
resetProgressBar();
play(index - 1);
}
}
@ -555,22 +552,11 @@ public class DownloadServiceImpl extends Service implements DownloadService {
public synchronized void next() {
int index = getCurrentPlayingIndex();
if (index != -1) {
resetProgressBar();
play(index + 1);
}
}
private void resetProgressBar()
{
SeekBar progressBar = DownloadActivity.getProgressBar();
if (progressBar != null) {
progressBar.setProgress(0);
}
secondaryProgress = -1;
}
private void onSongCompleted() {
resetProgressBar();
int index = getCurrentPlayingIndex();
if (index != -1) {
@ -612,8 +598,6 @@ public class DownloadServiceImpl extends Service implements DownloadService {
try {
if (playerState == STARTED) {
resetProgressBar();
if (jukeboxEnabled) {
jukeboxService.stop();
} else {
@ -680,7 +664,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
return duration * 1000;
}
}
if (playerState != IDLE && playerState != DOWNLOADING && playerState != PlayerState.PREPARING) {
if (playerState != IDLE && playerState != DOWNLOADING && playerState != PREPARING) {
try {
return mediaPlayer.getDuration();
} catch (Exception x) {
@ -716,7 +700,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
Util.broadcastA2dpPlayStatusChange(this, this.playerState, getInstance());
// Set remote control
updateRemoteControl();
updateRemoteControl();
// Update widget
UltraSonicAppWidgetProvider4x1.getInstance().notifyChange(this, this, this.playerState == PlayerState.STARTED);
@ -854,14 +838,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
private synchronized void bufferAndPlay() {
reset();
int progressBarProgress = 0;
SeekBar progressBar = DownloadActivity.getProgressBar();
if (progressBar != null) {
progressBarProgress = progressBar.getProgress();
}
bufferTask = new BufferTask(currentPlaying, progressBarProgress);
bufferTask = new BufferTask(currentPlaying, 0);
bufferTask.start();
}
@ -934,6 +911,8 @@ public class DownloadServiceImpl extends Service implements DownloadService {
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
Log.i(TAG, "Media player prepared");
setPlayerState(PREPARED);
SeekBar progressBar = DownloadActivity.getProgressBar();
@ -963,8 +942,10 @@ public class DownloadServiceImpl extends Service implements DownloadService {
String playUrl = url;
// Only use stream proxy if it is enabled and no complete file is available
if (Util.isStreamProxyEnabled(this) && !downloadFile.isCompleteFileAvailable()) {
if (!downloadFile.isOffline() && downloadFile.isStreamProxyEnabled() && !downloadFile.isCompleteFileAvailable()) {
if (proxy == null) {
Log.i(TAG, "Creating StreamProxy instance");
proxy = new StreamProxy();
proxy.start();
}
@ -973,8 +954,13 @@ public class DownloadServiceImpl extends Service implements DownloadService {
playUrl = String.format("http://127.0.0.1:%d/%s", proxy.getPort(), url);
}
Log.i(TAG, "Setting media player data source: " + playUrl);
mediaPlayer.setDataSource(playUrl);
setPlayerState(PREPARING);
Log.i(TAG, "Preparing media player");
mediaPlayer.prepareAsync();
} catch (Exception x) {
handleError(x);
@ -1120,28 +1106,23 @@ public class DownloadServiceImpl extends Service implements DownloadService {
this.position = position;
partialFile = downloadFile.getPartialFile();
if (!Util.isStreamProxyEnabled(getBaseContext())) {
int bufferLength = downloadFile.getBufferLength();
int bufferLength = downloadFile.getBufferLength();
// Calculate roughly how many bytes buffer length corresponds to.
int bitRate = downloadFile.getBitRate();
long byteCount = Math.max(100000, bitRate * 1024 / 8 * bufferLength);
// Calculate roughly how many bytes buffer length corresponds to.
int bitRate = downloadFile.getBitRate();
long byteCount = Math.max(100000, bitRate * 1024 / 8 * bufferLength);
// Find out how large the file should grow before resuming playback.
if (position == 0) {
expectedFileSize = byteCount;
} else {
expectedFileSize = partialFile.length() + byteCount;
}
} else {
Log.i(TAG, "StreamProxy is enabled, will let media player control buffer size");
expectedFileSize = 0;
}
// Find out how large the file should grow before resuming playback.
if (position == 0) {
expectedFileSize = byteCount;
} else {
expectedFileSize = partialFile.length() + byteCount;
}
}
@Override
public void execute() {
if (!getIsCompleteFileAvailable(downloadFile)) {
if (!downloadFile.isOffline() && !getIsCompleteFileAvailable(downloadFile)) {
setPlayerState(DOWNLOADING);
while (!bufferComplete()) {
@ -1167,18 +1148,18 @@ public class DownloadServiceImpl extends Service implements DownloadService {
}
private boolean bufferComplete() {
if (!getIsCompleteFileAvailable(downloadFile)) {
if (!downloadFile.isOffline() && getIsCompleteFileAvailable(downloadFile)) {
long size = partialFile.length();
if (size >= expectedFileSize) {
Log.i(TAG, "Buffering complete: " + partialFile + " ("
+ size + "/" + expectedFileSize + ")");
Log.i(TAG, "Buffering complete: " + partialFile + " (" + size + "/" + expectedFileSize + ")");
return true;
}
Log.i(TAG, "Buffering incomplete: " + partialFile + " (" + size
+ "/" + expectedFileSize + ")");
Log.i(TAG, "Buffering incomplete: " + partialFile + " (" + size + "/" + expectedFileSize + ")");
return false;
} else {
Log.i(TAG, "Buffering complete: " + partialFile);
return true;
}
}

View File

@ -67,8 +67,17 @@ public class OfflineMusicService extends RESTMusicService {
if (file.isDirectory()) {
Artist artist = new Artist();
artist.setId(file.getPath());
artist.setIndex(file.getName().substring(0, 1));
artist.setName(file.getName());
String artistIndex = "";
try {
artistIndex = file.getName().substring(0, 1);
}
catch (Exception ex) { }
artist.setIndex(artistIndex);
artists.add(artist);
}
}
@ -125,7 +134,7 @@ public class OfflineMusicService extends RESTMusicService {
String disc = null;
String year = null;
String genre = null;
String bitrate = null;
//String bitrate = null;
String duration = null;
String hasVideo = null;
@ -144,9 +153,7 @@ public class OfflineMusicService extends RESTMusicService {
duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
hasVideo = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
mmr.release();
} catch (Exception ex) {
}
} catch (Exception ex) { }
entry.setArtist(artist != null ? artist : file.getParentFile().getParentFile().getName());
entry.setAlbum(album != null ? album : file.getParentFile().getName());
@ -157,74 +164,77 @@ public class OfflineMusicService extends RESTMusicService {
entry.setVideo(hasVideo != null);
Log.i("OfflineMusicService", "Offline Stuff: " + track);
if (track != null) {
int slashIndex = track.indexOf("/");
if (slashIndex != 0) {
track = track.substring(0, slashIndex);
}
int trackValue = 0;
try {
int slashIndex = track.indexOf("/");
int trackValue = 0;
if (slashIndex > 0) {
track = track.substring(0, slashIndex);
}
try {
trackValue = Integer.parseInt(track);
}
catch(NumberFormatException nfe) {
}
}
catch(Exception ex) { Log.e("OfflineMusicService", "Offline Stuff: " + ex); }
Log.i("OfflineMusicService", "Offline Stuff: Setting Track: " + trackValue);
entry.setTrack(trackValue);
}
if (disc != null) {
int slashIndex = disc.indexOf("/");
if (slashIndex != 0) {
disc = disc.substring(0, slashIndex);
}
int discValue = 0;
try {
int slashIndex = disc.indexOf("/");
int discValue = 0;
if (slashIndex > 0) {
disc = disc.substring(0, slashIndex);
}
try {
discValue = Integer.parseInt(disc);
}
catch(NumberFormatException nfe) {
}
entry.setDiscNumber(discValue);
catch(Exception ex) { }
entry.setDiscNumber(discValue);
}
if (year != null) {
int yearValue = 0;
try {
yearValue = Integer.parseInt(year);
} catch(NumberFormatException nfe) {
}
entry.setYear(yearValue);
} catch(Exception ex) { }
entry.setYear(yearValue);
}
if (genre != null) {
entry.setGenre(genre);
}
if (bitrate != null) {
int bitRateValue = 0;
try {
bitRateValue = Integer.parseInt(bitrate) / 1000;
} catch(NumberFormatException nfe) {
}
entry.setBitRate(bitRateValue);
}
// if (bitrate != null) {
// int bitRateValue = 0;
//
// try {
// bitRateValue = Integer.parseInt(bitrate) / 1000;
// } catch(Exception ex) { }
//
// entry.setBitRate(bitRateValue);
// }
if (duration != null) {
long durationValue = 0;
try {
durationValue = Long.parseLong(duration);
} catch(NumberFormatException nfe) {
}
durationValue = TimeUnit.MILLISECONDS.toSeconds(durationValue);
durationValue = TimeUnit.MILLISECONDS.toSeconds(durationValue);
} catch(Exception ex) { }
entry.setDuration(durationValue);
}
}
@ -232,9 +242,11 @@ public class OfflineMusicService extends RESTMusicService {
entry.setSuffix(FileUtil.getExtension(file.getName().replace(".complete", "")));
File albumArt = FileUtil.getAlbumArtFile(context, entry);
if (albumArt.exists()) {
entry.setCoverArt(albumArt.getPath());
}
return entry;
}

View File

@ -97,8 +97,13 @@ public abstract class ModalBackgroundTask<T> extends BackgroundTask<T> {
getHandler().post(new Runnable() {
@Override
public void run() {
progressDialog.dismiss();
error(t);
try {
progressDialog.dismiss();
} catch (Exception e) {
// nothing
}
error(t);
}
});
}