Página 2 de 6

Re: Obtener la URL de un vídeo embebido

Publicado: 30 May 2016, 18:30
por tormund
Pues finalmente no he podido hacer ninguna de las dos propuestas. El Webview parece que carga el script pero no devuelve nada, por lo que he leído parece que sólo devuelve el código html. Por otro lado he intentado importar la librería javax.script de java en Android Studio pero a su vez requiere de otra dependencia de java. Intentaré hacerlo a pelo tal y como me indicó robalo en su primera respuesta.

Gracias de nuevo.

Saludos.

Re: Obtener la URL de un vídeo embebido

Publicado: 30 May 2016, 22:46
por robalo
tormund escribió:Con ese simple código de java puedo obtener el código javascript que contiene la URL???? :shock:

No he entendido a que te refieres con que te falta probarlo AADecode.
Sí, con ese código desempaqueta el el "eval(function(p,a,c,k,e,d)....". Te pego los scripts con los que he hecho la prueba.

testUnpack.java

Código: Seleccionar todo

public class testUnpack {

	public static void main(String[] args) {

		String pageUrl = "http://powvideo.net/ccj7r5u58u7v";

		String[] videourls = new powvideo(pageUrl).videoUrls;

		System.out.println("");
		System.out.println("Urls:");
		System.out.println("---------------------------------------------------------------------");

		Integer c = 0;
		for (String url : videourls){
			System.out.println("url " + c + ": " + url.replace("/.mp4", "/v.mp4"));
			c++;
		}
		System.out.println("---------------------------------------------------------------------");
	}
}
powvideo.java

Código: Seleccionar todo

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class powvideo {

	String[] videoUrls;

	powvideo(String pageUrl) {

		String host = "http://powvideo.net";
		String id = "";
		String data = "";
		String videoUrl = "";
		String packed = "";

		String patron = "";
		Matcher matches;

		patron = "powvideo.net/(?:embed-|iframe-|preview-|)([a-z0-9]+)";
		matches = Pattern.compile(patron).matcher(pageUrl);
		while (matches.find())
			id = matches.group(1);

		String[] headers = {
				"User-Agent",
				"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
				"Referer", host + "/embed-" + id + "-640x360.html" };

		pageUrl = host + "/iframe-" + id + "-640x360.html";
		String getdata = new getDataFromUrl(pageUrl, headers).data;

		patron = "<script type='text/javascript'>eval\\((.*?)\\)</script>";
		matches = Pattern.compile(patron).matcher(getdata.replaceAll("\\n", ""));
		while (matches.find())
			packed = matches.group(1);

		String unpacked = new unPack(packed).unPacked;

		patron = ";sources=\\[(.*?)\\];";
		matches = Pattern.compile(patron).matcher(unpacked);
		while (matches.find())
			data = matches.group(1);

		patron = "src:[^']*'([^']+)'";
		matches = Pattern.compile(patron).matcher(data);
		while (matches.find())
			videoUrl+= matches.group(1).replace("\\", "") + "|";

		videoUrls = videoUrl.replaceAll("\\|$", "").split("\\|");
	}
}
getDataFromUrl.java

Código: Seleccionar todo

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;

public class getDataFromUrl {

	String data;

	getDataFromUrl(String pageUrl, String[] headers) {

		StringBuilder sb = new StringBuilder();
		URLConnection urlConn = null;
		InputStreamReader in = null;

		int c = 0;
		String key = "";
		String value = "";

		try {
			URL getUrl = new URL(pageUrl);
			urlConn = getUrl.openConnection();
			for (String header : headers) {
				if (c % 2 == 0)
					key = header;
				else {
					value = header;
					urlConn.addRequestProperty(key, value);
				}
				c++;
			}
			if (urlConn != null)
				urlConn.setReadTimeout(60 * 1000);
			if (urlConn != null && urlConn.getInputStream() != null) {
				in = new InputStreamReader(urlConn.getInputStream(),
						Charset.defaultCharset());
				BufferedReader bufferedReader = new BufferedReader(in);
				if (bufferedReader != null) {
					int cp;
					while ((cp = bufferedReader.read()) != -1) {
						sb.append((char) cp);
					}
					bufferedReader.close();
				}
			}
			in.close();
		} catch (Exception e) {
			throw new RuntimeException("Exception gatDataFromUrl:" + pageUrl, e);
		}

		data = sb.toString();

	}
}
unPack.java

Código: Seleccionar todo

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class unPack {

	String unPacked;

	unPack(String packed) {

		ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");

		try {
			engine.eval("var res = " + packed + ";");
		} catch (ScriptException e) {
			e.printStackTrace();
		}

		unPacked = (String) engine.get("res");

	}
}
Con la url que tiene en "testUnpack.java" en la variable "pageUrl" te debería salir

Código: Seleccionar todo

