如何使用 JSoup 从 Android 中的 url 中的嵌入式 url 直接获取远程视频的 link?
How to get direct link of remote video from embedded url within a url in Android using JSoup?
我之前曾问过有关如何检索视频文件的嵌入式 url 的问题,并且已经成功完成了。现在我有一个不同的问题。 WUnderground API 网络摄像头响应的 json 响应给出以下 url:
https://www.wunderground.com/webcams/cadot1/902/show.html
使用 JSoup 并根据我最初问题的答案,我能够得到这个嵌入式 link:
https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4
在尝试将 "stream" 视频从 url 转换为 VideoView 时,我一直收到错误 "cannot play video"。查看 link 的来源后,我注意到需要播放的视频文件未在 html 中引用,而是 javascript 中引用。如何获取需要播放的视频文件的直接link?使用 JSoup 或其他进程?
url https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4
的来源在 <script>
括号内显示了所需视频文件的以下内容:
url: "//icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1480377508"
我正在使用 JSoup 从响应 url 中获取嵌入的视频 url,如下所示:
private class VideoLink extends AsyncTask<Void, Void, Void> {
String title;
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setTitle("JSOUP Test");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try {
// for avoiding javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
System.setProperty("jsse.enableSNIExtension", "false");
// WARNING: do it only if security isn't important, otherwise you have
// to follow this advices:
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){return null;}
public void checkClientTrusted(X509Certificate[] certs, String authType){}
public void checkServerTrusted(X509Certificate[] certs, String authType){}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
;
}
// Connect to the web site
Document doc = Jsoup.connect(TEST_URL).get();
Elements elements = doc.getElementsByClass("videoText");
// Get the html document title
for (Element link : elements) {
String linkHref = link.attr("href");
// linkHref contains something like video.html?month=11&year=2016&filename=current.mp4
// TODO check if linkHref ends with current.mp4
title = linkHref;
}
} catch (IOException e) {
e.printStackTrace();
mProgressDialog.dismiss();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// Set title into TextView
resultTxt.setText(title);
String resVid = TEST_URL;
Log.d(TAG, "URL: " + resVid);
Uri resUri = Uri.parse(resVid);
try {
// Start the MediaController
MediaController mediacontroller = new MediaController(
MainActivity.this);
mediacontroller.setAnchorView(resultVidVw);
// Get the URL from String VideoURL
Uri video = Uri.parse(resVid);
resultVidVw.setMediaController(mediacontroller);
resultVidVw.setVideoURI(video);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
resultVidVw.requestFocus();
resultVidVw.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mProgressDialog.dismiss();
resultVidVw.start();
}
});
}
}
请注意,我需要对响应数组中的每个 JSONObject 执行此操作。
这是获取文件的方法:
(注意:提取部分仅适用于站点的当前 html,如果发生变化,它可能无法正常工作!)
String url = "https://www.wunderground.com/webcams/cadot1/902/video.html";
int timeout = 100 * 1000;
// Extract video URL
Document doc = Jsoup.connect(url).timeout(timeout).get();
Element script = doc.getElementById("inner-content")
.getElementsByTag("script").last();
String content = script.data();
int indexOfUrl = content.indexOf("url");
int indexOfComma = content.indexOf(',', indexOfUrl);
String videoUrl = "https:" + content.substring(indexOfUrl + 6, indexOfComma - 1);
System.out.println(videoUrl);
[输出:https://icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1481246112
]
现在可以通过指定.ignoreContentType(true)
来获取文件以避免org.jsoup.UnsupportedMimeTypeException
和.maxBodySize(0)
解除文件大小限制
// Get video file
byte[] video = Jsoup.connect(videoUrl)
.ignoreContentType(true).timeout(timeout).maxBodySize(0)
.execute().bodyAsBytes();
我不知道你是否可以在 Android 中播放它,但我认为你可以使用 org.apache.commons.io.FileUtils
保存它(我在 Java SE 中测试过,但没有 Android开发环境。)
// Save video file
org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("test.mp4"), video);
我之前曾问过有关如何检索视频文件的嵌入式 url 的问题,并且已经成功完成了。现在我有一个不同的问题。 WUnderground API 网络摄像头响应的 json 响应给出以下 url:
https://www.wunderground.com/webcams/cadot1/902/show.html
使用 JSoup 并根据我最初问题的答案,我能够得到这个嵌入式 link:
https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4
在尝试将 "stream" 视频从 url 转换为 VideoView 时,我一直收到错误 "cannot play video"。查看 link 的来源后,我注意到需要播放的视频文件未在 html 中引用,而是 javascript 中引用。如何获取需要播放的视频文件的直接link?使用 JSoup 或其他进程?
url https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4
的来源在 <script>
括号内显示了所需视频文件的以下内容:
url: "//icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1480377508"
我正在使用 JSoup 从响应 url 中获取嵌入的视频 url,如下所示:
private class VideoLink extends AsyncTask<Void, Void, Void> {
String title;
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setTitle("JSOUP Test");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try {
// for avoiding javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
System.setProperty("jsse.enableSNIExtension", "false");
// WARNING: do it only if security isn't important, otherwise you have
// to follow this advices:
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){return null;}
public void checkClientTrusted(X509Certificate[] certs, String authType){}
public void checkServerTrusted(X509Certificate[] certs, String authType){}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
;
}
// Connect to the web site
Document doc = Jsoup.connect(TEST_URL).get();
Elements elements = doc.getElementsByClass("videoText");
// Get the html document title
for (Element link : elements) {
String linkHref = link.attr("href");
// linkHref contains something like video.html?month=11&year=2016&filename=current.mp4
// TODO check if linkHref ends with current.mp4
title = linkHref;
}
} catch (IOException e) {
e.printStackTrace();
mProgressDialog.dismiss();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// Set title into TextView
resultTxt.setText(title);
String resVid = TEST_URL;
Log.d(TAG, "URL: " + resVid);
Uri resUri = Uri.parse(resVid);
try {
// Start the MediaController
MediaController mediacontroller = new MediaController(
MainActivity.this);
mediacontroller.setAnchorView(resultVidVw);
// Get the URL from String VideoURL
Uri video = Uri.parse(resVid);
resultVidVw.setMediaController(mediacontroller);
resultVidVw.setVideoURI(video);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
resultVidVw.requestFocus();
resultVidVw.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mProgressDialog.dismiss();
resultVidVw.start();
}
});
}
}
请注意,我需要对响应数组中的每个 JSONObject 执行此操作。
这是获取文件的方法:
(注意:提取部分仅适用于站点的当前 html,如果发生变化,它可能无法正常工作!)
String url = "https://www.wunderground.com/webcams/cadot1/902/video.html";
int timeout = 100 * 1000;
// Extract video URL
Document doc = Jsoup.connect(url).timeout(timeout).get();
Element script = doc.getElementById("inner-content")
.getElementsByTag("script").last();
String content = script.data();
int indexOfUrl = content.indexOf("url");
int indexOfComma = content.indexOf(',', indexOfUrl);
String videoUrl = "https:" + content.substring(indexOfUrl + 6, indexOfComma - 1);
System.out.println(videoUrl);
[输出:https://icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1481246112
]
现在可以通过指定.ignoreContentType(true)
来获取文件以避免org.jsoup.UnsupportedMimeTypeException
和.maxBodySize(0)
解除文件大小限制
// Get video file
byte[] video = Jsoup.connect(videoUrl)
.ignoreContentType(true).timeout(timeout).maxBodySize(0)
.execute().bodyAsBytes();
我不知道你是否可以在 Android 中播放它,但我认为你可以使用 org.apache.commons.io.FileUtils
保存它(我在 Java SE 中测试过,但没有 Android开发环境。)
// Save video file
org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("test.mp4"), video);