2016-11-29 15 views
8

我之前就问过关于如何检索视频文件的嵌入式网址并已成功完成此任务的问题。现在我有一个不同的问题。对于WUnderground API网络摄像头响应JSON响应提供了以下网址:如何使用JSoup在Android中的URL内直接链接远程视频?

https://www.wunderground.com/webcams/cadot1/902/show.html

使用JSoup每回答我最初的问题,我能得到这个嵌入的链接:

https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4

尝试将视频从该网址“流”到VideoView时,我不断收到错误“无法播放视频”。在查看该链接的源代码时,我注意到需要播放的视频文件未在html中引用,而是JavaScript。如何获得需要播放的视频文件的直接链接?使用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: http://stackoverflow.com/a/7745706/1363265 
      // 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上执行此操作。

回答

0

这是你如何能得到的文件:

注意:提取部分只适用于该网站的当前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); 
+0

保存部分也可以通过其他方式完成:http://stackoverflow.com/questions/4350084/byte-to-file-in-java – Omid

相关问题