Extractor is now able to detect if a video is blocked by country

This commit is contained in:
Ramon M 2017-05-27 14:23:48 +02:00
parent cd81998705
commit 306f836087
3 changed files with 48 additions and 13 deletions

View File

@ -260,7 +260,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
Parser.matchGroup1("ytplayer.config\\s*=\\s*(\\{.*?\\});", pageContent); Parser.matchGroup1("ytplayer.config\\s*=\\s*(\\{.*?\\});", pageContent);
return new JSONObject(ytPlayerConfigRaw); return new JSONObject(ytPlayerConfigRaw);
} catch (Parser.RegexException e) { } catch (Parser.RegexException e) {
String errorReason = findErrorReason(doc); String errorReason = getErrorMessage();
switch(errorReason) { switch(errorReason) {
case "GEMA": case "GEMA":
throw new GemaException(errorReason); throw new GemaException(errorReason);
@ -948,15 +948,28 @@ public class YoutubeStreamExtractor extends StreamExtractor {
return result == null ? "" : result.toString(); return result == null ? "" : result.toString();
} }
private String findErrorReason(Document doc) {
/**
* {@inheritDoc}
*/
public String getErrorMessage() {
String errorMessage = doc.select("h1[id=\"unavailable-message\"]").first().text(); String errorMessage = doc.select("h1[id=\"unavailable-message\"]").first().text();
if(errorMessage.contains("GEMA")) { StringBuilder errorReason;
if (errorMessage == null || errorMessage.isEmpty()) {
errorReason = null;
} else if(errorMessage.contains("GEMA")) {
// Gema sometimes blocks youtube music content in germany: // Gema sometimes blocks youtube music content in germany:
// https://www.gema.de/en/ // https://www.gema.de/en/
// Detailed description: // Detailed description:
// https://en.wikipedia.org/wiki/GEMA_%28German_organization%29 // https://en.wikipedia.org/wiki/GEMA_%28German_organization%29
return "GEMA"; errorReason = new StringBuilder("GEMA");
} else {
errorReason = new StringBuilder(errorMessage);
errorReason.append(" ");
errorReason.append(doc.select("[id=\"unavailable-submessage\"]").first().text());
} }
return "";
return errorReason != null ? errorReason.toString() : null;
} }
} }

View File

@ -49,7 +49,7 @@ public abstract class StreamExtractor {
} }
} }
public class ContentNotAvailableException extends ParsingException { public static class ContentNotAvailableException extends ParsingException {
public ContentNotAvailableException(String message) { public ContentNotAvailableException(String message) {
super(message); super(message);
} }
@ -101,4 +101,11 @@ public abstract class StreamExtractor {
public int getServiceId() { public int getServiceId() {
return serviceId; return serviceId;
} }
/**
* Analyses the webpage's document and extracts any error message there might be.
*
* @return Error message; null if there is no error message.
*/
public abstract String getErrorMessage();
} }

View File

@ -74,19 +74,34 @@ public class StreamInfo extends AbstractStreamInfo {
/**Fills out the video info fields which are common to all services. /**Fills out the video info fields which are common to all services.
* Probably needs to be overridden by subclasses*/ * Probably needs to be overridden by subclasses*/
public static StreamInfo getVideoInfo(StreamExtractor extractor) public static StreamInfo getVideoInfo(StreamExtractor extractor)
throws ExtractionException, IOException { throws ExtractionException, StreamExtractor.ContentNotAvailableException {
StreamInfo streamInfo = new StreamInfo(); StreamInfo streamInfo = new StreamInfo();
try {
streamInfo = extractImportantData(streamInfo, extractor); streamInfo = extractImportantData(streamInfo, extractor);
streamInfo = extractStreams(streamInfo, extractor); streamInfo = extractStreams(streamInfo, extractor);
streamInfo = extractOptionalData(streamInfo, extractor); streamInfo = extractOptionalData(streamInfo, extractor);
} catch (ExtractionException e) {
// Currently YouTube does not distinguish between age restricted videos and videos blocked
// by country. This means that during the initialisation of the extractor, the extractor
// will assume that a video is age restricted while in reality it it blocked by country.
//
// We will now detect whether the video is blocked by country or not.
String errorMsg = extractor.getErrorMessage();
if (errorMsg != null) {
throw new StreamExtractor.ContentNotAvailableException(errorMsg);
} else {
throw e;
}
}
return streamInfo; return streamInfo;
} }
private static StreamInfo extractImportantData( private static StreamInfo extractImportantData(
StreamInfo streamInfo, StreamExtractor extractor) StreamInfo streamInfo, StreamExtractor extractor)
throws ExtractionException, IOException { throws ExtractionException {
/* ---- important data, withoug the video can't be displayed goes here: ---- */ /* ---- important data, withoug the video can't be displayed goes here: ---- */
// if one of these is not available an exception is meant to be thrown directly into the frontend. // if one of these is not available an exception is meant to be thrown directly into the frontend.
@ -112,7 +127,7 @@ public class StreamInfo extends AbstractStreamInfo {
private static StreamInfo extractStreams( private static StreamInfo extractStreams(
StreamInfo streamInfo, StreamExtractor extractor) StreamInfo streamInfo, StreamExtractor extractor)
throws ExtractionException, IOException { throws ExtractionException {
/* ---- stream extraction goes here ---- */ /* ---- stream extraction goes here ---- */
// At least one type of stream has to be available, // At least one type of stream has to be available,
// otherwise an exception will be thrown directly into the frontend. // otherwise an exception will be thrown directly into the frontend.