Work around feeds with broken mime type (#7846)

If a feed has a broken mime type that is not audio or video,
try to still use it as audio (if there is no audio yet).
This might lead to AP trying to play random other files that are not media files,
but it works around publishers messing up their mime types.
This commit is contained in:
ByteHamster 2025-06-25 08:46:30 +02:00 committed by GitHub
parent c3a1f3a98e
commit 5b43cfe5c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 16 deletions

View File

@ -78,7 +78,7 @@ public class Atom extends Namespace {
String href = attributes.getValue(LINK_HREF);
String rel = attributes.getValue(LINK_REL);
SyndElement parent = state.getTagstack().peek();
if (parent.getName().matches(isFeedItem)) {
if (parent.getName().matches(isFeedItem) && state.getCurrentItem() != null) {
if (rel == null || LINK_REL_ALTERNATE.equals(rel)) {
state.getCurrentItem().setLink(href);
} else if (LINK_REL_ENCLOSURE.equals(rel)) {
@ -92,10 +92,15 @@ public class Atom extends Namespace {
Log.d(TAG, "Length attribute could not be parsed.");
}
String mimeType = MimeTypeUtils.getMimeType(attributes.getValue(LINK_TYPE), href);
boolean isValidMedia = MimeTypeUtils.isMediaFile(mimeType);
if (!isValidMedia && state.getCurrentItem().getMedia() == null
&& !MimeTypeUtils.isImageFile(mimeType)) {
isValidMedia = true;
mimeType = "audio/*";
}
FeedItem currItem = state.getCurrentItem();
if (MimeTypeUtils.isMediaFile(mimeType) && currItem != null && !currItem.hasMedia()) {
currItem.setMedia(new FeedMedia(currItem, href, size, mimeType));
if (isValidMedia && !state.getCurrentItem().hasMedia()) {
state.getCurrentItem().setMedia(new FeedMedia(state.getCurrentItem(), href, size, mimeType));
}
} else if (LINK_REL_PAYMENT.equals(rel)) {
state.getCurrentItem().setPaymentLink(href);

View File

@ -41,7 +41,7 @@ public class Media extends Namespace {
@Override
public SyndElement handleElementStart(String localName, HandlerState state,
Attributes attributes) {
if (CONTENT.equals(localName)) {
if (CONTENT.equals(localName) && state.getCurrentItem() != null) {
String url = attributes.getValue(DOWNLOAD_URL);
String defaultStr = attributes.getValue(DEFAULT);
String medium = attributes.getValue(MEDIUM);
@ -61,16 +61,17 @@ public class Media extends Namespace {
// Apparently, some publishers explicitly specify the audio file as an image
validTypeImage = true;
mimeType = "image/*";
} else if (MimeTypeUtils.isMediaFile(mimeType)) {
validTypeMedia = true;
} else if (MimeTypeUtils.isImageFile(mimeType)) {
validTypeImage = true;
} else {
if (MimeTypeUtils.isMediaFile(mimeType)) {
validTypeMedia = true;
} else if (MimeTypeUtils.isImageFile(mimeType)) {
validTypeImage = true;
}
// Workaround for broken feeds
validTypeMedia = state.getCurrentItem().getMedia() == null;
mimeType = "audio/*";
}
if (state.getCurrentItem() != null && (state.getCurrentItem().getMedia() == null || isDefault)
&& url != null && validTypeMedia) {
if ((state.getCurrentItem().getMedia() == null || isDefault) && url != null && validTypeMedia) {
long size = 0;
String sizeStr = attributes.getValue(SIZE);
if (!TextUtils.isEmpty(sizeStr)) {

View File

@ -45,13 +45,17 @@ public class Rss20 extends Namespace {
state.setCurrentItem(new FeedItem());
state.getItems().add(state.getCurrentItem());
state.getCurrentItem().setFeed(state.getFeed());
} else if (ENCLOSURE.equals(localName) && ITEM.equals(state.getTagstack().peek().getName())) {
} else if (ENCLOSURE.equals(localName) && ITEM.equals(state.getTagstack().peek().getName())
&& state.getCurrentItem() != null) {
String url = attributes.getValue(ENC_URL);
String mimeType = MimeTypeUtils.getMimeType(attributes.getValue(ENC_TYPE), url);
boolean isValidMedia = MimeTypeUtils.isMediaFile(mimeType);
if (!isValidMedia && !MimeTypeUtils.isImageFile(mimeType) && state.getCurrentItem().getMedia() == null) {
isValidMedia = true;
mimeType = "audio/*";
}
boolean validUrl = !TextUtils.isEmpty(url);
if (state.getCurrentItem() != null && state.getCurrentItem().getMedia() == null
&& MimeTypeUtils.isMediaFile(mimeType) && validUrl) {
if (state.getCurrentItem().getMedia() == null && isValidMedia && !TextUtils.isEmpty(url)) {
long size = 0;
try {
String sizeStr = attributes.getValue(ENC_LEN);