Merge pull request #72 from medavox/master
Code cleanup & minor additions
This commit is contained in:
commit
c51a5a51f1
14 changed files with 86 additions and 106 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
.gitignore
|
||||||
.gradle
|
.gradle
|
||||||
/local.properties
|
/local.properties
|
||||||
/.idea/workspace.xml
|
/.idea/workspace.xml
|
||||||
|
@ -5,3 +6,5 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
/build
|
||||||
/captures
|
/captures
|
||||||
|
.idea/gradle.xml
|
||||||
|
.idea/misc.xml
|
||||||
|
|
2
app/.gitignore
vendored
2
app/.gitignore
vendored
|
@ -1 +1,3 @@
|
||||||
|
.gitignore
|
||||||
/build
|
/build
|
||||||
|
app/app.iml
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
<activity android:name=".PlayVideoActivity"
|
<activity android:name=".PlayVideoActivity"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
android:theme="@style/FullscreenTheme"
|
android:theme="@style/FullscreenTheme"
|
||||||
|
android:parentActivityName=".VideoItemDetailActivity"
|
||||||
>
|
>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 14.08.15.
|
* Created by Christian Schabesberger on 14.08.15.
|
||||||
|
@ -45,7 +46,13 @@ public class Downloader {
|
||||||
response.append(inputLine);
|
response.append(inputLine);
|
||||||
}
|
}
|
||||||
in.close();
|
in.close();
|
||||||
} catch (Exception e) {
|
|
||||||
|
}
|
||||||
|
catch(UnknownHostException uhe) {//thrown when there's no internet connection
|
||||||
|
uhe.printStackTrace();
|
||||||
|
//Toast.makeText(getActivity(), uhe.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return response.toString();
|
return response.toString();
|
||||||
|
|
|
@ -25,11 +25,11 @@ public interface StreamingService {
|
||||||
public String name = "";
|
public String name = "";
|
||||||
}
|
}
|
||||||
ServiceInfo getServiceInfo();
|
ServiceInfo getServiceInfo();
|
||||||
Class getExtractorClass();
|
Extractor getExtractorInstance();
|
||||||
Class getSearchEngineClass();
|
SearchEngine getSearchEngineInstance();
|
||||||
|
|
||||||
// When a VIEW_ACTION is caught this function will test if the url delivered within the calling
|
/**When a VIEW_ACTION is caught this function will test if the url delivered within the calling
|
||||||
// Intent was meant to be watched with this Service.
|
Intent was meant to be watched with this Service.
|
||||||
// Return false if this service shall not allow to be callean through ACTIONs.
|
Return false if this service shall not allow to be callean through ACTIONs.*/
|
||||||
boolean acceptUrl(String videoUrl);
|
boolean acceptUrl(String videoUrl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class VideoInfo {
|
||||||
|
|
||||||
public static final int VIDEO_AVAILABLE = 0x00;
|
public static final int VIDEO_AVAILABLE = 0x00;
|
||||||
public static final int VIDEO_UNAVAILABLE = 0x01;
|
public static final int VIDEO_UNAVAILABLE = 0x01;
|
||||||
public static final int VIDEO_UNAVAILABLE_GEMA = 0x02;
|
public static final int VIDEO_UNAVAILABLE_GEMA = 0x02;//German DRM organisation; sound pretty draconian
|
||||||
|
|
||||||
public static String getNameById(int id) {
|
public static String getNameById(int id) {
|
||||||
switch(id) {
|
switch(id) {
|
||||||
|
@ -68,8 +68,7 @@ public class VideoInfo {
|
||||||
case I_WEBM: return F_WEBM;
|
case I_WEBM: return F_WEBM;
|
||||||
case I_M4A: return F_M4A;
|
case I_M4A: return F_M4A;
|
||||||
case I_WEBMA: return F_WEBMA;
|
case I_WEBMA: return F_WEBMA;
|
||||||
default: Log.e(TAG, "format not known: " +
|
default: formatNotKnown(id);
|
||||||
Integer.toString(id) + "call the programmer he messed it up.");
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -81,8 +80,7 @@ public class VideoInfo {
|
||||||
case I_WEBM: return C_WEBM;
|
case I_WEBM: return C_WEBM;
|
||||||
case I_M4A: return C_M4A;
|
case I_M4A: return C_M4A;
|
||||||
case I_WEBMA: return C_WEBMA;
|
case I_WEBMA: return C_WEBMA;
|
||||||
default: Log.e(TAG, "format not known: " +
|
default: formatNotKnown(id);
|
||||||
Integer.toString(id) + "call the programmer he messed it up.");
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -94,8 +92,7 @@ public class VideoInfo {
|
||||||
case I_WEBM: return M_WEBM;
|
case I_WEBM: return M_WEBM;
|
||||||
case I_M4A: return M_M4A;
|
case I_M4A: return M_M4A;
|
||||||
case I_WEBMA: return M_WEBMA;
|
case I_WEBMA: return M_WEBMA;
|
||||||
default: Log.e(TAG, "format not known: " +
|
default: formatNotKnown(id);
|
||||||
Integer.toString(id) + "call the programmer he messed it up.");
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -109,6 +106,11 @@ public class VideoInfo {
|
||||||
public String resolution = "";
|
public String resolution = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void formatNotKnown(int id) {
|
||||||
|
Log.e(TAG, "format not known: \"" +
|
||||||
|
Integer.toString(id) + "\". Call the programmers, they messed it up!");
|
||||||
|
}
|
||||||
|
|
||||||
public static class AudioStream {
|
public static class AudioStream {
|
||||||
public AudioStream(String url, int format, int bandwidth, int samplingRate) {
|
public AudioStream(String url, int format, int bandwidth, int samplingRate) {
|
||||||
this.url = url; this.format = format;
|
this.url = url; this.format = format;
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class VideoInfoItemViewCreator {
|
||||||
if(!info.upload_date.isEmpty()) {
|
if(!info.upload_date.isEmpty()) {
|
||||||
holder.itemUploadDateView.setText(info.upload_date);
|
holder.itemUploadDateView.setText(info.upload_date);
|
||||||
} else {
|
} else {
|
||||||
//tewak if nececeary: This is a hack preventing to have a white space in the layout :P
|
//tweak if necessary: This is a hack to prevent having white space in the layout :P
|
||||||
holder.itemUploadDateView.setText(info.view_count);
|
holder.itemUploadDateView.setText(info.view_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,8 +67,8 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||||
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, i);
|
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, i);
|
||||||
try {
|
try {
|
||||||
currentStreamingService = i;
|
currentStreamingService = i;
|
||||||
extractor = (Extractor) ServiceList.getService(i)
|
extractor = ServiceList.getService(i)
|
||||||
.getExtractorClass().newInstance();
|
.getExtractorInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -122,9 +122,9 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||||
// activity, the Up button is shown. Use NavUtils to allow users
|
// activity, the Up button is shown. Use NavUtils to allow users
|
||||||
// to navigate up one level in the application structure. For
|
// to navigate up one level in the application structure. For
|
||||||
// more details, see the Navigation pattern on Android Design:
|
// more details, see the Navigation pattern on Android Design:
|
||||||
//
|
|
||||||
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
||||||
//
|
|
||||||
Intent intent = new Intent(this, VideoItemListActivity.class);
|
Intent intent = new Intent(this, VideoItemListActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
NavUtils.navigateUpTo(this, intent);
|
NavUtils.navigateUpTo(this, intent);
|
||||||
|
|
|
@ -79,16 +79,16 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
|
|
||||||
private class ExtractorRunnable implements Runnable {
|
private class ExtractorRunnable implements Runnable {
|
||||||
private Handler h = new Handler();
|
private Handler h = new Handler();
|
||||||
private Class extractorClass;
|
private Extractor extractor;
|
||||||
private String videoUrl;
|
private String videoUrl;
|
||||||
public ExtractorRunnable(String videoUrl, Class extractorClass) {
|
|
||||||
this.extractorClass = extractorClass;
|
public ExtractorRunnable(String videoUrl, Extractor extractor, VideoItemDetailFragment f) {
|
||||||
|
this.extractor = extractor;
|
||||||
this.videoUrl = videoUrl;
|
this.videoUrl = videoUrl;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Extractor extractor = (Extractor) extractorClass.newInstance();
|
|
||||||
VideoInfo videoInfo = extractor.getVideoInfo(videoUrl);
|
VideoInfo videoInfo = extractor.getVideoInfo(videoUrl);
|
||||||
h.post(new VideoResultReturnedRunnable(videoInfo));
|
h.post(new VideoResultReturnedRunnable(videoInfo));
|
||||||
if (videoInfo.videoAvailableStatus == VideoInfo.VIDEO_AVAILABLE) {
|
if (videoInfo.videoAvailableStatus == VideoInfo.VIDEO_AVAILABLE) {
|
||||||
|
@ -173,7 +173,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
// No god programm design i know. :/
|
// Not good program design, I know. :/
|
||||||
Log.w(TAG, "updateThumbnail(): Fragment closed before thread ended work");
|
Log.w(TAG, "updateThumbnail(): Fragment closed before thread ended work");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,8 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
StreamingService streamingService = ServiceList.getService(
|
StreamingService streamingService = ServiceList.getService(
|
||||||
getArguments().getInt(STREAMING_SERVICE));
|
getArguments().getInt(STREAMING_SERVICE));
|
||||||
extractorThread = new Thread(new ExtractorRunnable(
|
extractorThread = new Thread(new ExtractorRunnable(
|
||||||
getArguments().getString(VIDEO_URL), streamingService.getExtractorClass()));
|
getArguments().getString(VIDEO_URL), streamingService.getExtractorInstance(), this));
|
||||||
|
|
||||||
autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY);
|
autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY);
|
||||||
extractorThread.start();
|
extractorThread.start();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -106,6 +106,7 @@ public class VideoItemListActivity extends AppCompatActivity
|
||||||
//-------- remove this line when multiservice support is implemented ----------
|
//-------- remove this line when multiservice support is implemented ----------
|
||||||
currentStreamingServiceId = ServiceList.getIdOfService("Youtube");
|
currentStreamingServiceId = ServiceList.getIdOfService("Youtube");
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
listFragment = (VideoItemListFragment) getSupportFragmentManager()
|
listFragment = (VideoItemListFragment) getSupportFragmentManager()
|
||||||
.findFragmentById(R.id.videoitem_list);
|
.findFragmentById(R.id.videoitem_list);
|
||||||
listFragment.setStreamingService(ServiceList.getService(currentStreamingServiceId));
|
listFragment.setStreamingService(ServiceList.getService(currentStreamingServiceId));
|
||||||
|
|
|
@ -72,14 +72,14 @@ public class VideoItemListFragment extends ListFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SearchRunnable implements Runnable {
|
private class SearchRunnable implements Runnable {
|
||||||
private Class engineClass = null;
|
private SearchEngine engine;
|
||||||
private String query;
|
private String query;
|
||||||
private int page;
|
private int page;
|
||||||
Handler h = new Handler();
|
Handler h = new Handler();
|
||||||
private volatile boolean run = true;
|
private volatile boolean run = true;
|
||||||
private int requestId;
|
private int requestId;
|
||||||
public SearchRunnable(Class engineClass, String query, int page, int requestId) {
|
public SearchRunnable(SearchEngine engine, String query, int page, int requestId) {
|
||||||
this.engineClass = engineClass;
|
this.engine = engine;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.requestId = requestId;
|
this.requestId = requestId;
|
||||||
|
@ -89,13 +89,6 @@ public class VideoItemListFragment extends ListFragment {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
SearchEngine engine = null;
|
|
||||||
try {
|
|
||||||
engine = (SearchEngine) engineClass.newInstance();
|
|
||||||
} catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
SearchEngine.Result result = engine.search(query, page);
|
SearchEngine.Result result = engine.search(query, page);
|
||||||
if(run) {
|
if(run) {
|
||||||
|
@ -197,7 +190,8 @@ public class VideoItemListFragment extends ListFragment {
|
||||||
private void startSearch(String query, int page) {
|
private void startSearch(String query, int page) {
|
||||||
currentRequestId++;
|
currentRequestId++;
|
||||||
terminateThreads();
|
terminateThreads();
|
||||||
searchRunnable = new SearchRunnable(streamingService.getSearchEngineClass(), query, page, currentRequestId);
|
searchRunnable = new SearchRunnable(streamingService.getSearchEngineInstance(),
|
||||||
|
query, page, currentRequestId);
|
||||||
searchThread = new Thread(searchRunnable);
|
searchThread = new Thread(searchRunnable);
|
||||||
searchThread.start();
|
searchThread.start();
|
||||||
}
|
}
|
||||||
|
@ -252,10 +246,6 @@ public class VideoItemListFragment extends ListFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayList() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The serialization (saved instance state) Bundle key representing the
|
* The serialization (saved instance state) Bundle key representing the
|
||||||
* activated item position. Only used on tablets.
|
* activated item position. Only used on tablets.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.schabi.newpipe.youtube;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
|
@ -50,7 +51,7 @@ public class YoutubeExtractor implements Extractor {
|
||||||
private static final String TAG = YoutubeExtractor.class.toString();
|
private static final String TAG = YoutubeExtractor.class.toString();
|
||||||
|
|
||||||
// These lists only contain itag formats that are supported by the common Android Video player.
|
// These lists only contain itag formats that are supported by the common Android Video player.
|
||||||
// How ever if you are heading for a list showing all itag formats lock at
|
// How ever if you are heading for a list showing all itag formats look at
|
||||||
// https://github.com/rg3/youtube-dl/issues/1687
|
// https://github.com/rg3/youtube-dl/issues/1687
|
||||||
|
|
||||||
public static int resolveFormat(int itag) {
|
public static int resolveFormat(int itag) {
|
||||||
|
@ -141,14 +142,7 @@ public class YoutubeExtractor implements Extractor {
|
||||||
|
|
||||||
Document doc = Jsoup.parse(site, siteUrl);
|
Document doc = Jsoup.parse(site, siteUrl);
|
||||||
|
|
||||||
try {
|
videoInfo.id = matchGroup1("v=([0-9a-zA-Z]*)", siteUrl);
|
||||||
Pattern p = Pattern.compile("v=([0-9a-zA-Z]*)");
|
|
||||||
Matcher m = p.matcher(siteUrl);
|
|
||||||
m.find();
|
|
||||||
videoInfo.id = m.group(1);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
videoInfo.age_limit = 0;
|
videoInfo.age_limit = 0;
|
||||||
videoInfo.webpage_url = siteUrl;
|
videoInfo.webpage_url = siteUrl;
|
||||||
|
@ -160,16 +154,14 @@ public class YoutubeExtractor implements Extractor {
|
||||||
JSONObject ytAssets = null;
|
JSONObject ytAssets = null;
|
||||||
String dashManifest;
|
String dashManifest;
|
||||||
{
|
{
|
||||||
Pattern p = Pattern.compile("ytplayer.config\\s*=\\s*(\\{.*?\\});");
|
String jsonString = matchGroup1("ytplayer.config\\s*=\\s*(\\{.*?\\});", site);
|
||||||
Matcher m = p.matcher(site);
|
|
||||||
m.find();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
playerArgs = (new JSONObject(m.group(1)))
|
JSONObject jsonObj = new JSONObject(jsonString);
|
||||||
.getJSONObject("args");
|
playerArgs = jsonObj.getJSONObject("args");
|
||||||
ytAssets = (new JSONObject(m.group(1)))
|
ytAssets = jsonObj.getJSONObject("assets");
|
||||||
.getJSONObject("assets");
|
}
|
||||||
}catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
// If we fail in this part the video is most likely not available.
|
// If we fail in this part the video is most likely not available.
|
||||||
// Determining why is done later.
|
// Determining why is done later.
|
||||||
|
@ -199,7 +191,7 @@ public class YoutubeExtractor implements Extractor {
|
||||||
videoInfo.audioStreams = parseDashManifest(dashManifest, decryptionCode);
|
videoInfo.audioStreams = parseDashManifest(dashManifest, decryptionCode);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
//todo: check if the following statement is true
|
//todo: check if the following statement is true
|
||||||
Log.e(TAG, "Dash manifest seems not to bee available.");
|
Log.e(TAG, "Dash manifest doesn't seem to be available.");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,15 +255,9 @@ public class YoutubeExtractor implements Extractor {
|
||||||
// upload date
|
// upload date
|
||||||
videoInfo.upload_date = doc.select("strong[class=\"watch-time-text\"").first()
|
videoInfo.upload_date = doc.select("strong[class=\"watch-time-text\"").first()
|
||||||
.text();
|
.text();
|
||||||
|
|
||||||
// Try to only use date not the text around it
|
// Try to only use date not the text around it
|
||||||
try {
|
videoInfo.upload_date = matchGroup1("([0-9.]*$)", videoInfo.upload_date);
|
||||||
Pattern p = Pattern.compile("([0-9.]*$)");
|
|
||||||
Matcher m = p.matcher(videoInfo.upload_date);
|
|
||||||
m.find();
|
|
||||||
videoInfo.upload_date = m.group(1);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// description
|
// description
|
||||||
videoInfo.description = doc.select("p[id=\"eow-description\"]").first()
|
videoInfo.description = doc.select("p[id=\"eow-description\"]").first()
|
||||||
|
@ -322,16 +308,9 @@ public class YoutubeExtractor implements Extractor {
|
||||||
|
|
||||||
private VideoInfo.AudioStream[] parseDashManifest(String dashManifest, String decryptoinCode) {
|
private VideoInfo.AudioStream[] parseDashManifest(String dashManifest, String decryptoinCode) {
|
||||||
if(!dashManifest.contains("/signature/")) {
|
if(!dashManifest.contains("/signature/")) {
|
||||||
String encryptedSig = "";
|
String encryptedSig = matchGroup1("/s/([a-fA-F0-9\\.]+)", dashManifest);
|
||||||
String decryptedSig;
|
String decryptedSig;
|
||||||
try {
|
|
||||||
Pattern p = Pattern.compile("/s/([a-fA-F0-9\\.]+)");
|
|
||||||
Matcher m = p.matcher(dashManifest);
|
|
||||||
m.find();
|
|
||||||
encryptedSig = m.group(1);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
decryptedSig = decryptSignature(encryptedSig, decryptoinCode);
|
decryptedSig = decryptSignature(encryptedSig, decryptoinCode);
|
||||||
dashManifest = dashManifest.replace("/s/" + encryptedSig, "/signature/" + decryptedSig);
|
dashManifest = dashManifest.replace("/s/" + encryptedSig, "/signature/" + decryptedSig);
|
||||||
}
|
}
|
||||||
|
@ -396,10 +375,7 @@ public class YoutubeExtractor implements Extractor {
|
||||||
info.webpage_url = li.select("a[class*=\"content-link\"]").first()
|
info.webpage_url = li.select("a[class*=\"content-link\"]").first()
|
||||||
.attr("abs:href");
|
.attr("abs:href");
|
||||||
try {
|
try {
|
||||||
Pattern p = Pattern.compile("v=([0-9a-zA-Z-]*)");
|
info.id = matchGroup1("v=([0-9a-zA-Z-]*)", info.webpage_url);
|
||||||
Matcher m = p.matcher(info.webpage_url);
|
|
||||||
m.find();
|
|
||||||
info.id=m.group(1);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -446,27 +422,15 @@ public class YoutubeExtractor implements Extractor {
|
||||||
String decryptionCode;
|
String decryptionCode;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Pattern p = Pattern.compile("\\.sig\\|\\|([a-zA-Z0-9$]+)\\(");
|
decryptionFuncName = matchGroup1("\\.sig\\|\\|([a-zA-Z0-9$]+)\\(", playerCode);
|
||||||
Matcher m = p.matcher(playerCode);
|
|
||||||
m.find();
|
|
||||||
decryptionFuncName = m.group(1);
|
|
||||||
|
|
||||||
String functionPattern = "(function " + decryptionFuncName.replace("$", "\\$") + "\\([a-zA-Z0-9_]*\\)\\{.+?\\})";
|
String functionPattern = "(function " + decryptionFuncName.replace("$", "\\$") + "\\([a-zA-Z0-9_]*\\)\\{.+?\\})";
|
||||||
p = Pattern.compile(functionPattern);
|
decryptionFunc = matchGroup1(functionPattern, playerCode);
|
||||||
m = p.matcher(playerCode);
|
|
||||||
m.find();
|
|
||||||
decryptionFunc = m.group(1);
|
|
||||||
|
|
||||||
p = Pattern.compile(";([A-Za-z0-9_\\$]{2})\\...\\(");
|
helperObjectName = matchGroup1(";([A-Za-z0-9_\\$]{2})\\...\\(", decryptionFunc);
|
||||||
m = p.matcher(decryptionFunc);
|
|
||||||
m.find();
|
|
||||||
helperObjectName = m.group(1);
|
|
||||||
|
|
||||||
String helperPattern = "(var " + helperObjectName.replace("$", "\\$") + "=\\{.+?\\}\\};)function";
|
String helperPattern = "(var " + helperObjectName.replace("$", "\\$") + "=\\{.+?\\}\\};)function";
|
||||||
p = Pattern.compile(helperPattern);
|
helperObject = matchGroup1(helperPattern, playerCode);
|
||||||
m = p.matcher(playerCode);
|
|
||||||
m.find();
|
|
||||||
helperObject = m.group(1);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -493,4 +457,11 @@ public class YoutubeExtractor implements Extractor {
|
||||||
Context.exit();
|
Context.exit();
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String matchGroup1(String pattern, String input) {
|
||||||
|
Pattern pat = Pattern.compile(pattern);
|
||||||
|
Matcher mat = pat.matcher(input);
|
||||||
|
mat.find();
|
||||||
|
return mat.group(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,14 +57,14 @@ public class YoutubeSearchEngine implements SearchEngine {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Element item : list.children()) {
|
for(Element item : list.children()) {
|
||||||
i++;
|
i++;
|
||||||
/* First we need to determine witch kind of item we are working with.
|
/* First we need to determine which kind of item we are working with.
|
||||||
Youtube depicts fife different kinds if items at its search result page. These are
|
Youtube depicts five different kinds of items on its search result page. These are
|
||||||
regular videos, playlists, channels, two types of video suggestions, and a no video
|
regular videos, playlists, channels, two types of video suggestions, and a "no video
|
||||||
found item. Since we only want videos, we net to filter out all the others.
|
found" item. Since we only want videos, we need to filter out all the others.
|
||||||
An example for this can be seen here:
|
An example for this can be seen here:
|
||||||
https://www.youtube.com/results?search_query=asdf&page=1
|
https://www.youtube.com/results?search_query=asdf&page=1
|
||||||
|
|
||||||
We already applied a filter to the url, so we don't need to care about channels, and
|
We already applied a filter to the url, so we don't need to care about channels and
|
||||||
playlists now.
|
playlists now.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -102,9 +102,9 @@ public class YoutubeSearchEngine implements SearchEngine {
|
||||||
Element te = item.select("div[class=\"yt-thumb video-thumb\"]").first()
|
Element te = item.select("div[class=\"yt-thumb video-thumb\"]").first()
|
||||||
.select("img").first();
|
.select("img").first();
|
||||||
resultItem.thumbnail_url = te.attr("abs:src");
|
resultItem.thumbnail_url = te.attr("abs:src");
|
||||||
// Sometimes youtube sends links to gif files witch somehow seam to not exist
|
// 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
|
// anymore. Items with such gif also offer a secondary image source. So we are going
|
||||||
// to use that if we caught such an item.
|
// to use that if we've caught such an item.
|
||||||
if(resultItem.thumbnail_url.contains(".gif")) {
|
if(resultItem.thumbnail_url.contains(".gif")) {
|
||||||
resultItem.thumbnail_url = te.attr("abs:data-thumb");
|
resultItem.thumbnail_url = te.attr("abs:data-thumb");
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,6 @@ public class YoutubeSearchEngine implements SearchEngine {
|
||||||
Log.e(TAG, "GREAT FUCKING ERROR");
|
Log.e(TAG, "GREAT FUCKING ERROR");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package org.schabi.newpipe.youtube;
|
package org.schabi.newpipe.youtube;
|
||||||
|
|
||||||
import org.schabi.newpipe.StreamingService;
|
import org.schabi.newpipe.StreamingService;
|
||||||
|
import org.schabi.newpipe.Extractor;
|
||||||
|
import org.schabi.newpipe.SearchEngine;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 23.08.15.
|
* Created by Christian Schabesberger on 23.08.15.
|
||||||
|
@ -30,12 +33,12 @@ public class YoutubeService implements StreamingService {
|
||||||
return serviceInfo;
|
return serviceInfo;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Class getExtractorClass() {
|
public Extractor getExtractorInstance() {
|
||||||
return YoutubeExtractor.class;
|
return new YoutubeExtractor();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Class getSearchEngineClass() {
|
public SearchEngine getSearchEngineInstance() {
|
||||||
return YoutubeSearchEngine.class;
|
return new YoutubeSearchEngine();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptUrl(String videoUrl) {
|
public boolean acceptUrl(String videoUrl) {
|
||||||
|
|
Loading…
Reference in a new issue