summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2012-09-22 11:56:50 +0200
committerdaniel oeh <daniel.oeh@gmail.com>2012-09-22 11:56:50 +0200
commit142f3cb9dbd9babae91146d1d972f80b598c59a5 (patch)
treedef4d71f7a18375ec20f1498d92918d0c3cbad5f
parent7bbbeb0382f8c03212b7360d83a6da2988a244d6 (diff)
downloadAntennaPod-142f3cb9dbd9babae91146d1d972f80b598c59a5.zip
Added support for reading chapters from streams
-rw-r--r--src/de/danoeh/antennapod/activity/AudioplayerActivity.java19
-rw-r--r--src/de/danoeh/antennapod/service/PlaybackService.java20
-rw-r--r--src/de/danoeh/antennapod/service/download/DownloadService.java2
-rw-r--r--src/de/danoeh/antennapod/util/ChapterUtils.java72
-rw-r--r--src/de/danoeh/antennapod/util/id3reader/ID3Reader.java30
5 files changed, 129 insertions, 14 deletions
diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
index c469e70f9..8d0b4a0f5 100644
--- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -81,7 +81,13 @@ public class AudioplayerActivity extends MediaplayerActivity {
@Override
protected void loadMediaInfo() {
super.loadMediaInfo();
- if (controller.getMedia() != null) {
+ final FeedMedia media = controller.getMedia();
+ if (media != null) {
+ if (media.getItem().getChapters() != null
+ && pagerAdapter.getCount() < MediaPlayerPagerAdapter.NUM_ITEMS_WITH_CHAPTERS) {
+ pagerAdapter
+ .setNumItems(MediaPlayerPagerAdapter.NUM_ITEMS_WITH_CHAPTERS);
+ }
pagerAdapter.notifyDataSetChanged();
}
}
@@ -96,6 +102,9 @@ public class AudioplayerActivity extends MediaplayerActivity {
private static final int POS_DESCR = 1;
private static final int POS_CHAPTERS = 2;
+ public static final int NUM_ITEMS_WITH_CHAPTERS = 3;
+ public static final int NUM_ITMEMS_WITHOUT_CHAPTERS = 2;
+
public MediaPlayerPagerAdapter(FragmentManager fm, int numItems,
AudioplayerActivity activity) {
super(fm);
@@ -123,8 +132,8 @@ public class AudioplayerActivity extends MediaplayerActivity {
public void onListItemClick(ListView l, View v,
int position, long id) {
super.onListItemClick(l, v, position, id);
- Chapter chapter = (Chapter) this.getListAdapter().getItem(
- position);
+ Chapter chapter = (Chapter) this.getListAdapter()
+ .getItem(position);
controller.seekToChapter(chapter);
}
@@ -161,6 +170,10 @@ public class AudioplayerActivity extends MediaplayerActivity {
return numItems;
}
+ public void setNumItems(int numItems) {
+ this.numItems = numItems;
+ }
+
@Override
public int getItemPosition(Object object) {
return POSITION_UNCHANGED;
diff --git a/src/de/danoeh/antennapod/service/PlaybackService.java b/src/de/danoeh/antennapod/service/PlaybackService.java
index 2a425e9fe..e83912970 100644
--- a/src/de/danoeh/antennapod/service/PlaybackService.java
+++ b/src/de/danoeh/antennapod/service/PlaybackService.java
@@ -46,6 +46,7 @@ import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.feed.SimpleChapter;
import de.danoeh.antennapod.receiver.MediaButtonReceiver;
import de.danoeh.antennapod.receiver.PlayerWidget;
+import de.danoeh.antennapod.util.ChapterUtils;
/** Controls the MediaPlayer that plays a FeedMedia-file */
public class PlaybackService extends Service {
@@ -505,6 +506,23 @@ public class PlaybackService extends Service {
if (startWhenPrepared) {
play();
}
+ if (shouldStream && media.getItem().getChapters() == null) {
+ // load chapters if available
+ Thread chapterLoader = new Thread() {
+
+ @Override
+ public void run() {
+ if (AppConfig.DEBUG) Log.d(TAG, "Starting chapterLoader thread");
+ ChapterUtils.readID3ChaptersFromFeedMediaDownloadUrl(media.getItem());
+ if (media.getItem().getChapters() != null) {
+ sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0);
+ }
+ if (AppConfig.DEBUG) Log.d(TAG, "ChapterLoaderThread has finished");
+ }
+
+ };
+ chapterLoader.start();
+ }
}
};
@@ -961,7 +979,7 @@ public class PlaybackService extends Service {
try {
Thread.sleep(UPDATE_INTERVALL);
waitingTime -= UPDATE_INTERVALL;
-
+
if (waitingTime <= 0) {
if (AppConfig.DEBUG)
Log.d(TAG, "Waiting completed");
diff --git a/src/de/danoeh/antennapod/service/download/DownloadService.java b/src/de/danoeh/antennapod/service/download/DownloadService.java
index 5341c54aa..fae0f3b0f 100644
--- a/src/de/danoeh/antennapod/service/download/DownloadService.java
+++ b/src/de/danoeh/antennapod/service/download/DownloadService.java
@@ -695,7 +695,7 @@ public class DownloadService extends Service {
}
if (media.getItem().getChapters() == null) {
- ChapterUtils.readID3ChaptersFromFeedItem(media.getItem());
+ ChapterUtils.readID3ChaptersFromFeedMediaFileUrl(media.getItem());
if (media.getItem().getChapters() != null) {
chaptersRead = true;
}
diff --git a/src/de/danoeh/antennapod/util/ChapterUtils.java b/src/de/danoeh/antennapod/util/ChapterUtils.java
index dd9dbce5a..65fb6daf2 100644
--- a/src/de/danoeh/antennapod/util/ChapterUtils.java
+++ b/src/de/danoeh/antennapod/util/ChapterUtils.java
@@ -5,6 +5,9 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -25,7 +28,63 @@ public class ChapterUtils {
private ChapterUtils() {
}
- public static void readID3ChaptersFromFeedItem(FeedItem item) {
+ /**
+ * Uses the download URL of a media object of a feeditem to read its ID3
+ * chapters.
+ */
+ public static void readID3ChaptersFromFeedMediaDownloadUrl(FeedItem item) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Reading id3 chapters from item " + item.getTitle());
+ final FeedMedia media = item.getMedia();
+ if (media != null && media.getDownload_url() != null) {
+ InputStream in = null;
+ try {
+ URL url = new URL(media.getDownload_url());
+ ChapterReader reader = new ChapterReader();
+
+ in = url.openStream();
+ reader.readInputStream(in);
+ List<Chapter> chapters = reader.getChapters();
+
+ if (chapters != null) {
+ Collections
+ .sort(chapters, new ChapterStartTimeComparator());
+ processChapters(chapters, item);
+ if (chaptersValid(chapters)) {
+ item.setChapters(chapters);
+ Log.i(TAG, "Chapters loaded");
+ } else {
+ Log.e(TAG, "Chapter data was invalid");
+ }
+ } else {
+ Log.i(TAG, "ChapterReader could not find any ID3 chapters");
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ID3ReaderException e) {
+ e.printStackTrace();
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } else {
+ Log.e(TAG,
+ "Unable to read ID3 chapters: media or download URL was null");
+ }
+ }
+
+ /**
+ * Uses the file URL of a media object of a feeditem to read its ID3
+ * chapters.
+ */
+ public static void readID3ChaptersFromFeedMediaFileUrl(FeedItem item) {
if (AppConfig.DEBUG)
Log.d(TAG, "Reading id3 chapters from item " + item.getTitle());
final FeedMedia media = item.getMedia();
@@ -40,17 +99,20 @@ public class ChapterUtils {
in = new BufferedInputStream(new FileInputStream(source));
reader.readInputStream(in);
List<Chapter> chapters = reader.getChapters();
-
+
if (chapters != null) {
- Collections.sort(chapters, new ChapterStartTimeComparator());
+ Collections.sort(chapters,
+ new ChapterStartTimeComparator());
processChapters(chapters, item);
if (chaptersValid(chapters)) {
item.setChapters(chapters);
+ Log.i(TAG, "Chapters loaded");
} else {
Log.e(TAG, "Chapter data was invalid");
}
} else {
- Log.i(TAG, "ChapterReader could not find any ID3 chapters");
+ Log.i(TAG,
+ "ChapterReader could not find any ID3 chapters");
}
} catch (IOException e) {
e.printStackTrace();
@@ -93,5 +155,5 @@ public class ChapterUtils {
}
return true;
}
-
+
}
diff --git a/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java b/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java
index 8164170bf..7db8dbee5 100644
--- a/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java
+++ b/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java
@@ -43,9 +43,13 @@ public class ID3Reader {
while (readerPosition < tagHeader.getSize()) {
FrameHeader frameHeader = createFrameHeader(readBytes(
input, HEADER_LENGTH));
- rc = onStartFrameHeader(frameHeader, input);
- if (rc == ACTION_SKIP) {
- skipBytes(input, frameHeader.getSize());
+ if (checkForNullString(frameHeader.getId())) {
+ break;
+ } else {
+ rc = onStartFrameHeader(frameHeader, input);
+ if (rc == ACTION_SKIP) {
+ skipBytes(input, frameHeader.getSize());
+ }
}
}
onEndTag();
@@ -53,6 +57,25 @@ public class ID3Reader {
}
}
+ /** Returns true if string only contains null-bytes. */
+ private boolean checkForNullString(String s) {
+ if (!s.isEmpty()) {
+ int i = 0;
+ if (s.charAt(i) == 0) {
+ for (i = 1; i < s.length(); i++) {
+ if (s.charAt(i) != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ } else {
+ return true;
+ }
+
+ }
+
/**
* Read a certain number of bytes from the given input stream. This method
* changes the readerPosition-attribute.
@@ -80,7 +103,6 @@ public class ID3Reader {
int skipped = 0;
while (skipped < number) {
skipped += input.skip(number - skipped);
- System.out.println("Skipped = " + skipped);
}
readerPosition += number;