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 700f06766..bd1f5107c 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 @@ -188,143 +188,6 @@ public class YoutubeSearchEngine extends SearchEngine { } private StreamPreviewInfoExtractor extractPreviewInfo(final Element item) { - return new StreamPreviewInfoExtractor() { - @Override - public String getWebPageUrl() throws ParsingException { - 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 { - 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 int getDuration() throws ParsingException { - try { - return YoutubeParsingHelper.parseDurationString( - item.select("span[class=\"video-time\"]").first().text()); - } catch(Exception e) { - if(isLiveStream(item)) { - // -1 for no duration - return -1; - } else { - throw new ParsingException("Could not get Duration: " + getTitle(), e); - } - - - } - } - - @Override - public String getUploader() throws ParsingException { - 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 { - 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 - public long getViewCount() throws ParsingException { - String output; - String input; - try { - input = item.select("div[class=\"yt-lockup-meta\"]").first() - .select("li").get(1) - .text(); - } catch (IndexOutOfBoundsException e) { - if(isLiveStream(item)) { - // -1 for no view count - return -1; - } else { - throw new ParsingException( - "Could not parse yt-lockup-meta although available: " + getTitle(), e); - } - } - - output = Parser.matchGroup1("([0-9,\\. ]*)", input) - .replace(" ", "") - .replace(".", "") - .replace(",", ""); - - try { - return Long.parseLong(output); - } catch (NumberFormatException e) { - // if this happens the video probably has no views - if(!input.isEmpty()) { - return 0; - } else { - throw new ParsingException("Could not handle input: " + input, e); - } - } - } - - @Override - public String getThumbnailUrl() throws ParsingException { - 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); - } - } - - @Override - public AbstractVideoInfo.StreamType getStreamType() { - if(isLiveStream(item)) { - return AbstractVideoInfo.StreamType.LIVE_STREAM; - } else { - return AbstractVideoInfo.StreamType.VIDEO_STREAM; - } - } - - private boolean isLiveStream(Element item) { - Element bla = item.select("span[class*=\"yt-badge-live\"]").first(); - - if(bla == null) { - // sometimes livestreams dont have badges but sill are live streams - // if video time is not available we most likly have an offline livestream - if(item.select("span[class*=\"video-time\"]").first() == null) { - return true; - } - } - return bla != null; - } - }; + return new YoutubeStreamPreviewInfoExtractor(item); } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamPreviewInfoExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamPreviewInfoExtractor.java new file mode 100644 index 000000000..a23bf904c --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamPreviewInfoExtractor.java @@ -0,0 +1,171 @@ +package org.schabi.newpipe.extractor.services.youtube; + +import org.jsoup.nodes.Element; +import org.schabi.newpipe.extractor.AbstractVideoInfo; +import org.schabi.newpipe.extractor.Parser; +import org.schabi.newpipe.extractor.ParsingException; +import org.schabi.newpipe.extractor.StreamPreviewInfoExtractor; + +/** + * Copyright (C) Christian Schabesberger 2016 + * YoutubeStreamPreviewInfoExtractor.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 YoutubeStreamPreviewInfoExtractor implements StreamPreviewInfoExtractor { + + private final Element item; + + public YoutubeStreamPreviewInfoExtractor(Element item) { + this.item = item; + } + + @Override + public String getWebPageUrl() throws ParsingException { + 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 { + 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 int getDuration() throws ParsingException { + try { + return YoutubeParsingHelper.parseDurationString( + item.select("span[class=\"video-time\"]").first().text()); + } catch(Exception e) { + if(isLiveStream(item)) { + // -1 for no duration + return -1; + } else { + throw new ParsingException("Could not get Duration: " + getTitle(), e); + } + + + } + } + + @Override + public String getUploader() throws ParsingException { + 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 { + 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 + public long getViewCount() throws ParsingException { + String output; + String input; + try { + input = item.select("div[class=\"yt-lockup-meta\"]").first() + .select("li").get(1) + .text(); + } catch (IndexOutOfBoundsException e) { + if(isLiveStream(item)) { + // -1 for no view count + return -1; + } else { + throw new ParsingException( + "Could not parse yt-lockup-meta although available: " + getTitle(), e); + } + } + + output = Parser.matchGroup1("([0-9,\\. ]*)", input) + .replace(" ", "") + .replace(".", "") + .replace(",", ""); + + try { + return Long.parseLong(output); + } catch (NumberFormatException e) { + // if this happens the video probably has no views + if(!input.isEmpty()) { + return 0; + } else { + throw new ParsingException("Could not handle input: " + input, e); + } + } + } + + @Override + public String getThumbnailUrl() throws ParsingException { + 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); + } + } + + @Override + public AbstractVideoInfo.StreamType getStreamType() { + if(isLiveStream(item)) { + return AbstractVideoInfo.StreamType.LIVE_STREAM; + } else { + return AbstractVideoInfo.StreamType.VIDEO_STREAM; + } + } + + private boolean isLiveStream(Element item) { + Element bla = item.select("span[class*=\"yt-badge-live\"]").first(); + + if(bla == null) { + // sometimes livestreams dont have badges but sill are live streams + // if video time is not available we most likly have an offline livestream + if(item.select("span[class*=\"video-time\"]").first() == null) { + return true; + } + } + return bla != null; + } +} diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 8636e9fa9..e8865273d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -60,7 +60,7 @@ Netzwerkfehler Downloadverzeichnis für Musik - Verzeichnis zum Speichern heruntergeladener Audiodateien + Verzeichnis zum Speichern heruntergeladener Audiodateien. Pfad für heruntergeladene Audiodateien eingeben. Aussehen @@ -91,7 +91,7 @@ MELDEN Info: Dies ist passiert: - Was:\\nAnfrage:\\nSprache des Inhalts:\\nDienst:\\nZeit (GMT):\\nVersion:\\nBS-Version:\\nGlob. IP-Bereich: + Was:\\nAnfrage:\\nSprache des Inhalts:\\nDienst:\\nZeit (GMT):\\nVersion:\\nOS-Version:\\nGlob. IP-Bereich: Details: @@ -120,4 +120,9 @@ Dieses Gerät stellt keinen abgesicherten Dekodierer für %1$s bereit Konnte keinen Stream holen. Geschützte Inhalte werden von API-Ebenen unterhalb von 18 nicht unterstützt + Bei Aufruf aus einer anderen App automatisch abspielen. + Spielt ein Video automatisch ab, wenn NewPipe von einer anderen App aufgerufen wurde. + Einen Fehler melden + Anwenderbericht + diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 2498500c3..eaee7b686 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -119,4 +119,9 @@ ストレージにアクセスするアクセス許可が拒否されました ExoPlayer を使用する 実験的 - +別のアプリから呼び出されたときに自動再生。 + NewPipe が別のアプリから呼び出されたときに、自動的にビデオを再生します。 + エラーを報告 + ユーザー報告 + + diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index e38bb232b..9db3edddd 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -118,4 +118,9 @@ Ni mogoče preiskati dekodirnikov na napravi Ni mogoče začeti dekodirnika %1$s Dovoljenje za dostop do shrambe je zavrnjeno + Samodejno predvajaj vsebino, poslano iz drugega programa. + Samodejno predvajaj vsebino, če je NewPipe klican iz drugega programa. + Pošlji poročilo o napaki + Poročilo uporabnika + diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 05835492a..78cf4fab3 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -121,4 +121,7 @@ Не могох да потражим декодере уређаја Не могох да покренем декодер %1$s Дозвола за приступ складишту је одбијена + Пријавите грешку + Извештај корисника +