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" <manifest xmlns:a="http://schemas.android.com/apk/res/android"
package="com.thejoshwa.ultrasonic.androidapp" package="com.thejoshwa.ultrasonic.androidapp"
a:installLocation="auto" a:installLocation="auto"
a:versionCode="5" a:versionCode="6"
a:versionName="1.0.0.29" > a:versionName="1.0.0.30" >
<uses-permission a:name="android.permission.INTERNET" /> <uses-permission a:name="android.permission.INTERNET" />
<uses-permission a:name="android.permission.READ_PHONE_STATE" /> <uses-permission a:name="android.permission.READ_PHONE_STATE" />

View File

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

View File

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

View File

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

View File

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

View File

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