Fixed playback speed issues when switching to next media

Fixes some issues related to the playback speed when playback was
completed or playback was paused and the app went away for awhile.

Now a media item which is "in progress" will remember its playback
speed so that it can be restored properly. The per-feed-media speed is
cleared once playback finishes, either by reaching the end or by the
user starting to play something different.
This commit is contained in:
Jonas Kalderstam 2019-09-12 10:57:16 +02:00
parent 4054c330ac
commit 6b1a7a9162
9 changed files with 76 additions and 18 deletions

View File

@ -11,9 +11,11 @@ import java.text.DecimalFormatSymbols;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
/**
@ -24,9 +26,6 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
private final AtomicBoolean isSetup = new AtomicBoolean(false);
// Used to work around race condition in updating the controller speed and receiving the callback that it has changed
private float playbackSpeed = -1;
@Override
protected void onResume() {
super.onResume();
@ -81,10 +80,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
}
float speed = 1.0f;
if(controller.canSetPlaybackSpeed()) {
speed = playbackSpeed;
if (speed == -1) {
speed = getPlaybackSpeedForMedia();
}
speed = getPlaybackSpeedForMedia();
}
String speedStr = new DecimalFormat("0.00x").format(speed);
butPlaybackSpeed.setText(speedStr);
@ -136,9 +132,10 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
break;
}
}
playbackSpeed = Float.parseFloat(newSpeed);
storeNewMediaPlaybackSpeed(newSpeed);
UserPreferences.setPlaybackSpeed(newSpeed);
controller.setPlaybackSpeed(playbackSpeed);
controller.setPlaybackSpeed(Float.parseFloat(newSpeed));
onPositionObserverUpdate();
} else {
VariableSpeedDialog.showGetPluginDialog(this);
@ -151,4 +148,11 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
butPlaybackSpeed.setVisibility(View.VISIBLE);
}
}
private void storeNewMediaPlaybackSpeed(String speed) {
Playable media = controller.getMedia();
if (media instanceof FeedMedia) {
((FeedMedia) media).updateLastPlaybackSpeed(speed);
}
}
}

View File

@ -879,7 +879,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
boolean isFeedMedia = media instanceof FeedMedia;
if (isFeedMedia) {
return ((FeedMedia) media).getFeedPlaybackSpeed();
return ((FeedMedia) media).getMediaPlaybackSpeed();
}
}

View File

@ -219,7 +219,7 @@ public class PlaybackControlsDialog extends DialogFragment {
boolean isFeedMedia = media instanceof FeedMedia;
if (isFeedMedia) {
return ((FeedMedia) media).getFeedPlaybackSpeed();
return ((FeedMedia) media).getMediaPlaybackSpeed();
}
}

View File

@ -55,6 +55,7 @@ public class FeedMedia extends FeedFile implements Playable {
private Date playbackCompletionDate;
private int startPosition = -1;
private int playedDurationWhenStarted;
private String lastPlaybackSpeed = null;
// if null: unknown, will be checked
private Boolean hasEmbeddedPicture;
@ -91,10 +92,11 @@ public class FeedMedia extends FeedFile implements Playable {
private FeedMedia(long id, FeedItem item, int duration, int position,
long size, String mime_type, String file_url, String download_url,
boolean downloaded, Date playbackCompletionDate, int played_duration,
Boolean hasEmbeddedPicture, long lastPlayedTime) {
Boolean hasEmbeddedPicture, long lastPlayedTime, String lastPlaybackSpeed) {
this(id, item, duration, position, size, mime_type, file_url, download_url, downloaded,
playbackCompletionDate, played_duration, lastPlayedTime);
this.hasEmbeddedPicture = hasEmbeddedPicture;
this.lastPlaybackSpeed = lastPlaybackSpeed;
}
public static FeedMedia fromCursor(Cursor cursor) {
@ -109,6 +111,7 @@ public class FeedMedia extends FeedFile implements Playable {
int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
int indexPlayedDuration = cursor.getColumnIndex(PodDBAdapter.KEY_PLAYED_DURATION);
int indexLastPlayedTime = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_PLAYED_TIME);
int indexLastPlaybackSpeed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_PLAYBACK_SPEED);
long mediaId = cursor.getLong(indexId);
Date playbackCompletionDate = null;
@ -143,7 +146,8 @@ public class FeedMedia extends FeedFile implements Playable {
playbackCompletionDate,
cursor.getInt(indexPlayedDuration),
hasEmbeddedPicture,
cursor.getLong(indexLastPlayedTime)
cursor.getLong(indexLastPlayedTime),
cursor.getString(indexLastPlaybackSpeed)
);
}
@ -624,15 +628,33 @@ public class FeedMedia extends FeedFile implements Playable {
return super.equals(o);
}
public String getLastPlaybackSpeed() {
return lastPlaybackSpeed;
}
public void updateLastPlaybackSpeed(String newSpeed) {
lastPlaybackSpeed = newSpeed;
DBWriter.setFeedMediaPlaybackInformation(this);
}
/**
*
* @return playback speed for this feed, or the global setting if no feed-specific setting
* @return the current playback speed for the media, or the feed's configured speed
*/
public float getFeedPlaybackSpeed() {
public float getMediaPlaybackSpeed() {
if (lastPlaybackSpeed != null) {
try {
return Float.parseFloat(lastPlaybackSpeed);
} catch (NumberFormatException e) {
lastPlaybackSpeed = null;
}
}
FeedItem item = getItem();
if (item != null) {
return item.getFeedPlaybackSpeed();
}
return UserPreferences.getPlaybackSpeed();
}
}

