diff options
author | Tony Tam <149837+tonytamsf@users.noreply.github.com> | 2024-03-17 00:52:16 -1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-17 11:52:16 +0100 |
commit | 8dc8cc64a8a6de3adfba1aaf0a0306f90727a2c4 (patch) | |
tree | 6edcb4ae7600a7f6353684b418833257fbe746f2 | |
parent | 48c0ccb4a261eed51959973e86e673ec27462bfa (diff) | |
download | AntennaPod-8dc8cc64a8a6de3adfba1aaf0a0306f90727a2c4.zip |
Allow retrying chapter loading if interrupted (#6828)
Chapter loading can sometimes get interrupted, most importantly if
the corresponding fragment tries to refresh the view again.
Before, this set the chapters to an empty list, indicating that it
should not be tried again. Now, interrupted exceptions do not set
the list to be empty, so it can be retried later.
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java | 17 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java | 66 |
2 files changed, 51 insertions, 32 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java index 98c470f21..55831b821 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java @@ -10,6 +10,7 @@ import de.danoeh.antennapod.model.MediaMetadataRetrieverCompat; import org.greenrobot.eventbus.EventBus; import java.io.File; +import java.io.InterruptedIOException; import java.util.concurrent.ExecutionException; import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; @@ -54,14 +55,18 @@ public class MediaDownloadedHandler implements Runnable { media.setSize(new File(request.getDestination()).length()); media.checkEmbeddedPicture(); // enforce check - // check if file has chapters - if (media.getItem() != null && !media.getItem().hasChapters()) { - media.setChapters(ChapterUtils.loadChaptersFromMediaFile(media, context)); + 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 } - if (media.getItem() != null && media.getItem().getPodcastIndexChapterUrl() != null) { - ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl(), false); - } // Get duration String durationStr = null; try (MediaMetadataRetrieverCompat mmr = new MediaMetadataRetrieverCompat()) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java index 084b34e76..901771913 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java @@ -28,6 +28,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.util.Collections; import java.util.List; @@ -60,42 +61,50 @@ public class ChapterUtils { return; } - List<Chapter> chaptersFromDatabase = null; - List<Chapter> chaptersFromPodcastIndex = null; - if (playable instanceof FeedMedia) { - FeedMedia feedMedia = (FeedMedia) playable; - if (feedMedia.getItem() == null) { - feedMedia.setItem(DBReader.getFeedItem(feedMedia.getItemId())); - } - if (feedMedia.getItem().hasChapters()) { - chaptersFromDatabase = DBReader.loadChaptersOfFeedItem(feedMedia.getItem()); - } + try { + List<Chapter> chaptersFromDatabase = null; + List<Chapter> chaptersFromPodcastIndex = null; + if (playable instanceof FeedMedia) { + FeedMedia feedMedia = (FeedMedia) playable; + if (feedMedia.getItem() == null) { + feedMedia.setItem(DBReader.getFeedItem(feedMedia.getItemId())); + } + if (feedMedia.getItem().hasChapters()) { + chaptersFromDatabase = DBReader.loadChaptersOfFeedItem(feedMedia.getItem()); + } + + if (!TextUtils.isEmpty(feedMedia.getItem().getPodcastIndexChapterUrl())) { + chaptersFromPodcastIndex = ChapterUtils.loadChaptersFromUrl( + feedMedia.getItem().getPodcastIndexChapterUrl(), forceRefresh); + } - if (!TextUtils.isEmpty(feedMedia.getItem().getPodcastIndexChapterUrl())) { - chaptersFromPodcastIndex = ChapterUtils.loadChaptersFromUrl( - feedMedia.getItem().getPodcastIndexChapterUrl(), forceRefresh); } - } - - List<Chapter> chaptersFromMediaFile = ChapterUtils.loadChaptersFromMediaFile(playable, context); - List<Chapter> chaptersMergePhase1 = ChapterMerger.merge(chaptersFromDatabase, chaptersFromMediaFile); - List<Chapter> chapters = ChapterMerger.merge(chaptersMergePhase1, chaptersFromPodcastIndex); - if (chapters == null) { - // Do not try loading again. There are no chapters. - playable.setChapters(Collections.emptyList()); - } else { - playable.setChapters(chapters); + List<Chapter> chaptersFromMediaFile = ChapterUtils.loadChaptersFromMediaFile(playable, context); + List<Chapter> chaptersMergePhase1 = ChapterMerger.merge(chaptersFromDatabase, chaptersFromMediaFile); + List<Chapter> chapters = ChapterMerger.merge(chaptersMergePhase1, chaptersFromPodcastIndex); + if (chapters == null) { + // Do not try loading again. There are no chapters or parsing failed. + playable.setChapters(Collections.emptyList()); + } else { + playable.setChapters(chapters); + } + } catch (InterruptedIOException e) { + Log.d(TAG, "Chapter loading interrupted"); + playable.setChapters(null); // Allow later retry } } - public static List<Chapter> loadChaptersFromMediaFile(Playable playable, Context context) { + public static List<Chapter> loadChaptersFromMediaFile(Playable playable, Context context) + throws InterruptedIOException { try (CountingInputStream in = openStream(playable, context)) { List<Chapter> chapters = readId3ChaptersFrom(in); if (!chapters.isEmpty()) { Log.i(TAG, "Chapters loaded"); return chapters; } + } catch (InterruptedIOException e) { + throw e; } catch (IOException | ID3ReaderException e) { Log.e(TAG, "Unable to load ID3 chapters: " + e.getMessage()); } @@ -106,6 +115,8 @@ public class ChapterUtils { Log.i(TAG, "Chapters loaded"); return chapters; } + } catch (InterruptedIOException e) { + throw e; } catch (IOException | VorbisCommentReaderException e) { Log.e(TAG, "Unable to load vorbis chapters: " + e.getMessage()); } @@ -135,7 +146,7 @@ public class ChapterUtils { } } - public static List<Chapter> loadChaptersFromUrl(String url, boolean forceRefresh) { + public static List<Chapter> loadChaptersFromUrl(String url, boolean forceRefresh) throws InterruptedIOException { if (forceRefresh) { return loadChaptersFromUrl(url, CacheControl.FORCE_NETWORK); } @@ -147,7 +158,8 @@ public class ChapterUtils { return cachedChapters; } - private static List<Chapter> loadChaptersFromUrl(String url, CacheControl cacheControl) { + private static List<Chapter> loadChaptersFromUrl(String url, CacheControl cacheControl) + throws InterruptedIOException { Response response = null; try { Request request = new Request.Builder().url(url).cacheControl(cacheControl).build(); @@ -155,6 +167,8 @@ public class ChapterUtils { if (response.isSuccessful() && response.body() != null) { return PodcastIndexChapterParser.parse(response.body().string()); } + } catch (InterruptedIOException e) { + throw e; } catch (IOException e) { e.printStackTrace(); } finally { |