Urls:
---------------------------------------------------------------------
url 0: rtmp://149.202.80.233:19350/vod/mp4:01/00269/ccj7r5u58u7v_n?h=haohpdb4pyikkfn2mal72ny4hy2ooszuw7ntjsjlcffvmncsc6qgyw4eva
url 1: http://powvideo.net/haohpdb4pyikkfn2mal72ny4hy2ooszuw7ntjsjlcffvmncsc6qgyw4eva.m3u8
url 2: http://149.202.80.233:8777/haohpdb4pyikkfn2mal72ny4hy2ooszuw7ntjsjlcffvmncsc6qgyw4eva/v.mp4
---------------------------------------------------------------------
El "AADecode" o mejor dicho "AAEncode", el la ofuscación que usa openload "゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚)......".
Ya lo he probado y es un pelín más complicadillo al tener que esquivar objetos del DOM, en powvideo sólo nos tenemos que quedar con el contenido de "eval" y cargarlo en un variable para recoger el resultado con ".get( "nombreVariable" )" pero en openload se tiene que separar las deficiones de los datos insertando entre ambos la variable en la que se almacenará el resultado. La parte de los datos se le tiene que pasar a nuestra variable como una cadena por lo que la tenemos que encomillar y eliminar del principio "(゚Д゚)['_']" = "function Function(){ [native code] }" y al final "('_');" = "_". Todo junto en JS con las definicines de la primera parte: "(゚Д゚)['_']('_');" = "function anonymous(){_}". Lo que falta en esa función es lo que guardamos en la variable.
Tambien hay que sacar la función que usa "toString" de los resultados que en la actualidad ofusca el resultado con esta función. Luego en el archivo del scraped de openload se le tiene que sacar el contenido de "Location" de las caberecras de la respuesta al solicitar la url que se ha conseguido en el paso anterior.

Código: Seleccionar todo

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class aaDecode {
	
	String decode;

	aaDecode(String encode) {

		String patron = "";
		Matcher  matches;
		String res = "";

		ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");

		encode = encode.replaceAll("\\s+", "");
		encode = encode.replaceAll("';.゚Д゚..'_'.", "'; res = ");
		encode = encode.replaceAll(".'_'.;$", ";");

		try {
			engine.eval(encode);
				res = (String) engine.get("res");
			if (new String(res).contains("toString")){
				patron = "=\\((.*)\\);";
				matches = Pattern.compile(patron).matcher(res);
				while (matches.find())
					res = (String) matches.group(1);

				engine.eval("res =" + res + ";");
				res = (String) engine.get("res");
			}
		} catch (ScriptException e) {
			e.printStackTrace();
		}
		decode = res;
	}
}
El código para AAdecode con el que he probado

Re: Obtener la URL de un vídeo embebido

Publicado: 01 Jun 2016, 22:03
por tormund
Finalmente lo he conseguido usando un webview. No he sido capaz de importar javax.script a android, me pedía una dependencia de java que no he encontrado.

Muchas gracias por todo.

Re: Obtener la URL de un vídeo embebido

Publicado: 02 Jun 2016, 01:12
por robalo
yo tampoco he podido para android, te dice algo de java.lang o algo así, lo que si he podido para android es sin usar ni javax.scripts ni webkit.WebView de la forma "clásica"

Código: Seleccionar todo

package pez.robalo.jsunpack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class unPack {

	public String unPacked;

	public unPack(String packed) {

		String   p = "";
		Integer  a = 0;
		Integer  c = 0;
		String[] k = {};
		String[] toString = {};

		String patron = "";
		Matcher  matches;

		patron = "\\}\\('(.*)', *(\\d+), *(\\d+), *'(.*)'\\.split\\('\\|'\\)";
		matches = Pattern.compile(patron).matcher(packed);

		while (matches.find()) {
			p = matches.group(1);
			a = Integer.parseInt(matches.group(2));
			c = Integer.parseInt(matches.group(3));
			k = matches.group(4).split("\\|");
		}

		if (a <= 62) toString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
		else toString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~".split("");

		while (c > 0) {
			c--;
			p = p.replaceAll("\\b" + e(c, a, toString) + "\\b", k[c]);
		}

		unPacked = p;

	}

	private static String e(Integer c, Integer a, String[] toString) {
		if (c < a) return toString[c + 1];
		else return toString[(c / a) + 1] + toString[(c % a) + 1];
	}

}
Con WebView se lo haces a la página y scrapeas o al código JS?

Mañana voy a ver si en android trabaja jython y si lo hace a ver como lo hace, en una aplicación Java trabaja bien y sería interesante poder usar .py por el tema del mantenimiento

Re: Obtener la URL de un vídeo embebido

Publicado: 02 Jun 2016, 08:17
por tormund
Para desempaquetar con WebView primero identifico las variables mediante expresiones regulares, luego genero una especie de packed formateado que el WebView entienda (si le envío el que obtengo directamente de PowVideo el WebView no lo entiende):

