2016-11-29 21 views
8

Tôi đã hỏi câu hỏi trước đây về cách truy xuất url được nhúng cho tệp video và đã thực hiện thành công như vậy. Bây giờ tôi có một vấn đề khác. Câu trả lời json cho một phản ứng Wunderground API webcam cho url sau:Cách nhận liên kết trực tiếp của video từ xa từ url được nhúng trong url trong Android bằng JSoup?

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

Sử dụng JSoup và mỗi câu trả lời cho vấn đề ban đầu của tôi, tôi đã có thể để có được liên kết này được nhúng:

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

Trong khi cố gắng "phát" video từ url đó đến VideoView, tôi đã nhận được lỗi "không thể phát video". Khi nhìn vào nguồn cho liên kết đó, tôi nhận thấy rằng tệp video cần được phát không được tham chiếu trong html mà là javascript. Làm thế nào tôi có thể nhận được liên kết trực tiếp cho tệp video cần được phát? Sử dụng JSoup hoặc quá trình khác?

Các nguồn cho các url https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4 cho thấy sau cho file video cần thiết trong một khung <script>:

url: "//icons.wunderground.com/webcamcurrent/c/a/cadot1/902/ ? current.mp4 e = 1480377508"

tôi đang sử dụng JSoup để có được url nhúng cho video từ url phản ứng như vậy:

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(); 
      } 
     }); 
    } 
} 

Xin lưu ý rằng tôi cần thực hiện điều này trên mọi JSONObject trong mảng phản hồi.

Trả lời

0

Đây là cách bạn có thể lấy file:

(Thông báo: phần Khai thác chỉ làm việc với html hiện tại của trang web và nếu điều đó thay đổi, nó có thể không hoạt động chính xác)

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); 

[Output: https://icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1481246112]

Bây giờ bạn có thể nhận được các tập tin bằng cách xác định .ignoreContentType(true) để tránh org.jsoup.UnsupportedMimeTypeException.maxBodySize(0) để loại bỏ các giới hạn kích thước tệp.

// Get video file 
byte[] video = Jsoup.connect(videoUrl) 
     .ignoreContentType(true).timeout(timeout).maxBodySize(0) 
     .execute().bodyAsBytes(); 

Tôi không biết nếu bạn có thể chơi nó trên Android hay không nhưng tôi nghĩ bạn có thể lưu nó bằng cách sử org.apache.commons.io.FileUtils (Tôi đã thử nghiệm nó trong Java SE nhưng không phải môi trường phát triển Android.)

// Save video file 
org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("test.mp4"), video); 
+0

Tiết kiệm một phần cũng có thể được thực hiện theo những cách khác: http://stackoverflow.com/questions/4350084/byte-to-file-in-java – Omid

Các vấn đề liên quan