¿Cómo obtener el enlace directo de video remoto de url incrustado dentro de una url en Android usando JSoup?

Había hecho la pregunta anteriormente sobre cómo recuperar la url incrustada para un archivo de vídeo y lo han hecho con éxito. Ahora tengo un problema diferente. La respuesta de json para una respuesta de webcam WUnderground API da la siguiente URL:

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

Utilizando JSoup y por la respuesta a mi problema inicial pude conseguir este enlace incrustado:

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

Mientras intentaba "transmitir" el video de esa url a un VideoView, seguí recibiendo el error "no se puede reproducir video". Al mirar la fuente de ese enlace me di cuenta de que el archivo de vídeo que necesita ser jugado no se hace referencia en html, sino más bien javascript. ¿Cómo puedo obtener el enlace directo para el archivo de vídeo que se debe reproducir? ¿Usando JSoup u otro proceso?

La fuente de la URL https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4 muestra lo siguiente para el archivo de vídeo necesario dentro de un soporte <script> :

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

Estoy usando JSoup para obtener la url incrustada para el video de la URL de respuesta como así:

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

Tenga en cuenta que necesito hacer esto en cada JSONObject en la matriz de respuesta.

Así es como puede obtener el archivo:

( Aviso : la parte de extracción sólo funciona con el html actual del sitio y si eso cambia, puede que no funcione correctamente!)

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

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

Ahora puede obtener el archivo especificando .ignoreContentType(true) para evitar que org.jsoup.UnsupportedMimeTypeException y .maxBodySize(0) eliminen el límite en el tamaño del archivo.

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

No sé si puedes jugarlo en Android o no, pero creo que puedes guardarlo usando org.apache.commons.io.FileUtils (lo probé en Java SE, pero no en el entorno de desarrollo de Android).

 // Save video file org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("test.mp4"), video); 
  • Jsoup no puede leer el archivo de retorno xml
  • obtener img src con jsoup
  • ¿Cómo obtener una imagen captcha de formulario con Jsoup?
  • Android - Parse JS generó urls con JSOUP
  • Cómo agregar niños a childnodes mediante el documento jsoup
  • El análisis con jsoup lanza error (NetworkOnMainThreadException)
  • Manipulación de datos en webs en Android
  • ¿Cómo convertir una cadena a UTF-8 en Android?
  • Nth-child (incluso) generando ParseException mientras usa el selector jsoup en android?
  • Analizar la página web con Jsoup. ¿Por qué el comportamiento en Android es diferente?
  • ¿Hay algo más rápido que Jsoup para el raspado de HTML?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.