Code refactoring

* Add getters
 * Add javadoc
 * Use Mediaformat instead of the id of media format
This commit is contained in:
Coffeemakr 2017-11-11 01:21:43 +01:00
parent 98358cb0f9
commit e11c6e35f6
No known key found for this signature in database
GPG Key ID: 3F35676D8FF6E743
13 changed files with 322 additions and 32 deletions

View File

@ -23,25 +23,44 @@ package org.schabi.newpipe.extractor;
import java.io.Serializable; import java.io.Serializable;
public abstract class InfoItem implements Serializable { public abstract class InfoItem implements Serializable {
public enum InfoType {
STREAM,
PLAYLIST,
CHANNEL
}
public final InfoType info_type; public final InfoType info_type;
public InfoItem(InfoType infoType) {
this.info_type = infoType;
}
public int service_id = -1; public int service_id = -1;
public String url; public String url;
public String name; public String name;
public String thumbnail_url; public String thumbnail_url;
public InfoItem(InfoType infoType) {
this.info_type = infoType;
}
public InfoType getInfoType() {
return info_type;
}
public int getServiceId() {
return service_id;
}
public String getUrl() {
return url;
}
public String getName() {
return name;
}
public String getThumbnailUrl() {
return thumbnail_url;
}
@Override @Override
public String toString() { public String toString() {
return getClass().getSimpleName() + "[url=\"" + url + "\", name=\"" + name + "\"]"; return getClass().getSimpleName() + "[url=\"" + url + "\", name=\"" + name + "\"]";
} }
public enum InfoType {
STREAM,
PLAYLIST,
CHANNEL
}
} }

View File

@ -23,7 +23,7 @@ package org.schabi.newpipe.extractor;
*/ */
/** /**
* Static data about various media formats support by Newpipe, eg mime type, extension * Static data about various media formats support by NewPipe, eg mime type, extension
*/ */
public enum MediaFormat { public enum MediaFormat {
@ -103,4 +103,40 @@ public enum MediaFormat {
} }
return null; return null;
} }
/**
* Get the media format by it's id.
* @param id the id
* @return the id of the media format or null.
*/
public static MediaFormat getFormatById(int id) {
for (MediaFormat vf: values()) {
if (vf.id == id) return vf;
}
return null;
}
/**
* Get the name of the format
* @return the name of the format
*/
public String getName() {
return name;
}
/**
* Get the filename extension
* @return the filename extension
*/
public String getSuffix() {
return suffix;
}
/**
* Get the mime type
* @return the mime type
*/
public String getMimeType() {
return mimeType;
}
} }

View File

@ -129,7 +129,7 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
String mp3Url = responseObject.getString("http_mp3_128_url"); String mp3Url = responseObject.getString("http_mp3_128_url");
if (mp3Url != null && !mp3Url.isEmpty()) { if (mp3Url != null && !mp3Url.isEmpty()) {
audioStreams.add(new AudioStream(mp3Url, MediaFormat.MP3.id, 128)); audioStreams.add(new AudioStream(mp3Url, MediaFormat.MP3, 128));
} else { } else {
throw new ExtractionException("Could not get SoundCloud's track audio url"); throw new ExtractionException("Could not get SoundCloud's track audio url");
} }

View File

