Descargar vídeos de TVE

Nota: Este programa está discontinuado. Hay una versión mejorada y actualizada en http://www.carballude.es/blog/?p=1019

Hace algún tiempo publiqué un Script para descargar vídeos de TVE. Desgraciadamente cambiaron su sistema y dejó de funcionar. Sin embargo, ayer necesité descargar algunos vídeos porque no iba a tener conexión así que me puse manos a la obra e investigué su sistema. A continuación explicaré cómo descargar los vídeos manualmente y publicaré el código de un programa en C# y un script de PowerShell que automatizan el proceso.

Funcionamiento del sistema

Cuando se accede a un vídeo de TVE la dirección que obtenemos es similar a esta: http://www.rtve.es/mediateca/videos/20100814/jovenes-solistas/851513.shtml. Realmente sólo nos interesa el nombre del fichero shtml, en este caso 851513, para hacerlo genérico, digamos que es de la forma abcdef.

Por cada fichero shtml de ese aspecto, tenemos un fichero xml que da detalles sobre el vídeo que ofrece. La URL de ese xml se construye de la forma: http://www.rtve.es/swf/data/es/videos/video/f/e/d/c/abcdef.xml. En el caso de nuestro ejemplo, la dirección que formaríamos sería: http://www.rtve.es/swf/data/es/videos/video/3/1/5/1/851513.xml

Llegados a este punto, pueden pasar dos cosas. Algunos xml contienen el elemento <file>URL</file>, si este fuera el caso, no hay más que hacer, esa es la dirección desde la que podríamos descargar el fichero. Sin embargo, algunos xml (como el de nuestro ejemplo) contienen <file/>, con lo que no tenemos ni idea de dónde puede estar.

De ocurrir eso, tendríamos que seguir leyendo el xml hasta encontrar una referencia a assetDataId:: seguido de otro código de 6 dígitos, 527620 en el caso del ejemplo. Dicho código nos servirá para formar una url con la siguiente fórmula: http://www.rtve.es/scd/CONTENTS/ASSET_DATA_VIDEO/f/e/d/c/ASSET_DATA_VIDEO-abcdef.xml. En nuestro caso obtenemos: http://www.rtve.es/scd/CONTENTS/ASSET_DATA_VIDEO/0/2/6/7/ASSET_DATA_VIDEO-527620.xml.

Dentro de ese xml encontraremos el atributo defaultLocation, y nos interesa la ruta desde /flv, a la que antecederemos de http://www.rtve.es/resources/TE_NGVA. Es decir, en nuestro ejemplo obtenemos:

1
defaultLocation="/deliverty/demo/resources/flv/8/9/1281768459498.flv"

Que debemos cambiar por: http://www.rtve.es/resources/TE_NGVA/flv/8/9/1281768459498.flv y ya estaremos listos para descargar el fichero :)

Si alguien se pregunta cómo he descubierto el sistema, simplemente he leído los ficheros shtml y xml y he analizado el tráfico que enviaba el reproductor Flash de TVE con Wireshark, siguiendo el método que ya empleé para GoEar y que explico en http://www.carballude.es/blog/?p=444

Programa en C#

Como me parecía muy pesado hacer todo esto a mano, me he creado un sencillo programa en C# que automatiza el proceso. Podéis descargároslo junto con su código fuente, pero que nadie tome ese código para nada “serio”. Es una chapuza del quince, son cuatro líneas puestas juntas para hacer lo justo, basta con mostraros esto:

1
2
3
4
5
        public Form1()
        {
            CheckForIllegalCrossThreadCalls = false; //Smelly
            InitializeComponent();
        }

Os dejo una capturilla:

Script PowerShell

Últimamente me estoy aficionando mucho a PowerShell y casi siempre la tengo a mano, así que me he decidido a hacerme un script que me ayude en la tarea. Tal y como está hace lo mismo que el programa en C#, pero si tenéis wget en vuestro sistema, descomentando la línea que indico haréis que además os lo baje ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function PrintBanner()
{
	Write-Host "TVE Revealer for PowerShell - v0.1"
	Write-Host "Pablo Carballude - 16/08/2010"
	Write-Host ""
}
 
function DownloadFileFromURL([string]$url)
{
	$aux = $url.Split('/')
	$id = $aux[$aux.Count-1].Split('.')[0]
	$url = "http://www.rtve.es/swf/data/es/videos/video/" + $id[5] + "/" + $id[4] + "/" + $id[3] + "/" + $id[2] + "/" + $id + ".xml";
	$content = (new-object net.webclient).DownloadString($url);
	if ($content.Contains("<file/>")) 
	{
		$aux = [regex]::split($content, "assetDataId::")[1]
		$id = $aux.Split('"')[0]
		$url = "http://www.rtve.es/scd/CONTENTS/ASSET_DATA_VIDEO/" + $id[5] + "/" + $id[4] + "/" + $id[3] + "/" + $id[2] + "/ASSET_DATA_VIDEO-" + $id + ".xml";
		$content = (new-object net.webclient).DownloadString($url)
		$url = [regex]::split($content,"defaultLocation=""/deliverty/demo/resources/")[1]
		$url = "http://www.rtve.es/resources/TE_NGVA/" + $url.Split('"')[0]
	} else {
		$aux = [regex]::split($content, "<file>")[1]
		$url = [regex]::split($aux,"</file>")[0]
	}
	Write-Host $url
	#Uncoment the following line to download the file with wget
	#wget $url
}
 
PrintBanner
DownloadFileFromURL($args[0])

About the Author

Me llamo Pablo Carballude González, soy graduado en computación con master en HCI y Seguridad Informática. Actualmente trabajo para Amazon en Seattle como Software Developer Engineer. Soy de esas personas que no saben si los textos autobiográficos deben ser en primera o tercera persona. Lo intenté en segunda, pero no le entendí nada :P