summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2020-02-10 11:29:32 +0100
committerByteHamster <info@bytehamster.com>2020-02-12 17:12:21 +0100
commit9497a97289d7d798a09d3a155b402fc9495693a8 (patch)
treec6e16e90196aef62505038c55566591e368118e8
parenta980281d4794a867e9c972b53c87e6355182a916 (diff)
downloadAntennaPod-9497a97289d7d798a09d3a155b402fc9495693a8.zip
Store embedded chapter information
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java15
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java92
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java21
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;
}