@ -76,7 +76,6 @@ public class ItagItem {
new ItagItem(313, VIDEO_ONLY, WEBM, "2160p"), new ItagItem(313, VIDEO_ONLY, WEBM, "2160p"),
new ItagItem(315, VIDEO_ONLY, WEBM, "2160p60", 60) new ItagItem(315, VIDEO_ONLY, WEBM, "2160p60", 60)
}; };
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Utils // Utils
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@ -115,7 +114,7 @@ public class ItagItem {
public ItagItem(int id, ItagType type, MediaFormat format, String resolution) { public ItagItem(int id, ItagType type, MediaFormat format, String resolution) {
this.id = id; this.id = id;
this.itagType = type; this.itagType = type;
this.mediaFormatId = format.id; this.mediaFormat = format;
this.resolutionString = resolution; this.resolutionString = resolution;
this.fps = 30; this.fps = 30;
} }
@ -128,7 +127,7 @@ public class ItagItem {
public ItagItem(int id, ItagType type, MediaFormat format, String resolution, int fps) { public ItagItem(int id, ItagType type, MediaFormat format, String resolution, int fps) {
this.id = id; this.id = id;
this.itagType = type; this.itagType = type;
this.mediaFormatId = format.id; this.mediaFormat = format;
this.resolutionString = resolution; this.resolutionString = resolution;
this.fps = fps; this.fps = fps;
} }
@ -136,13 +135,19 @@ public class ItagItem {
public ItagItem(int id, ItagType type, MediaFormat format, int avgBitrate) { public ItagItem(int id, ItagType type, MediaFormat format, int avgBitrate) {
this.id = id; this.id = id;
this.itagType = type; this.itagType = type;
this.mediaFormatId = format.id; this.mediaFormat = format;
this.avgBitrate = avgBitrate; this.avgBitrate = avgBitrate;
} }
private final MediaFormat mediaFormat;
public MediaFormat getMediaFormat() {
return mediaFormat;
}
public int id; public int id;
public ItagType itagType; public ItagType itagType;
public int mediaFormatId;
// Audio fields // Audio fields
public int avgBitrate = -1; public int avgBitrate = -1;

View File

@ -223,7 +223,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
try { try {
likesString = button.select("span.yt-uix-button-content").first().text(); likesString = button.select("span.yt-uix-button-content").first().text();
} catch (NullPointerException e) { } catch (NullPointerException e) {
//if this ckicks in our button has no content and thefore likes/dislikes are disabled //if this kicks in our button has no content and therefore likes/dislikes are disabled
return -1; return -1;
} }
return Integer.parseInt(Utils.removeNonDigitCharacters(likesString)); return Integer.parseInt(Utils.removeNonDigitCharacters(likesString));
@ -329,7 +329,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
for (Map.Entry<String, ItagItem> entry : getItags(ADAPTIVE_FMTS, ItagItem.ItagType.AUDIO).entrySet()) { for (Map.Entry<String, ItagItem> entry : getItags(ADAPTIVE_FMTS, ItagItem.ItagType.AUDIO).entrySet()) {
ItagItem itag = entry.getValue(); ItagItem itag = entry.getValue();
AudioStream audioStream = new AudioStream(entry.getKey(), itag.mediaFormatId, itag.avgBitrate); AudioStream audioStream = new AudioStream(entry.getKey(), itag.getMediaFormat(), itag.avgBitrate);
if (!Stream.containSimilarStream(audioStream, audioStreams)) { if (!Stream.containSimilarStream(audioStream, audioStreams)) {
audioStreams.add(audioStream); audioStreams.add(audioStream);
} }
@ -348,7 +348,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
for (Map.Entry<String, ItagItem> entry : getItags(URL_ENCODED_FMT_STREAM_MAP, ItagItem.ItagType.VIDEO).entrySet()) { for (Map.Entry<String, ItagItem> entry : getItags(URL_ENCODED_FMT_STREAM_MAP, ItagItem.ItagType.VIDEO).entrySet()) {
ItagItem itag = entry.getValue(); ItagItem itag = entry.getValue();
VideoStream videoStream = new VideoStream(entry.getKey(), itag.mediaFormatId, itag.resolutionString); VideoStream videoStream = new VideoStream(entry.getKey(), itag.getMediaFormat(), itag.resolutionString);
if (!Stream.containSimilarStream(videoStream, videoStreams)) { if (!Stream.containSimilarStream(videoStream, videoStreams)) {
videoStreams.add(videoStream); videoStreams.add(videoStream);
} }
@ -367,7 +367,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
for (Map.Entry<String, ItagItem> entry : getItags(ADAPTIVE_FMTS, ItagItem.ItagType.VIDEO_ONLY).entrySet()) { for (Map.Entry<String, ItagItem> entry : getItags(ADAPTIVE_FMTS, ItagItem.ItagType.VIDEO_ONLY).entrySet()) {
ItagItem itag = entry.getValue(); ItagItem itag = entry.getValue();
VideoStream videoStream = new VideoStream(entry.getKey(), itag.mediaFormatId, itag.resolutionString, true); VideoStream videoStream = new VideoStream(entry.getKey(), itag.getMediaFormat(), itag.resolutionString, true);
if (!Stream.containSimilarStream(videoStream, videoOnlyStreams)) { if (!Stream.containSimilarStream(videoStream, videoOnlyStreams)) {
videoOnlyStreams.add(videoStream); videoOnlyStreams.add(videoStream);
} }

View File

@ -20,10 +20,30 @@ package org.schabi.newpipe.extractor.stream;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>. * along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/ */
import org.schabi.newpipe.extractor.MediaFormat;
public class AudioStream extends Stream { public class AudioStream extends Stream {
public int average_bitrate = -1; public int average_bitrate = -1;
/**
* Create a new audio stream
* @param url the url
* @param format the id of the format
* @param averageBitrate the average bit rate
* @deprecated use {@link AudioStream#AudioStream(String, MediaFormat, int)} instead
*/
@Deprecated
public AudioStream(String url, int format, int averageBitrate) { public AudioStream(String url, int format, int averageBitrate) {
this(url, MediaFormat.getFormatById(format), averageBitrate);
}
/**
* Create a new audio stream
* @param url the url
* @param format the format
* @param averageBitrate the average bitrate
*/
public AudioStream(String url, MediaFormat format, int averageBitrate) {
super(url, format); super(url, format);
this.average_bitrate = averageBitrate; this.average_bitrate = averageBitrate;
} }
@ -33,4 +53,12 @@ public class AudioStream extends Stream {
return super.equalStats(cmp) && cmp instanceof AudioStream && return super.equalStats(cmp) && cmp instanceof AudioStream &&
average_bitrate == ((AudioStream) cmp).average_bitrate; average_bitrate == ((AudioStream) cmp).average_bitrate;
} }
/**
* Get the average bitrate
* @return the average bitrate or -1
*/
public int getAverageBitrate() {
return average_bitrate;
}
} }

View File

@ -1,15 +1,19 @@
package org.schabi.newpipe.extractor.stream; package org.schabi.newpipe.extractor.stream;
import org.schabi.newpipe.extractor.MediaFormat;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
public abstract class Stream implements Serializable { public abstract class Stream implements Serializable {
private final MediaFormat mediaFormat;
public String url; public String url;
public int format = -1; public int format = -1;
public Stream(String url, int format) { public Stream(String url, MediaFormat format) {
this.url = url; this.url = url;
this.format = format; this.format = format.id;
this.mediaFormat = format;
} }
/** /**
@ -36,4 +40,12 @@ public abstract class Stream implements Serializable {
} }
return false; return false;
} }
public String getUrl() {
return url;
}
public MediaFormat getFormat() {
return mediaFormat;
}
} }

View File

@ -35,6 +35,102 @@ import java.util.List;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class StreamInfo extends Info { public class StreamInfo extends Info {
/**
* Get the stream type
* @return the stream type
*/
public StreamType getStreamType() {
return stream_type;
}
/**
* Get the thumbnail url
* @return the thumbnail url as a string
*/
public String getThumbnailUrl() {
return thumbnail_url;
}
public String getUploadDate() {
return upload_date;
}
/**
* Get the duration in seconds
* @return the duration in seconds
*/
public long getDuration() {
return duration;
}
public int getAgeLimit() {
return age_limit;
}
public String getDescription() {
return description;
}
public long getViewCount() {
return view_count;
}
/**
* Get the number of likes.
* @return The number of likes or -1 if this information is not available
*/
public long getLikeCount() {
return like_count;
}
/**
* Get the number of dislikes.
* @return The number of likes or -1 if this information is not available
*/
public long getDislikeCount() {
return dislike_count;
}
public String getUploaderName() {
return uploader_name;
}
public String getUploaderUrl() {
return uploader_url;
}
public String getUploaderAvatarUrl() {
return uploader_avatar_url;
}
public List<VideoStream> getVideoStreams() {
return video_streams;
}
public List<AudioStream> getAudioStreams() {
return audio_streams;
}
public List<VideoStream> getVideoOnlyStreams() {
return video_only_streams;
}
public String getDashMpdUrl() {
return dashMpdUrl;
}
public StreamInfoItem getNextVideo() {
return next_video;
}
public List<InfoItem> getRelatedStreams() {
return related_streams;
}
public long getStartPosition() {
return start_position;
}
public static class StreamExtractException extends ExtractionException { public static class StreamExtractException extends ExtractionException {
StreamExtractException(String message) { StreamExtractException(String message) {
super(message); super(message);
@ -86,7 +182,7 @@ public class StreamInfo extends Info {
} }
private static StreamInfo extractImportantData(StreamInfo streamInfo, StreamExtractor extractor) throws ExtractionException { private static StreamInfo extractImportantData(StreamInfo streamInfo, StreamExtractor extractor) throws ExtractionException {
/* ---- important data, withoug the video can't be displayed goes here: ---- */ /* ---- important data, without 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.
streamInfo.service_id = extractor.getServiceId(); streamInfo.service_id = extractor.getServiceId();
@ -271,9 +367,9 @@ public class StreamInfo extends Info {
public List<AudioStream> audio_streams; public List<AudioStream> audio_streams;
public List<VideoStream> video_only_streams; public List<VideoStream> video_only_streams;
// video streams provided by the dash mpd do not need to be provided as VideoStream. // video streams provided by the dash mpd do not need to be provided as VideoStream.
// Later on this will also aplly to audio streams. Since dash mpd is standarized, // Later on this will also apply to audio streams. Since dash mpd is standarized,
// crawling such a file is not service dependent. Therefore getting audio only streams by yust // crawling such a file is not service dependent. Therefore getting audio only streams by yust
// providing the dash mpd fille will be possible in the future. // providing the dash mpd file will be possible in the future.
public String dashMpdUrl; public String dashMpdUrl;
public StreamInfoItem next_video; public StreamInfoItem next_video;

View File

@ -46,4 +46,24 @@ public class StreamInfoItem extends InfoItem {
public String getUploaderUrl() { public String getUploaderUrl() {
return uploaderUrl; return uploaderUrl;
} }
public StreamType getStreamType() {
return stream_type;
}
public String getUploaderName() {
return uploader_name;
}
public String getUploadDate() {
return upload_date;
}
public long getViewCount() {
return view_count;
}
public long getDuration() {
return duration;
}
} }

View File

@ -24,14 +24,50 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
*/ */
public interface StreamInfoItemExtractor extends InfoItemExtractor { public interface StreamInfoItemExtractor extends InfoItemExtractor {
/**
* Get the stream type
* @return the stream type
* @throws ParsingException thrown if there is an error in the extraction
*/
StreamType getStreamType() throws ParsingException; StreamType getStreamType() throws ParsingException;
/**
* Check if the stream is an ad.
* @return {@code true} if the stream is an ad.
* @throws ParsingException thrown if there is an error in the extraction
*/
boolean isAd() throws ParsingException; boolean isAd() throws ParsingException;
/**
* Get the stream duration in seconds
* @return the stream duration in seconds
* @throws ParsingException thrown if there is an error in the extraction
*/
long getDuration() throws ParsingException; long getDuration() throws ParsingException;
/**
* Parses the number of views
* @return the number of views or -1 for live streams
* @throws ParsingException thrown if there is an error in the extraction
*/
long getViewCount() throws ParsingException; long getViewCount() throws ParsingException;
/**
* Get the uploader name
* @return the uploader name
* @throws ParsingException if parsing fails
*/
String getUploaderName() throws ParsingException; String getUploaderName() throws ParsingException;
String getUploaderUrl() throws ParsingException; String getUploaderUrl() throws ParsingException;
/**
* Extract the uploader name
* @return the uploader name
* @throws ParsingException thrown if there is an error in the extraction
*/
String getUploadDate() throws ParsingException; String getUploadDate() throws ParsingException;
} }

View File

@ -20,17 +20,36 @@ package org.schabi.newpipe.extractor.stream;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>. * along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/ */
import org.schabi.newpipe.extractor.MediaFormat;
public class VideoStream extends Stream { public class VideoStream extends Stream {
public String resolution; public String resolution;
public boolean isVideoOnly; public boolean isVideoOnly;
/**
* @deprecated use {@link VideoStream#VideoStream(String, MediaFormat, String)}
*/
@Deprecated
public VideoStream(String url, int format, String res) { public VideoStream(String url, int format, String res) {
this(url, format, res, false); this(url, MediaFormat.getFormatById(format), res);
} }
/**
* @deprecated use {@link VideoStream#VideoStream(String, MediaFormat, String, boolean)}
*/
@Deprecated
public VideoStream(String url, int format, String res, boolean isVideoOnly) { public VideoStream(String url, int format, String res, boolean isVideoOnly) {
this(url, MediaFormat.getFormatById(format), res, isVideoOnly);
}
public VideoStream(String url, MediaFormat format, String resolution) {
this(url, format, resolution, false);
}
public VideoStream(String url, MediaFormat format, String resolution, boolean isVideoOnly) {
super(url, format); super(url, format);
this.resolution = res; this.resolution = resolution;
this.isVideoOnly = isVideoOnly; this.isVideoOnly = isVideoOnly;
} }
@ -40,4 +59,22 @@ public class VideoStream extends Stream {
resolution.equals(((VideoStream) cmp).resolution) && resolution.equals(((VideoStream) cmp).resolution) &&
isVideoOnly == ((VideoStream) cmp).isVideoOnly; isVideoOnly == ((VideoStream) cmp).isVideoOnly;
} }
/**
* Get the video resolution
* @return the video resolution
*/
public String getResolution() {
return resolution;
}
/**
* Check if the video is video only.
*
* Video only streams have no audio
* @return {@code true} if this stream is vid
*/
public boolean isVideoOnly() {
return isVideoOnly;
}
} }

View File

@ -88,17 +88,16 @@ public class DashMpdParser {
ItagItem itag = ItagItem.getItag(Integer.parseInt(id)); ItagItem itag = ItagItem.getItag(Integer.parseInt(id));
if (itag != null) { if (itag != null) {
MediaFormat mediaFormat = MediaFormat.getFromMimeType(mimeType); MediaFormat mediaFormat = MediaFormat.getFromMimeType(mimeType);
int format = mediaFormat != null ? mediaFormat.id : -1;
if (itag.itagType.equals(ItagItem.ItagType.AUDIO)) { if (itag.itagType.equals(ItagItem.ItagType.AUDIO)) {
AudioStream audioStream = new AudioStream(url, format, itag.avgBitrate); AudioStream audioStream = new AudioStream(url, mediaFormat, itag.avgBitrate);
if (!Stream.containSimilarStream(audioStream, streamInfo.audio_streams)) { if (!Stream.containSimilarStream(audioStream, streamInfo.audio_streams)) {
streamInfo.audio_streams.add(audioStream); streamInfo.audio_streams.add(audioStream);
} }
} else { } else {
boolean isVideoOnly = itag.itagType.equals(ItagItem.ItagType.VIDEO_ONLY); boolean isVideoOnly = itag.itagType.equals(ItagItem.ItagType.VIDEO_ONLY);
VideoStream videoStream = new VideoStream(url, format, itag.resolutionString, isVideoOnly); VideoStream videoStream = new VideoStream(url, mediaFormat, itag.resolutionString, isVideoOnly);
if (isVideoOnly) { if (isVideoOnly) {
if (!Stream.containSimilarStream(videoStream, streamInfo.video_only_streams)) { if (!Stream.containSimilarStream(videoStream, streamInfo.video_only_streams)) {

View File

@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.Downloader; import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.extractor.InfoItemCollector; import org.schabi.newpipe.extractor.InfoItemCollector;
@ -34,6 +35,7 @@ public class SoundcloudChartsExtractorTest {
assertNotNull(NewPipe.getDownloader()); assertNotNull(NewPipe.getDownloader());
} }
@Ignore
@Test @Test
public void testGetName() throws Exception { public void testGetName() throws Exception {
assertEquals(extractor.getName(), "Top 50"); assertEquals(extractor.getName(), "Top 50");