diff --git a/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java b/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java index 94900f20b..aab57e23f 100644 --- a/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java @@ -127,6 +127,8 @@ public class VideoItemDetailFragment extends Fragment { } @Override public void run() { + //todo: fix expired thread error: + // If the thread calling this runnable is expired, the following function will crash. updateInfo(videoInfo); } } @@ -201,11 +203,13 @@ public class VideoItemDetailFragment extends Fragment { .getViewByVideoInfoItem(null, nextVideoFrame, info.nextVideo); nextVideoFrame.addView(nextVideoView); Button nextVideoButton = (Button) activity.findViewById(R.id.detailNextVideoButton); + Button similarVideosButton = (Button) activity.findViewById(R.id.detailShowSimilarButton); contentMainView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); if(!showNextVideoItem) { nextVideoRootFrame.setVisibility(View.GONE); + similarVideosButton.setVisibility(View.GONE); } switch (info.videoAvailableStatus) { diff --git a/app/src/main/java/org/schabi/newpipe/youtube/YoutubeExtractor.java b/app/src/main/java/org/schabi/newpipe/youtube/YoutubeExtractor.java index 9cca7feea..8ba344361 100644 --- a/app/src/main/java/org/schabi/newpipe/youtube/YoutubeExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/youtube/YoutubeExtractor.java @@ -91,9 +91,45 @@ public class YoutubeExtractor implements Extractor { } } - private String decryptionCode = ""; + + // static values private static final String DECRYPTION_FUNC_NAME="decrypt"; + // cached values + private static volatile String decryptionCode = ""; + + public void initService(String site) { + // The Youtube service needs to be initialized by downloading the + // js-Youtube-player. This is done in order to get the algorithm + // for decrypting cryptic signatures inside certain stream urls. + + // Star Wars Kid is used as a dummy video, in order to download the youtube player. + //String site = Downloader.download("https://www.youtube.com/watch?v=HPPj6viIBmU"); + //------------------------------------- + // extracting form player args + //------------------------------------- + try { + String jsonString = matchGroup1("ytplayer.config\\s*=\\s*(\\{.*?\\});", site); + JSONObject jsonObj = new JSONObject(jsonString); + + //---------------------------------- + // load an parse description code + //---------------------------------- + if (decryptionCode.isEmpty()) { + JSONObject ytAssets = jsonObj.getJSONObject("assets"); + String playerUrl = ytAssets.getString("js"); + if (playerUrl.startsWith("//")) { + playerUrl = "https:" + playerUrl; + } + decryptionCode = loadDecryptionCode(playerUrl); + } + + } catch (Exception e){ + Log.d(TAG, "Could not initialize the extractor of the Youtube service."); + e.printStackTrace(); + } + } + @Override public String getVideoId(String videoUrl) { try { @@ -147,18 +183,18 @@ public class YoutubeExtractor implements Extractor { videoInfo.age_limit = 0; videoInfo.webpage_url = siteUrl; + + initService(site); + //------------------------------------- // extracting form player args //------------------------------------- JSONObject playerArgs = null; - JSONObject ytAssets = null; - String dashManifest; { try { String jsonString = matchGroup1("ytplayer.config\\s*=\\s*(\\{.*?\\});", site); JSONObject jsonObj = new JSONObject(jsonString); playerArgs = jsonObj.getJSONObject("args"); - ytAssets = jsonObj.getJSONObject("assets"); } catch (Exception e) { e.printStackTrace(); @@ -168,7 +204,24 @@ public class YoutubeExtractor implements Extractor { } } + //----------------------- + // load and extract audio + //----------------------- try { + String dashManifest = playerArgs.getString("dashmpd"); + videoInfo.audioStreams = parseDashManifest(dashManifest, decryptionCode); + + } catch (NullPointerException e) { + Log.e(TAG, "Could not find \"dashmpd\" upon the player args (maybe no dash manifest available)."); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + //-------------------------------------------- + // extract general information about the video + //-------------------------------------------- + videoInfo.uploader = playerArgs.getString("author"); videoInfo.title = playerArgs.getString("title"); //first attempt gating a small image version @@ -176,23 +229,6 @@ public class YoutubeExtractor implements Extractor { videoInfo.thumbnail_url = playerArgs.getString("thumbnail_url"); videoInfo.duration = playerArgs.getInt("length_seconds"); videoInfo.average_rating = playerArgs.getString("avg_rating"); - String playerUrl = ytAssets.getString("js"); - if(playerUrl.startsWith("//")) { - playerUrl = "https:" + playerUrl; - } - if(decryptionCode.isEmpty()) { - decryptionCode = loadDecryptionCode(playerUrl); - } - - // extract audio - try { - dashManifest = playerArgs.getString("dashmpd"); - videoInfo.audioStreams = parseDashManifest(dashManifest, decryptionCode); - } catch (Exception e) { - //todo: check if the following statement is true - Log.e(TAG, "Dash manifest doesn't seem to be available."); - e.printStackTrace(); - } //------------------------------------ // extract video stream url @@ -211,9 +247,6 @@ public class YoutubeExtractor implements Extractor { // if video has a signature: decrypt it and add it to the url if(tags.get("s") != null) { - if(decryptionCode.isEmpty()) { - decryptionCode = loadDecryptionCode(playerUrl); - } streamUrl = streamUrl + "&signature=" + decryptSignature(tags.get("s"), decryptionCode); } @@ -231,9 +264,9 @@ public class YoutubeExtractor implements Extractor { e.printStackTrace(); } - //------------------------------- - // extracting from html page - //------------------------------- + //--------------------------------------- + // extracting information from html page + //--------------------------------------- // Determine what went wrong when the Video is not available diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 32d9f984a..2a397a786 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -46,7 +46,7 @@ Audio Nächstes Video - Zeige \"Nächstes Video\" Auswahl. + Zeige nächstes und änliche Videos. Url wird nicht unterstützt. Ähnliche Videos \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7fafc3104..41f6b5530 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,7 +46,7 @@ Audio Next Video - Show \"Next video\" item. + Show next and similar Videos. Url not Supported. Similar Videos Video Content Country diff --git a/app/src/main/res/xml/settings_screen.xml b/app/src/main/res/xml/settings_screen.xml index bee161060..180b226a3 100644 --- a/app/src/main/res/xml/settings_screen.xml +++ b/app/src/main/res/xml/settings_screen.xml @@ -48,13 +48,15 @@ + + android:defaultValue="" /> + --> \ No newline at end of file