View File

@ -187,7 +187,6 @@ public class FeedPreferences {
try {
speed = Float.parseFloat(getFeedPlaybackSpeed());
} catch (NumberFormatException e) {
Log.e(TAG, Log.getStackTraceString(e));
setFeedPlaybackSpeed("global");
}
}

View File

@ -308,7 +308,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (media.getMediaType() == MediaType.VIDEO) {
setPlaybackParams(UserPreferences.getVideoPlaybackSpeed(), UserPreferences.isSkipSilence());
} else if (media instanceof FeedMedia) {
setPlaybackParams(((FeedMedia) media).getFeedPlaybackSpeed(), UserPreferences.isSkipSilence());
setPlaybackParams(((FeedMedia) media).getMediaPlaybackSpeed(), UserPreferences.isSkipSilence());
} else {
setPlaybackParams(UserPreferences.getPlaybackSpeed(), UserPreferences.isSkipSilence());
}

View File

@ -291,6 +291,8 @@ class DBUpgrader {
if (oldVersion < 1070306) {
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
+ " ADD COLUMN " + PodDBAdapter.KEY_FEED_PLAYBACK_SPEED + " TEXT");
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
+ " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYBACK_SPEED + " TEXT");
}
}

View File

@ -760,6 +760,20 @@ public class DBWriter {
});
}
/**
* Saves the 'lastPlaybackSpeed' attribute of a FeedMedia object
*
* @param media The FeedMedia object.
*/
public static Future<?> setFeedMediaLastPlaybackSpeed(final FeedMedia media) {
return dbExec.submit(() -> {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.setFeedMediaLastPlaybackSpeed(media);
adapter.close();
});
}
/**
* Saves a FeedItem object in the database. This method will save all attributes of the FeedItem object including
* the content of FeedComponent-attributes.

View File

@ -115,6 +115,7 @@ public class PodDBAdapter {
public static final String KEY_INCLUDE_FILTER = "include_filter";
public static final String KEY_EXCLUDE_FILTER = "exclude_filter";
public static final String KEY_FEED_PLAYBACK_SPEED = "feed_playback_speed";
public static final String KEY_LAST_PLAYBACK_SPEED = "last_playback_speed";
// Table names
static final String TABLE_NAME_FEEDS = "Feeds";
@ -169,7 +170,8 @@ public class PodDBAdapter {
+ KEY_FEEDITEM + " INTEGER,"
+ KEY_PLAYED_DURATION + " INTEGER,"
+ KEY_HAS_EMBEDDED_PICTURE + " INTEGER,"
+ KEY_LAST_PLAYED_TIME + " INTEGER)";
+ KEY_LAST_PLAYED_TIME + " INTEGER,"
+ KEY_LAST_PLAYBACK_SPEED + " TEXT)";
private static final String CREATE_TABLE_DOWNLOAD_LOG = "CREATE TABLE "
+ TABLE_NAME_DOWNLOAD_LOG + " (" + TABLE_PRIMARY_KEY + KEY_FEEDFILE
@ -440,6 +442,7 @@ public class PodDBAdapter {
values.put(KEY_FILE_URL, media.getFile_url());
values.put(KEY_HAS_EMBEDDED_PICTURE, media.hasEmbeddedPicture());
values.put(KEY_LAST_PLAYED_TIME, media.getLastPlayedTime());
values.put(KEY_LAST_PLAYBACK_SPEED, media.getLastPlaybackSpeed());
if (media.getPlaybackCompletionDate() != null) {
values.put(KEY_PLAYBACK_COMPLETION_DATE, media.getPlaybackCompletionDate().getTime());
@ -465,6 +468,7 @@ public class PodDBAdapter {
values.put(KEY_DURATION, media.getDuration());
values.put(KEY_PLAYED_DURATION, media.getPlayedDuration());
values.put(KEY_LAST_PLAYED_TIME, media.getLastPlayedTime());
values.put(KEY_LAST_PLAYBACK_SPEED, media.getLastPlaybackSpeed());
db.update(TABLE_NAME_FEED_MEDIA, values, KEY_ID + "=?",
new String[]{String.valueOf(media.getId())});
} else {
@ -472,11 +476,24 @@ public class PodDBAdapter {
}
}
public void setFeedMediaLastPlaybackSpeed(FeedMedia media) {
if (media.getId() != 0) {
ContentValues values = new ContentValues();
values.put(KEY_LAST_PLAYBACK_SPEED, media.getLastPlaybackSpeed());
db.update(TABLE_NAME_FEED_MEDIA, values, KEY_ID + "=?",
new String[]{String.valueOf(media.getId())});
} else {
Log.e(TAG, "setFeedMediaLastPlaybackSpeed: ID of media was 0");
}
}
public void setFeedMediaPlaybackCompletionDate(FeedMedia media) {
if (media.getId() != 0) {
ContentValues values = new ContentValues();
values.put(KEY_PLAYBACK_COMPLETION_DATE, media.getPlaybackCompletionDate().getTime());
values.put(KEY_PLAYED_DURATION, media.getPlayedDuration());
// Also reset stored playback speed for media
values.putNull(KEY_LAST_PLAYBACK_SPEED);
db.update(TABLE_NAME_FEED_MEDIA, values, KEY_ID + "=?",
new String[]{String.valueOf(media.getId())});
} else {