diff --git a/app/src/androidTest/java/org/schabi/newpipe/extractor/youtube/YoutubeSearchEngineTest.java b/app/src/androidTest/java/org/schabi/newpipe/extractor/youtube/YoutubeSearchEngineTest.java index 70e955d7d..0a590ea51 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/extractor/youtube/YoutubeSearchEngineTest.java +++ b/app/src/androidTest/java/org/schabi/newpipe/extractor/youtube/YoutubeSearchEngineTest.java @@ -68,7 +68,7 @@ public class YoutubeSearchEngineTest extends AndroidTestCase { public void testItemsHaveRightDuration() { for(StreamPreviewInfo i : result.resultList) { - assertTrue(i.duration, i.duration.contains(":")); + assertTrue(i.duration >= 0); } } diff --git a/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java b/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java index b9dbebea8..53950361f 100644 --- a/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java +++ b/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java @@ -1,6 +1,7 @@ package org.schabi.newpipe; import android.content.Context; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -74,8 +75,8 @@ class VideoInfoItemViewCreator { } else { holder.itemDurationView.setVisibility(View.INVISIBLE); } - if(info.duration != null && !info.duration.isEmpty()) { - holder.itemDurationView.setText(info.duration); + if(info.duration > 0) { + holder.itemDurationView.setText(getDurationString(info.duration)); } else { holder.itemDurationView.setVisibility(View.GONE); } @@ -115,4 +116,50 @@ class VideoInfoItemViewCreator { } } + public static String getDurationString(int duration) { + Log.d("asfd", Integer.toString(duration) + " ----------------------"); + String output = ""; + int days = duration / (24 * 60 * 60); /* greater than a day */ + duration %= (24 * 60 * 60); + int hours = duration / (60 * 60); /* greater than an hour */ + duration %= (60 * 60); + int minutes = duration / 60; + int seconds = duration % 60; + + if(days > 0) { + output = Integer.toString(days) + ":"; + } + if(hours > 0 || !output.isEmpty()) { + if(hours > 0) { + if(hours >= 10) { + output += Integer.toString(minutes); + } else { + output += "0" + Integer.toString(minutes); + } + } else { + output += "00"; + } + output += ":"; + } + if(minutes > 0 || !output.isEmpty()) { + if(minutes > 0) { + if(minutes >= 10) { + output += Integer.toString(minutes); + } else { + output += "0" + Integer.toString(minutes); + } + } else { + output += "00"; + } + output += ":"; + } + + if(seconds >= 10) { + output += Integer.toString(seconds); + } else { + output += "0" + Integer.toString(seconds); + } + + return output; + } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/StreamInfo.java b/app/src/main/java/org/schabi/newpipe/extractor/StreamInfo.java index b6da26404..fdcbfd027 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/StreamInfo.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/StreamInfo.java @@ -254,10 +254,12 @@ public class StreamInfo extends AbstractVideoInfo { //todo: better than this if(avi instanceof StreamPreviewInfo) { //shitty String to convert code + /* String dur = ((StreamPreviewInfo)avi).duration; int minutes = Integer.parseInt(dur.substring(0, dur.indexOf(":"))); int seconds = Integer.parseInt(dur.substring(dur.indexOf(":")+1, dur.length())); - this.duration = (minutes*60)+seconds; + */ + this.duration = ((StreamPreviewInfo)avi).duration; } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfo.java b/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfo.java index 5ab1f75fc..5b0ff7c57 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfo.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfo.java @@ -22,5 +22,5 @@ package org.schabi.newpipe.extractor; /**Info object for previews of unopened videos, eg search results, related videos*/ public class StreamPreviewInfo extends AbstractVideoInfo { - public String duration = ""; + public int duration = 0; } \ No newline at end of file diff --git a/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfoExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfoExtractor.java index 4146acd84..8c64d6f79 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfoExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/StreamPreviewInfoExtractor.java @@ -23,7 +23,7 @@ package org.schabi.newpipe.extractor; public interface StreamPreviewInfoExtractor { String getWebPageUrl() throws ParsingException; String getTitle() throws ParsingException; - String getDuration() throws ParsingException; + int getDuration() throws ParsingException; String getUploader() throws ParsingException; String getUploadDate() throws ParsingException; long getViewCount() throws ParsingException; diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java new file mode 100644 index 000000000..7d18ebc25 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java @@ -0,0 +1,61 @@ +package org.schabi.newpipe.extractor.services.youtube; + +import org.schabi.newpipe.extractor.ParsingException; + +/** + * Created by Christian Schabesberger on 02.03.16. + * + * Copyright (C) Christian Schabesberger 2016 + * YoutubeParsingHelper.java is part of NewPipe. + * + * NewPipe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NewPipe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NewPipe. If not, see . + */ + +public class YoutubeParsingHelper { + public static int parseDurationString(String input) + throws ParsingException, NumberFormatException { + String[] splitInput = input.split(":"); + String days = "0"; + String hours = "0"; + String minutes = "0"; + String seconds = "0"; + + switch(splitInput.length) { + case 4: + days = splitInput[0]; + hours = splitInput[1]; + minutes = splitInput[2]; + seconds = splitInput[3]; + break; + case 3: + hours = splitInput[0]; + minutes = splitInput[1]; + seconds = splitInput[2]; + break; + case 2: + minutes = splitInput[0]; + seconds = splitInput[1]; + break; + case 1: + seconds = splitInput[0]; + break; + default: + throw new ParsingException("Error duration string with unknown format: " + input); + } + return ((((Integer.parseInt(days) * 24) + + Integer.parseInt(hours) * 60) + + Integer.parseInt(minutes)) * 60) + + Integer.parseInt(seconds); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java index 4e6010108..d25c70f07 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java @@ -172,40 +172,56 @@ public class YoutubeSearchEngine implements SearchEngine { return new StreamPreviewInfoExtractor() { @Override public String getWebPageUrl() throws ParsingException { - Element el = item.select("div[class*=\"yt-lockup-video\"").first(); - Element dl = el.select("h3").first().select("a").first(); - return dl.attr("abs:href"); + try { + Element el = item.select("div[class*=\"yt-lockup-video\"").first(); + Element dl = el.select("h3").first().select("a").first(); + return dl.attr("abs:href"); + } catch (Exception e) { + throw new ParsingException("Could not get web page url for the video", e); + } } @Override public String getTitle() throws ParsingException { - Element el = item.select("div[class*=\"yt-lockup-video\"").first(); - Element dl = el.select("h3").first().select("a").first(); - return dl.text(); + try { + Element el = item.select("div[class*=\"yt-lockup-video\"").first(); + Element dl = el.select("h3").first().select("a").first(); + return dl.text(); + } catch (Exception e) { + throw new ParsingException("Could not get title", e); + } } @Override - public String getDuration() throws ParsingException { + public int getDuration() throws ParsingException { try { - return item.select("span[class=\"video-time\"]").first().text(); + return YoutubeParsingHelper.parseDurationString( + item.select("span[class=\"video-time\"]").first().text()); } catch(Exception e) { - e.printStackTrace(); + throw new ParsingException("Could not get Duration", e); } - return ""; } @Override public String getUploader() throws ParsingException { - return item.select("div[class=\"yt-lockup-byline\"]").first() - .select("a").first() - .text(); + try { + return item.select("div[class=\"yt-lockup-byline\"]").first() + .select("a").first() + .text(); + } catch (Exception e) { + throw new ParsingException("Could not get uploader", e); + } } @Override public String getUploadDate() throws ParsingException { - return item.select("div[class=\"yt-lockup-meta\"]").first() - .select("li").first() - .text(); + try { + return item.select("div[class=\"yt-lockup-meta\"]").first() + .select("li").first() + .text(); + } catch(Exception e) { + throw new ParsingException("Could not get uplaod date", e); + } } @Override @@ -233,18 +249,21 @@ public class YoutubeSearchEngine implements SearchEngine { @Override public String getThumbnailUrl() throws ParsingException { - String url; - Element te = item.select("div[class=\"yt-thumb video-thumb\"]").first() - .select("img").first(); - url = te.attr("abs:src"); - // Sometimes youtube sends links to gif files which somehow seem to not exist - // anymore. Items with such gif also offer a secondary image source. So we are going - // to use that if we've caught such an item. - if (url.contains(".gif")) { - url = te.attr("abs:data-thumb"); + try { + String url; + Element te = item.select("div[class=\"yt-thumb video-thumb\"]").first() + .select("img").first(); + url = te.attr("abs:src"); + // Sometimes youtube sends links to gif files which somehow seem to not exist + // anymore. Items with such gif also offer a secondary image source. So we are going + // to use that if we've caught such an item. + if (url.contains(".gif")) { + url = te.attr("abs:data-thumb"); + } + return url; + } catch (Exception e) { + throw new ParsingException("Could not get thumbnail url", e); } - - return url; } }; } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java index db137a145..00857bbba 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java @@ -701,7 +701,8 @@ public class YoutubeStreamExtractor implements StreamExtractor { } info.uploader = li.select("span.g-hovercard").first().text(); - info.duration = li.select("span.video-time").first().text(); + info.duration = YoutubeParsingHelper.parseDurationString( + li.select("span.video-time").first().text()); Element img = li.select("img").first(); info.thumbnail_url = img.attr("abs:src");