120 lines
4.9 KiB
Java
120 lines
4.9 KiB
Java
package de.danoeh.antennapod.net.download.service.episode;
|
|
|
|
import android.content.Context;
|
|
import android.media.MediaMetadataRetriever;
|
|
import android.util.Log;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import de.danoeh.antennapod.model.MediaMetadataRetrieverCompat;
|
|
import de.danoeh.antennapod.net.sync.serviceinterface.SynchronizationQueueSink;
|
|
import de.danoeh.antennapod.ui.chapters.ChapterUtils;
|
|
import org.greenrobot.eventbus.EventBus;
|
|
|
|
import java.io.File;
|
|
import java.io.InterruptedIOException;
|
|
import java.util.concurrent.ExecutionException;
|
|
|
|
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
|
|
import de.danoeh.antennapod.model.download.DownloadRequest;
|
|
import de.danoeh.antennapod.model.download.DownloadResult;
|
|
import de.danoeh.antennapod.storage.database.DBReader;
|
|
import de.danoeh.antennapod.storage.database.DBWriter;
|
|
import de.danoeh.antennapod.model.download.DownloadError;
|
|
import de.danoeh.antennapod.model.feed.FeedItem;
|
|
import de.danoeh.antennapod.model.feed.FeedMedia;
|
|
import de.danoeh.antennapod.net.sync.serviceinterface.EpisodeAction;
|
|
|
|
/**
|
|
* Handles a completed media download.
|
|
*/
|
|
public class MediaDownloadedHandler implements Runnable {
|
|
private static final String TAG = "MediaDownloadedHandler";
|
|
private final DownloadRequest request;
|
|
private final Context context;
|
|
private DownloadResult updatedStatus;
|
|
|
|
public MediaDownloadedHandler(@NonNull Context context, @NonNull DownloadResult status,
|
|
@NonNull DownloadRequest request) {
|
|
this.request = request;
|
|
this.context = context;
|
|
this.updatedStatus = status;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
FeedMedia media = DBReader.getFeedMedia(request.getFeedfileId());
|
|
if (media == null) {
|
|
Log.e(TAG, "Could not find downloaded media object in database");
|
|
return;
|
|
}
|
|
// media.setDownloaded modifies played state
|
|
boolean broadcastUnreadStateUpdate = media.getItem() != null && media.getItem().isNew();
|
|
media.setDownloaded(true);
|
|
media.setLocalFileUrl(request.getDestination());
|
|
media.setSize(new File(request.getDestination()).length());
|
|
media.checkEmbeddedPicture(); // enforce check
|
|
|
|
try {
|
|
// Cache chapters if file has them
|
|
if (media.getItem() != null && !media.getItem().hasChapters()) {
|
|
media.setChapters(ChapterUtils.loadChaptersFromMediaFile(media, context));
|
|
}
|
|
if (media.getItem() != null && media.getItem().getPodcastIndexChapterUrl() != null) {
|
|
ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl(), false);
|
|
}
|
|
} catch (InterruptedIOException ignore) {
|
|
// Ignore
|
|
}
|
|
|
|
// Get duration
|
|
String durationStr = null;
|
|
try (MediaMetadataRetrieverCompat mmr = new MediaMetadataRetrieverCompat()) {
|
|
mmr.setDataSource(media.getLocalFileUrl());
|
|
durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
|
|
media.setDuration(Integer.parseInt(durationStr));
|
|
Log.d(TAG, "Duration of file is " + media.getDuration());
|
|
} catch (NumberFormatException e) {
|
|
Log.d(TAG, "Invalid file duration: " + durationStr);
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Get duration failed", e);
|
|
}
|
|
|
|
final FeedItem item = media.getItem();
|
|
|
|
try {
|
|
DBWriter.setFeedMedia(media).get();
|
|
|
|
// we've received the media, we don't want to autodownload it again
|
|
if (item != null) {
|
|
item.disableAutoDownload();
|
|
// setFeedItem() signals (via EventBus) that the item has been updated,
|
|
// so we do it after the enclosing media has been updated above,
|
|
// to ensure subscribers will get the updated FeedMedia as well
|
|
DBWriter.setFeedItem(item).get();
|
|
if (broadcastUnreadStateUpdate) {
|
|
EventBus.getDefault().post(new UnreadItemsUpdateEvent());
|
|
}
|
|
}
|
|
} catch (InterruptedException e) {
|
|
Log.e(TAG, "MediaHandlerThread was interrupted");
|
|
} catch (ExecutionException e) {
|
|
Log.e(TAG, "ExecutionException in MediaHandlerThread: " + e.getMessage());
|
|
updatedStatus = new DownloadResult(media.getEpisodeTitle(), media.getId(),
|
|
FeedMedia.FEEDFILETYPE_FEEDMEDIA, false, DownloadError.ERROR_DB_ACCESS_ERROR, e.getMessage());
|
|
}
|
|
|
|
if (item != null) {
|
|
EpisodeAction action = new EpisodeAction.Builder(item, EpisodeAction.DOWNLOAD)
|
|
.currentTimestamp()
|
|
.build();
|
|
SynchronizationQueueSink.enqueueEpisodeActionIfSynchronizationIsActive(context, action);
|
|
}
|
|
}
|
|
|
|
@NonNull
|
|
public DownloadResult getUpdatedStatus() {
|
|
return updatedStatus;
|
|
}
|
|
}
|