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 chaptersFromDatabase = null; - List 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 chaptersFromDatabase = null; + List 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 chaptersFromMediaFile = ChapterUtils.loadChaptersFromMediaFile(playable, context); + List chaptersMergePhase1 = ChapterMerger.merge(chaptersFromDatabase, chaptersFromMediaFile); + List 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); } - - } - - List chaptersFromMediaFile = ChapterUtils.loadChaptersFromMediaFile(playable, context); - List chaptersMergePhase1 = ChapterMerger.merge(chaptersFromDatabase, chaptersFromMediaFile); - List 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); + } catch (InterruptedIOException e) { + Log.d(TAG, "Chapter loading interrupted"); + playable.setChapters(null); // Allow later retry } } - public static List loadChaptersFromMediaFile(Playable playable, Context context) { + public static List loadChaptersFromMediaFile(Playable playable, Context context) + throws InterruptedIOException { try (CountingInputStream in = openStream(playable, context)) { List 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 loadChaptersFromUrl(String url, boolean forceRefresh) { + public static List 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 loadChaptersFromUrl(String url, CacheControl cacheControl) { + private static List 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 {