use of de.danoeh.antennapod.model.playback.Playable in project AntennaPod by AntennaPod.
the class PlaybackService method onStartCommand.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d(TAG, "OnStartCommand called");
stateManager.startForeground(R.id.notification_playing, notificationBuilder.build());
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.cancel(R.id.notification_streaming_confirmation);
final int keycode = intent.getIntExtra(MediaButtonReceiver.EXTRA_KEYCODE, -1);
final boolean hardwareButton = intent.getBooleanExtra(MediaButtonReceiver.EXTRA_HARDWAREBUTTON, false);
Playable playable = intent.getParcelableExtra(EXTRA_PLAYABLE);
if (keycode == -1 && playable == null) {
Log.e(TAG, "PlaybackService was started with no arguments");
stateManager.stopService();
return Service.START_NOT_STICKY;
}
if ((flags & Service.START_FLAG_REDELIVERY) != 0) {
Log.d(TAG, "onStartCommand is a redelivered intent, calling stopForeground now.");
stateManager.stopForeground(true);
} else {
if (keycode != -1) {
boolean notificationButton;
if (hardwareButton) {
Log.d(TAG, "Received hardware button event");
notificationButton = false;
} else {
Log.d(TAG, "Received media button event");
notificationButton = true;
}
boolean handled = handleKeycode(keycode, notificationButton);
if (!handled && !stateManager.hasReceivedValidStartCommand()) {
stateManager.stopService();
return Service.START_NOT_STICKY;
}
} else {
stateManager.validStartCommandWasReceived();
boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM, true);
boolean allowStreamThisTime = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_THIS_TIME, false);
boolean allowStreamAlways = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_ALWAYS, false);
boolean startWhenPrepared = intent.getBooleanExtra(EXTRA_START_WHEN_PREPARED, false);
boolean prepareImmediately = intent.getBooleanExtra(EXTRA_PREPARE_IMMEDIATELY, false);
sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0);
if (allowStreamAlways) {
UserPreferences.setAllowMobileStreaming(true);
}
boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl());
if (stream && !NetworkUtils.isStreamingAllowed() && !allowStreamThisTime && !localFeed) {
displayStreamingNotAllowedNotification(intent);
PlaybackPreferences.writeNoMediaPlaying();
stateManager.stopService();
return Service.START_NOT_STICKY;
}
Observable.fromCallable(() -> {
if (playable instanceof FeedMedia) {
return DBReader.getFeedMedia(((FeedMedia) playable).getId());
} else {
return playable;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(playableLoaded -> {
if (!playable.getIdentifier().equals(PlaybackPreferences.getCurrentlyPlayingFeedMediaId())) {
PlaybackPreferences.clearCurrentlyPlayingTemporaryPlaybackSpeed();
}
mediaPlayer.playMediaObject(playableLoaded, stream, startWhenPrepared, prepareImmediately);
addPlayableToQueue(playableLoaded);
}, error -> {
Log.d(TAG, "Playable was not found. Stopping service.");
error.printStackTrace();
stateManager.stopService();
});
return Service.START_NOT_STICKY;
}
}
return Service.START_NOT_STICKY;
}
use of de.danoeh.antennapod.model.playback.Playable in project AntennaPod by AntennaPod.
the class PlaybackService method skipEndingIfNecessary.
private void skipEndingIfNecessary() {
Playable playable = mediaPlayer.getPlayable();
if (!(playable instanceof FeedMedia)) {
return;
}
int duration = getDuration();
int remainingTime = duration - getCurrentPosition();
FeedMedia feedMedia = (FeedMedia) playable;
FeedPreferences preferences = feedMedia.getItem().getFeed().getPreferences();
int skipEnd = preferences.getFeedSkipEnding();
if (skipEnd > 0 && skipEnd * 1000 < getDuration() && (remainingTime - (skipEnd * 1000) > 0) && ((remainingTime - skipEnd * 1000) < (getCurrentPlaybackSpeed() * 1000))) {
Log.d(TAG, "skipEndingIfNecessary: Skipping the remaining " + remainingTime + " " + skipEnd * 1000 + " speed " + getCurrentPlaybackSpeed());
Context context = getApplicationContext();
String skipMesg = context.getString(R.string.pref_feed_skip_ending_toast, skipEnd);
Toast toast = Toast.makeText(context, skipMesg, Toast.LENGTH_LONG);
toast.show();
this.autoSkippedFeedMediaId = feedMedia.getItem().getIdentifyingValue();
mediaPlayer.skip();
}
}
use of de.danoeh.antennapod.model.playback.Playable in project AntennaPod by AntennaPod.
the class DBWriter method addQueueItem.
/**
* Appends FeedItem objects to the end of the queue. The 'read'-attribute of all items will be set to true.
* If a FeedItem is already in the queue, the FeedItem will not change its position in the queue.
*
* @param context A context that is used for opening a database connection.
* @param performAutoDownload true if an auto-download process should be started after the operation.
* @param markAsUnplayed true if the items should be marked as unplayed when enqueueing
* @param itemIds IDs of the FeedItem objects that should be added to the queue.
*/
public static Future<?> addQueueItem(final Context context, final boolean performAutoDownload, final boolean markAsUnplayed, final long... itemIds) {
return dbExec.submit(() -> {
if (itemIds.length < 1) {
return;
}
final PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
final List<FeedItem> queue = DBReader.getQueue(adapter);
boolean queueModified = false;
LongList markAsUnplayedIds = new LongList();
List<QueueEvent> events = new ArrayList<>();
List<FeedItem> updatedItems = new ArrayList<>();
ItemEnqueuePositionCalculator positionCalculator = new ItemEnqueuePositionCalculator(UserPreferences.getEnqueueLocation());
Playable currentlyPlaying = PlayableUtils.createInstanceFromPreferences(context);
int insertPosition = positionCalculator.calcPosition(queue, currentlyPlaying);
for (long itemId : itemIds) {
if (!itemListContains(queue, itemId)) {
final FeedItem item = DBReader.getFeedItem(itemId);
if (item != null) {
queue.add(insertPosition, item);
events.add(QueueEvent.added(item, insertPosition));
item.addTag(FeedItem.TAG_QUEUE);
updatedItems.add(item);
queueModified = true;
if (item.isNew()) {
markAsUnplayedIds.add(item.getId());
}
insertPosition++;
}
}
}
if (queueModified) {
applySortOrder(queue, events);
adapter.setQueue(queue);
for (QueueEvent event : events) {
EventBus.getDefault().post(event);
}
EventBus.getDefault().post(FeedItemEvent.updated(updatedItems));
if (markAsUnplayed && markAsUnplayedIds.size() > 0) {
DBWriter.markItemPlayed(FeedItem.UNPLAYED, markAsUnplayedIds.toArray());
}
}
adapter.close();
if (performAutoDownload) {
DBTasks.autodownloadUndownloadedItems(context);
}
});
}
use of de.danoeh.antennapod.model.playback.Playable in project AntennaPod by AntennaPod.
the class PlaybackService method bufferUpdate.
@Subscribe(threadMode = ThreadMode.MAIN)
@SuppressWarnings("unused")
public void bufferUpdate(BufferUpdateEvent event) {
if (event.hasEnded()) {
Playable playable = getPlayable();
if (getPlayable() instanceof FeedMedia && playable.getDuration() <= 0 && mediaPlayer.getDuration() > 0) {
// Playable is being streamed and does not have a duration specified in the feed
playable.setDuration(mediaPlayer.getDuration());
DBWriter.setFeedMedia((FeedMedia) playable);
updateNotificationAndMediaSession(playable);
}
}
}
use of de.danoeh.antennapod.model.playback.Playable in project AntennaPod by AntennaPod.
the class FeedMedia method getMediaItem.
/**
* Returns a MediaItem representing the FeedMedia object.
* This is used by the MediaBrowserService
*/
public MediaBrowserCompat.MediaItem getMediaItem() {
Playable p = this;
MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder().setMediaId(String.valueOf(id)).setTitle(p.getEpisodeTitle()).setDescription(p.getFeedTitle()).setSubtitle(p.getFeedTitle());
if (item != null) {
// getImageLocation() also loads embedded images, which we can not send to external devices
if (item.getImageUrl() != null) {
builder.setIconUri(Uri.parse(item.getImageUrl()));
} else if (item.getFeed() != null && item.getFeed().getImageUrl() != null) {
builder.setIconUri(Uri.parse(item.getFeed().getImageUrl()));
}
}
return new MediaBrowserCompat.MediaItem(builder.build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE);
}
Aggregations