MediaHandler now reads id3 chapters
This commit is contained in:
parent
0eb841db4b
commit
48292609f6
@ -17,6 +17,7 @@ import com.viewpagerindicator.TabPageIndicator;
|
|||||||
import de.danoeh.antennapod.AppConfig;
|
import de.danoeh.antennapod.AppConfig;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.adapter.ChapterListAdapter;
|
import de.danoeh.antennapod.adapter.ChapterListAdapter;
|
||||||
|
import de.danoeh.antennapod.feed.Chapter;
|
||||||
import de.danoeh.antennapod.feed.FeedMedia;
|
import de.danoeh.antennapod.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.feed.SimpleChapter;
|
import de.danoeh.antennapod.feed.SimpleChapter;
|
||||||
import de.danoeh.antennapod.fragment.CoverFragment;
|
import de.danoeh.antennapod.fragment.CoverFragment;
|
||||||
@ -85,8 +86,7 @@ public class AudioplayerActivity extends MediaplayerActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MediaPlayerPagerAdapter extends
|
public class MediaPlayerPagerAdapter extends FragmentStatePagerAdapter {
|
||||||
FragmentStatePagerAdapter {
|
|
||||||
private int numItems;
|
private int numItems;
|
||||||
private AudioplayerActivity activity;
|
private AudioplayerActivity activity;
|
||||||
|
|
||||||
@ -109,8 +109,8 @@ public class AudioplayerActivity extends MediaplayerActivity {
|
|||||||
if (media != null) {
|
if (media != null) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case POS_COVER:
|
case POS_COVER:
|
||||||
activity.coverFragment = CoverFragment
|
activity.coverFragment = CoverFragment.newInstance(media
|
||||||
.newInstance(media.getItem());
|
.getItem());
|
||||||
return activity.coverFragment;
|
return activity.coverFragment;
|
||||||
case POS_DESCR:
|
case POS_DESCR:
|
||||||
activity.descriptionFragment = ItemDescriptionFragment
|
activity.descriptionFragment = ItemDescriptionFragment
|
||||||
@ -123,16 +123,15 @@ public class AudioplayerActivity extends MediaplayerActivity {
|
|||||||
public void onListItemClick(ListView l, View v,
|
public void onListItemClick(ListView l, View v,
|
||||||
int position, long id) {
|
int position, long id) {
|
||||||
super.onListItemClick(l, v, position, id);
|
super.onListItemClick(l, v, position, id);
|
||||||
SimpleChapter chapter = (SimpleChapter) this
|
Chapter chapter = (Chapter) this.getListAdapter().getItem(
|
||||||
.getListAdapter().getItem(position);
|
position);
|
||||||
controller.seekToChapter(chapter);
|
controller.seekToChapter(chapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sCChapterFragment.setListAdapter(new ChapterListAdapter(
|
sCChapterFragment.setListAdapter(new ChapterListAdapter(
|
||||||
activity, 0, media.getItem()
|
activity, 0, media.getItem().getChapters()));
|
||||||
.getChapters()));
|
|
||||||
|
|
||||||
return sCChapterFragment;
|
return sCChapterFragment;
|
||||||
default:
|
default:
|
||||||
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.feed;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data Object for a XML message
|
* Data Object for a XML message
|
||||||
@ -22,7 +23,7 @@ public class FeedItem extends FeedComponent {
|
|||||||
private Feed feed;
|
private Feed feed;
|
||||||
protected boolean read;
|
protected boolean read;
|
||||||
private String paymentLink;
|
private String paymentLink;
|
||||||
private ArrayList<Chapter> chapters;
|
private List<Chapter> chapters;
|
||||||
|
|
||||||
public FeedItem() {
|
public FeedItem() {
|
||||||
this.read = true;
|
this.read = true;
|
||||||
@ -144,11 +145,11 @@ public class FeedItem extends FeedComponent {
|
|||||||
this.paymentLink = paymentLink;
|
this.paymentLink = paymentLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Chapter> getChapters() {
|
public List<Chapter> getChapters() {
|
||||||
return chapters;
|
return chapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChapters(ArrayList<Chapter> chapters) {
|
public void setChapters(List<Chapter> chapters) {
|
||||||
this.chapters = chapters;
|
this.chapters = chapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ import de.danoeh.antennapod.PodcastApp;
|
|||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.AudioplayerActivity;
|
import de.danoeh.antennapod.activity.AudioplayerActivity;
|
||||||
import de.danoeh.antennapod.activity.VideoplayerActivity;
|
import de.danoeh.antennapod.activity.VideoplayerActivity;
|
||||||
|
import de.danoeh.antennapod.feed.Chapter;
|
||||||
import de.danoeh.antennapod.feed.Feed;
|
import de.danoeh.antennapod.feed.Feed;
|
||||||
import de.danoeh.antennapod.feed.FeedItem;
|
import de.danoeh.antennapod.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.feed.FeedManager;
|
import de.danoeh.antennapod.feed.FeedManager;
|
||||||
@ -761,7 +762,7 @@ public class PlaybackService extends Service {
|
|||||||
saveCurrentPosition();
|
saveCurrentPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seekToChapter(SimpleChapter chapter) {
|
public void seekToChapter(Chapter chapter) {
|
||||||
seek((int) chapter.getStart());
|
seek((int) chapter.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ import de.danoeh.antennapod.feed.FeedMedia;
|
|||||||
import de.danoeh.antennapod.storage.DownloadRequester;
|
import de.danoeh.antennapod.storage.DownloadRequester;
|
||||||
import de.danoeh.antennapod.syndication.handler.FeedHandler;
|
import de.danoeh.antennapod.syndication.handler.FeedHandler;
|
||||||
import de.danoeh.antennapod.syndication.handler.UnsupportedFeedtypeException;
|
import de.danoeh.antennapod.syndication.handler.UnsupportedFeedtypeException;
|
||||||
|
import de.danoeh.antennapod.util.ChapterUtils;
|
||||||
import de.danoeh.antennapod.util.DownloadError;
|
import de.danoeh.antennapod.util.DownloadError;
|
||||||
import de.danoeh.antennapod.util.InvalidFeedException;
|
import de.danoeh.antennapod.util.InvalidFeedException;
|
||||||
|
|
||||||
@ -427,7 +428,7 @@ public class DownloadService extends Service {
|
|||||||
createReport = true;
|
createReport = true;
|
||||||
}
|
}
|
||||||
successfulDownloads++;
|
successfulDownloads++;
|
||||||
} else if (!status.isCancelled()){
|
} else if (!status.isCancelled()) {
|
||||||
if (status.getFeedFile().getClass() != FeedImage.class) {
|
if (status.getFeedFile().getClass() != FeedImage.class) {
|
||||||
createReport = true;
|
createReport = true;
|
||||||
}
|
}
|
||||||
@ -675,6 +676,8 @@ public class DownloadService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
boolean chaptersRead = false;
|
||||||
|
|
||||||
media.setDownloaded(true);
|
media.setDownloaded(true);
|
||||||
// Get duration
|
// Get duration
|
||||||
MediaPlayer mediaplayer = new MediaPlayer();
|
MediaPlayer mediaplayer = new MediaPlayer();
|
||||||
@ -691,9 +694,20 @@ public class DownloadService extends Service {
|
|||||||
mediaplayer.release();
|
mediaplayer.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (media.getItem().getChapters() == null) {
|
||||||
|
ChapterUtils.readID3ChaptersFromFeedItem(media.getItem());
|
||||||
|
if (media.getItem().getChapters() != null) {
|
||||||
|
chaptersRead = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
saveDownloadStatus(status);
|
saveDownloadStatus(status);
|
||||||
sendDownloadHandledIntent(DOWNLOAD_TYPE_MEDIA);
|
sendDownloadHandledIntent(DOWNLOAD_TYPE_MEDIA);
|
||||||
|
if (chaptersRead) {
|
||||||
|
manager.setFeedItem(DownloadService.this, media.getItem());
|
||||||
|
} else {
|
||||||
manager.setFeedMedia(DownloadService.this, media);
|
manager.setFeedMedia(DownloadService.this, media);
|
||||||
|
}
|
||||||
|
|
||||||
downloadsBeingHandled -= 1;
|
downloadsBeingHandled -= 1;
|
||||||
queryDownloads();
|
queryDownloads();
|
||||||
|
@ -342,12 +342,12 @@ public class PodDBAdapter {
|
|||||||
new String[] { String.valueOf(item.getId()) });
|
new String[] { String.valueOf(item.getId()) });
|
||||||
}
|
}
|
||||||
if (item.getChapters() != null) {
|
if (item.getChapters() != null) {
|
||||||
setSimpleChapters(item);
|
setChapters(item);
|
||||||
}
|
}
|
||||||
return item.getId();
|
return item.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSimpleChapters(FeedItem item) {
|
public void setChapters(FeedItem item) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
for (Chapter chapter : item.getChapters()) {
|
for (Chapter chapter : item.getChapters()) {
|
||||||
values.put(KEY_TITLE, chapter.getTitle());
|
values.put(KEY_TITLE, chapter.getTitle());
|
||||||
|
97
src/de/danoeh/antennapod/util/ChapterUtils.java
Normal file
97
src/de/danoeh/antennapod/util/ChapterUtils.java
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package de.danoeh.antennapod.util;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import de.danoeh.antennapod.AppConfig;
|
||||||
|
import de.danoeh.antennapod.feed.Chapter;
|
||||||
|
import de.danoeh.antennapod.feed.FeedItem;
|
||||||
|
import de.danoeh.antennapod.feed.FeedMedia;
|
||||||
|
import de.danoeh.antennapod.util.comparator.ChapterStartTimeComparator;
|
||||||
|
import de.danoeh.antennapod.util.id3reader.ChapterReader;
|
||||||
|
import de.danoeh.antennapod.util.id3reader.ID3ReaderException;
|
||||||
|
|
||||||
|
/** Utility class for getting chapter data from media files. */
|
||||||
|
public class ChapterUtils {
|
||||||
|
private static final String TAG = "ChapterUtils";
|
||||||
|
|
||||||
|
private ChapterUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void readID3ChaptersFromFeedItem(FeedItem item) {
|
||||||
|
if (AppConfig.DEBUG)
|
||||||
|
Log.d(TAG, "Reading id3 chapters from item " + item.getTitle());
|
||||||
|
final FeedMedia media = item.getMedia();
|
||||||
|
if (media != null && media.isDownloaded()
|
||||||
|
&& media.getFile_url() != null) {
|
||||||
|
File source = new File(media.getFile_url());
|
||||||
|
if (source.exists()) {
|
||||||
|
ChapterReader reader = new ChapterReader();
|
||||||
|
InputStream in = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
in = new BufferedInputStream(new FileInputStream(source));
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Chapter data was invalid");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "ChapterReader could not find any ID3 chapters");
|
||||||
|
}
|
||||||
|
} 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: Source doesn't exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Makes sure that chapter does a title and an item attribute. */
|
||||||
|
private static void processChapters(List<Chapter> chapters, FeedItem item) {
|
||||||
|
for (int i = 0; i < chapters.size(); i++) {
|
||||||
|
Chapter c = chapters.get(i);
|
||||||
|
if (c.getTitle() == null) {
|
||||||
|
c.setTitle(Integer.toString(i));
|
||||||
|
}
|
||||||
|
c.setItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean chaptersValid(List<Chapter> chapters) {
|
||||||
|
for (Chapter c : chapters) {
|
||||||
|
if (c.getTitle() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.getStart() < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,6 +26,7 @@ import android.widget.TextView;
|
|||||||
import de.danoeh.antennapod.AppConfig;
|
import de.danoeh.antennapod.AppConfig;
|
||||||
import de.danoeh.antennapod.PodcastApp;
|
import de.danoeh.antennapod.PodcastApp;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.feed.Chapter;
|
||||||
import de.danoeh.antennapod.feed.FeedMedia;
|
import de.danoeh.antennapod.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.feed.SimpleChapter;
|
import de.danoeh.antennapod.feed.SimpleChapter;
|
||||||
import de.danoeh.antennapod.service.PlaybackService;
|
import de.danoeh.antennapod.service.PlaybackService;
|
||||||
@ -549,7 +550,7 @@ public abstract class PlaybackController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seekToChapter(SimpleChapter chapter) {
|
public void seekToChapter(Chapter chapter) {
|
||||||
if (playbackService != null) {
|
if (playbackService != null) {
|
||||||
playbackService.seekToChapter(chapter);
|
playbackService.seekToChapter(chapter);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package de.danoeh.antennapod.util.comparator;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.feed.Chapter;
|
||||||
|
|
||||||
|
public class ChapterStartTimeComparator implements Comparator<Chapter> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Chapter lhs, Chapter rhs) {
|
||||||
|
if (lhs.getStart() == rhs.getStart()) {
|
||||||
|
return 0;
|
||||||
|
} else if (lhs.getStart() < rhs.getStart()) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,6 +5,7 @@ import java.io.InputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.feed.Chapter;
|
||||||
import de.danoeh.antennapod.feed.ID3Chapter;
|
import de.danoeh.antennapod.feed.ID3Chapter;
|
||||||
import de.danoeh.antennapod.util.id3reader.model.FrameHeader;
|
import de.danoeh.antennapod.util.id3reader.model.FrameHeader;
|
||||||
import de.danoeh.antennapod.util.id3reader.model.TagHeader;
|
import de.danoeh.antennapod.util.id3reader.model.TagHeader;
|
||||||
@ -14,12 +15,12 @@ public class ChapterReader extends ID3Reader {
|
|||||||
private static final String FRAME_ID_CHAPTER = "CHAP";
|
private static final String FRAME_ID_CHAPTER = "CHAP";
|
||||||
private static final String FRAME_ID_TITLE = "TIT2";
|
private static final String FRAME_ID_TITLE = "TIT2";
|
||||||
|
|
||||||
private List<ID3Chapter> chapters;
|
private List<Chapter> chapters;
|
||||||
private ID3Chapter currentChapter;
|
private ID3Chapter currentChapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartTagHeader(TagHeader header) {
|
public int onStartTagHeader(TagHeader header) {
|
||||||
chapters = new ArrayList<ID3Chapter>();
|
chapters = new ArrayList<Chapter>();
|
||||||
System.out.println(header.toString());
|
System.out.println(header.toString());
|
||||||
return ID3Reader.ACTION_DONT_SKIP;
|
return ID3Reader.ACTION_DONT_SKIP;
|
||||||
}
|
}
|
||||||
@ -58,8 +59,8 @@ public class ChapterReader extends ID3Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasId3Chapter(ID3Chapter chapter) {
|
private boolean hasId3Chapter(ID3Chapter chapter) {
|
||||||
for (ID3Chapter c : chapters) {
|
for (Chapter c : chapters) {
|
||||||
if (c.getId3ID().equals(chapter.getId3ID())) {
|
if (((ID3Chapter) c).getId3ID().equals(chapter.getId3ID())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ public class ChapterReader extends ID3Reader {
|
|||||||
}
|
}
|
||||||
System.out.println("Reached end of tag");
|
System.out.println("Reached end of tag");
|
||||||
if (chapters != null) {
|
if (chapters != null) {
|
||||||
for (ID3Chapter c : chapters) {
|
for (Chapter c : chapters) {
|
||||||
System.out.println(c.toString());
|
System.out.println(c.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,4 +88,8 @@ public class ChapterReader extends ID3Reader {
|
|||||||
super.onNoTagHeaderFound();
|
super.onNoTagHeaderFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Chapter> getChapters() {
|
||||||
|
return chapters;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user