diff options
author | ByteHamster <info@bytehamster.com> | 2020-02-10 11:29:32 +0100 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2020-02-12 17:12:21 +0100 |
commit | 9497a97289d7d798a09d3a155b402fc9495693a8 (patch) | |
tree | c6e16e90196aef62505038c55566591e368118e8 | |
parent | a980281d4794a867e9c972b53c87e6355182a916 (diff) | |
download | AntennaPod-9497a97289d7d798a09d3a155b402fc9495693a8.zip |
Store embedded chapter information
4 files changed, 45 insertions, 86 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java index 2af946c67..08a531d17 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java @@ -2,11 +2,8 @@ package de.danoeh.antennapod.core.feed; import android.database.Cursor; -import android.text.TextUtils; import de.danoeh.antennapod.core.storage.PodDBAdapter; -import java.util.Objects; - public abstract class Chapter extends FeedComponent { /** Defines starting point in milliseconds. */ 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 300e0038a..e69bb2863 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 @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import android.util.Log; +import java.util.zip.CheckedOutputStream; import org.apache.commons.io.IOUtils; import java.io.BufferedInputStream; @@ -23,6 +24,7 @@ import de.danoeh.antennapod.core.util.id3reader.ID3ReaderException; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.vorbiscommentreader.VorbisCommentChapterReader; import de.danoeh.antennapod.core.util.vorbiscommentreader.VorbisCommentReaderException; +import org.apache.commons.io.input.CountingInputStream; /** * Utility class for getting chapter data from media files. @@ -82,13 +84,12 @@ public class ChapterUtils { return; } Log.d(TAG, "Reading id3 chapters from item " + p.getEpisodeTitle()); - InputStream in = null; + CountingInputStream in = null; try { URL url = new URL(p.getStreamUrl()); - - in = url.openStream(); + in = new CountingInputStream(url.openStream()); List<Chapter> chapters = readChaptersFrom(in); - if(!chapters.isEmpty()) { + if (!chapters.isEmpty()) { p.setChapters(chapters); } Log.i(TAG, "Chapters loaded"); @@ -114,9 +115,9 @@ public class ChapterUtils { return; } - InputStream in = null; + CountingInputStream in = null; try { - in = new BufferedInputStream(new FileInputStream(source)); + in = new CountingInputStream(new BufferedInputStream(new FileInputStream(source))); List<Chapter> chapters = readChaptersFrom(in); if (!chapters.isEmpty()) { p.setChapters(chapters); @@ -130,7 +131,7 @@ public class ChapterUtils { } @NonNull - private static List<Chapter> readChaptersFrom(InputStream in) throws IOException, ID3ReaderException { + private static List<Chapter> readChaptersFrom(CountingInputStream in) throws IOException, ID3ReaderException { ChapterReader reader = new ChapterReader(); reader.readInputStream(in); List<Chapter> chapters = reader.getChapters(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java index f7c5bfec7..b007967c1 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java @@ -1,22 +1,17 @@ package de.danoeh.antennapod.core.util.id3reader; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.util.Base64; +import android.text.TextUtils; import android.util.Log; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.ID3Chapter; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.id3reader.model.FrameHeader; import de.danoeh.antennapod.core.util.id3reader.model.TagHeader; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; +import org.apache.commons.io.input.CountingInputStream; public class ChapterReader extends ID3Reader { private static final String TAG = "ID3ChapterReader"; @@ -24,6 +19,8 @@ public class ChapterReader extends ID3Reader { private static final String FRAME_ID_CHAPTER = "CHAP"; private static final String FRAME_ID_TITLE = "TIT2"; private static final String FRAME_ID_LINK = "WXXX"; + private static final String FRAME_ID_PICTURE = "APIC"; + private static final int IMAGE_TYPE_COVER = 3; private List<Chapter> chapters; private ID3Chapter currentChapter; @@ -36,8 +33,7 @@ public class ChapterReader extends ID3Reader { } @Override - public int onStartFrameHeader(FrameHeader header, InputStream input) - throws IOException, ID3ReaderException { + public int onStartFrameHeader(FrameHeader header, CountingInputStream input) throws IOException, ID3ReaderException { Log.d(TAG, "header: " + header); switch (header.getId()) { case FRAME_ID_CHAPTER: @@ -85,57 +81,37 @@ public class ChapterReader extends ID3Reader { return ID3Reader.ACTION_DONT_SKIP; } break; - case "APIC": - Log.d(TAG, header.toString()); - StringBuilder mime = new StringBuilder(); - int read = readString(mime, input, header.getSize()); - byte type = (byte) input.read(); - // $00 Other - // $01 32x32 pixels 'file icon' (PNG only) - // $02 Other file icon - // $03 Cover (front) - // $04 Cover (back) - // $05 Leaflet page - // $06 Media (e.g. label side of CD) - // $07 Lead artist/lead performer/soloist - // $08 Artist/performer - // $09 Conductor - // $0A Band/Orchestra - // $0B Composer - // $0C Lyricist/text writer - // $0D Recording Location - // $0E During recording - // $0F During performance - // $10 Movie/video screen capture - // $11 A bright coloured fish - // $12 Illustration - // $13 Band/artist logotype - // $14 Publisher/Studio logotype - read++; - StringBuilder description = new StringBuilder(); - read += readISOString(description, input, header.getSize()); // Should use encoding from first string - - - Log.d(TAG, "Found apic: " + mime + "," + description); - if (mime.toString().equals("-->")) { - // Data contains a link to a picture - StringBuilder link = new StringBuilder(); - readISOString(link, input, header.getSize()); - Log.d(TAG, "link: " + link); - } else { - // Data contains the picture - byte[] imageData = readBytes(input, header.getSize() - read); - - Bitmap bmp = BitmapFactory.decodeByteArray(imageData, 0, imageData.length); - try (FileOutputStream out = new FileOutputStream(new File(UserPreferences.getDataFolder(null), - "chapter" + chapters.size() + ".jpg"))) { - bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance - // PNG is a lossless format, the compression factor (100) is ignored - } catch (IOException e) { - e.printStackTrace(); + case FRAME_ID_PICTURE: + if (currentChapter != null) { + Log.d(TAG, header.toString()); + StringBuilder mime = new StringBuilder(); + int read = readString(mime, input, header.getSize()); + byte type = (byte) readChars(input, 1)[0]; + read++; + StringBuilder description = new StringBuilder(); + read += readISOString(description, input, header.getSize()); // Should use same encoding as mime + + Log.d(TAG, "Found apic: " + mime + "," + description); + if (mime.toString().equals("-->")) { + // Data contains a link to a picture + StringBuilder link = new StringBuilder(); + readISOString(link, input, header.getSize()); + Log.d(TAG, "link: " + link.toString()); + if (TextUtils.isEmpty(currentChapter.getImageUrl()) || type == IMAGE_TYPE_COVER) { + currentChapter.setImageUrl(link.toString()); + } + } else { + // Data contains the picture + int length = header.getSize() - read; + if (TextUtils.isEmpty(currentChapter.getImageUrl()) || type == IMAGE_TYPE_COVER) { + currentChapter.setImageUrl("embedded-image://" + mime.toString() + + "@" + input.getByteCount() + ":" + length); + } + skipBytes(input, length); } + return ID3Reader.ACTION_DONT_SKIP; } - return ID3Reader.ACTION_DONT_SKIP; + break; } return super.onStartFrameHeader(header, input); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java index 85538d94c..dfc21a5f2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java @@ -9,6 +9,7 @@ import java.nio.charset.Charset; import de.danoeh.antennapod.core.util.id3reader.model.FrameHeader; import de.danoeh.antennapod.core.util.id3reader.model.TagHeader; +import org.apache.commons.io.input.CountingInputStream; /** * Reads the ID3 Tag of a given file. In order to use this class, you should @@ -33,8 +34,7 @@ public class ID3Reader { ID3Reader() { } - public final void readInputStream(InputStream input) throws IOException, - ID3ReaderException { + public final void readInputStream(CountingInputStream input) throws IOException, ID3ReaderException { int rc; readerPosition = 0; char[] tagHeaderSource = readChars(input, HEADER_LENGTH); @@ -101,20 +101,6 @@ public class ID3Reader { return header; } - byte[] readBytes(InputStream input, int number) throws IOException, ID3ReaderException { - byte[] header = new byte[number]; - for (int i = 0; i < number; i++) { - int b = input.read(); - readerPosition++; - if (b != -1) { - header[i] = (byte) b; - } else { - throw new ID3ReaderException("Unexpected end of stream"); - } - } - return header; - } - /** * Skip a certain number of bytes on the given input stream. This method * changes the readerPosition-attribute. @@ -243,8 +229,7 @@ public class ID3Reader { return ACTION_SKIP; } - int onStartFrameHeader(FrameHeader header, InputStream input) - throws IOException, ID3ReaderException { + int onStartFrameHeader(FrameHeader header, CountingInputStream input) throws IOException, ID3ReaderException { return ACTION_SKIP; } |