Código: Seleccionar todo

packedFormateado = "javascript: (function() { var p = '" + p + "';\n";
packedFormateado += "var a = " + a + ";\n";
packedFormateado += "var c = " + c + ";\n";
packedFormateado += "var k = '" + k + ";\n";
packedFormateado += "var e = " + e + ";\n";
packedFormateado += d + ")()"; //He llamado variable "d" al while
Una vez formateado lo evalúo y recibo la respuesta generando un ValueCallBack:

Código: Seleccionar todo

webView.evaluateJavascript(packedFormateado, new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String html) {
                        Log.d("HTML", html);
                        unpacked = html;
                        TextView txtTexto = (TextView) findViewById(R.id.txtTexto);
                        txtTexto.setText(unpacked);
                    }
                }
            );
Acabo de descubrir que solo funciona a partir del SDK 19 (KitKat), voy a investigar si con versiones anteriores se puede hacer algo.

Por cierto, me ocurre una cosa muy extraña al obtener el código HTML de PowVideo: una veces me devuelve el código que necesito (el que contiene el código packed) y otras veces no. Tengo que investigar más, quizá esté haciendo mal el post.

Saludos.

Re: Obtener la URL de un vídeo embebido

Publicado: 02 Jun 2016, 21:22
por robalo
powvideo necesita headers para los datos de las urls con formato "http://powvideo.net/iframe-<id>-640x360.html", no se si será por eso, con la clase "getDataFromUrl" no tengo problemas, siempre me entrega los datos de la página sin problemas. El headers necesario tiene que ser como el de la clase "powvideo".

Parece que jython no tira en android al menos en el entorno de trabajo que tengo pero de momento no he visto nada en la red que diga que si lo hace. Aún seguiré buscando.

Tengo que actualizar lo que estoy usando o cambiar a otro entrono. WebView ahora mismo no me tira por mucho que le diga api19 y le instale o meta los jar que le hacen falta.

Qué entorno usas?

Re: Obtener la URL de un vídeo embebido

Publicado: 02 Jun 2016, 22:53
por tormund
No creo que sean las headers porque unas veces me captura el html correcto a la primera, otras a la tercera, otras a la segunda. Al final le he puesto un bucle con una máximo de 10 intentos y normalmente a los dos o tres intentos lo consigo.

Estoy usando Android Studio 2.1 desde OS X. ¿Qué problema te da el WebView? Me extraña que te pida librerías, es nativo de Android. Lo que ocurre por debajo del SDK 19 es que no existe el método evaluateJavaScript que es el que evalúa el script, anteriormente se usaba loadURL o loadData pero están pensados para mostrar datos en el WebView, no encontrado una forma de obtener el html ya interpretado.

Re: Obtener la URL de un vídeo embebido

Publicado: 03 Jun 2016, 01:29
por robalo
El problema creo que soy yo que soy muy antiguo y me tengo que acualizar :) Quiero que clases que haga para java me valgan tanto para aplicaciones java y aplicaciones android y como he empezado hacerlas para java sólo me entran apis level antiguas.

Voy a empezar de cero y con la tablet de la jefa, cuando me deje, los ADV son un coñazo tanto en Android Studio como en Eclipse, los dos usan las mismas carpetas.

A ver sin con la tablet que tiene 4.4.2 me centro más y paso de chorradas que sólo funcionan en versiones antiguas. Cual sería la versión en la que deberían rodar las aplicaciones en la actualidad? El teléfono de mi jefa tiene la 6.0.1, una aplicación para la 4.4.2 debería funcionar en la 6.0.1? Ya no me fio :)

Re: Obtener la URL de un vídeo embebido

Publicado: 03 Jun 2016, 06:20
por tormund
Sí, debería funcionar. De hecho la SDK 19 es la versión 4.4 (KitKat). Yo uso la versión 5.1.1 para las pruebas y no tengo problemas.

Re: Obtener la URL de un vídeo embebido

Publicado: 04 Jun 2016, 00:02
por robalo
Que diferencia con la tablet :) Pues estaba equivocado, el código java era válido para android al final no parece que no estoy descatalagado :) lo que le faltaba para la api19 era

Código: Seleccionar todo

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Con las MV de Android Studio y Eclipse ni me enteraba de lo que pasaba, creo que por la deseperación, menudo coñazo. El la tablet es casi instantáneo y puedo ver el vídeo de la url v.mp4 en el navegador sin problemas.

WebView no soy capaz de hacerlo funcionar ni con lo más básico

Código: Seleccionar todo

webView.evaluateJavascript("(fuction(){return \"algo\";})()", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String html) {
        Log.d("HTML", html);
    }
});
o

Código: Seleccionar todo

webView.evaluateJavascript("javascript: (fuction(){return \"algo\";})()", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String html) {
        Log.d("HTML", html);
    }
});
Algo se me debe estar escapando pero a saber qué