Vuoi un invito a Google Wave?
Clicca qui e richiedilo!

Menu

http://www.tuxbay.org/images/menu/home1.gif

http://www.tuxbay.org/images/menu/progetto1.gif

http://www.tuxbay.org/images/menu/cerca1.gif

http://www.tuxbay.org/images/menu/archivio1.gif

http://www.tuxbay.org/images/menu/collegamenti1.gif

http://www.tuxbay.org/images/menu/contattaci1.gif

Statistiche

OS : Linux n
PHP : 5.2.8
MySQL : 5.0.45
Ora : 22:34
Caching : Attivato
GZIP : Disattivato
Utenti : 136
Contenuti : 294
Indirizzi internet : 40
Hits visite contenuti : 658478
JoomlaWatch Stats 1.2.7 by Matej Koval

Countries

89.2%ITALY ITALY
4.1%UNITED STATES UNITED STATES
1.3%UNITED KINGDOM UNITED KINGDOM
0.6%GERMANY GERMANY
0.6%IRELAND IRELAND

Visitors

Today: 41
Last week: 307
This month: 151
Total: 32825


 60 visitatori online
http://www.tuxbay.org/
Hardware
Internet
Linux
News
Software
Varie
 
Scaricare o guardare in un lettore i video di ustream.tv PDF Stampa E-mail
Scritto da array   
Mercoledì 21 Ottobre 2009 11:30

http://tuxbay.org/images/articles/glider.jpg

Su ustream.tv è possibile guardare dei canali in diretta, ma il sito ospita anche delle registrazioni. Tutto questo è bello e comodo ma può essere anche interessante e utile scaricare qualche video sul proprio computer oppure vederlo comodamente senza browser, magari con l'ausilio del lettore multimediale di fiducia. Come si fa? Beh... è molto semplice...

... per salvare o guardare in vlc o qualsiasi lettore multimediale uno di questi video è possibile usare questo script (passate il mouse sul codice e cliccate su copy to clipboard in alto a destra):

#!/bin/bash
#
# Get the FLV url of a recorded video on ustream.tv
# and display it in a media player.
#
# Usage: ./ustream.sh 
#
# videoUrl must be in the form: http://www.ustream.tv/recorded/...
# videoId is the first group of digits in the url.
#
# Examples
#
# ./ustream.sh 12345
# ./ustream.sh http://www.ustream.tv/recorded/12345
# ./ustream.sh http://www.ustream.tv/recorded/12345/highlight/9876
#
# Author: array at email.it
# If you cite me you can use this code as you wish.
# If you don't, you're a very naughty boy.
#

player="vlc"

# ---

reqtmp="`mktemp`"
resptmp="`mktemp`"

video="${1##*recorded/}"
video="${video%%/*}"

len=`printf '%02x' ${#video}`

printf "\x00\x00\x00\x00\x00\x01\x00"            >  "$reqtmp"
printf "\x0fViewer.getVideo\x00\x02/1\x00\x00"   >> "$reqtmp"
printf "\x00\x98\x0a\x00\x00\x00\x01\x03\x00"    >> "$reqtmp"
printf "\x07brandId\x02\x00\x011\x00"            >> "$reqtmp"
printf "\x07videoId\x02\x00\x${len}${video}\x00" >> "$reqtmp"
printf "\x08autoplay\x01\x01\x00"                >> "$reqtmp"
printf "\x00\x09"                                >> "$reqtmp"

wget \
 --header='Content-Type: application/x-amf' \
 --post-file="$reqtmp" \
 -O "$resptmp" \
 'http://216.52.240.138/gateway.php'

url="$(cat "$resptmp" | \
 tr -d '\0' | \
 sed 's/http/\n&/g;s/\.flv/&\n/g' | \
 grep ^http.*\.flv$)"

rm "$reqtmp"
rm "$resptmp"

if [ -z "$url" ]; then
 echo "Url not found."
 exit 1
fi

$player "$url" &

exit 0


Chi è interessato a sapere da dove viene fuori il codice può proseguire la lettura, altrimenti per iniziare a usarlo basta copiare lo script in un file di testo ustream.sh, dargli i permessi di esecuzione (chmod +x ustream.sh) e seguire la sintassi specificata nel sorgente.


Ispezionare il traffico di rete con Wireshark.
Per capire quali richieste effettua il browser al fine di ottenere il flusso video si può usare Wireshark, un programma che permette di analizzare i pacchetti in transito su un'interfaccia di rete (un packet sniffer per chi chiama da fuori Roma).

Aprendo un video di ustream con Wireshark attivo si nota che, dopo aver ottenuto l'oggetto flash che si occupa di riprodurre il filmato e poco prima che inizi il traffico di pacchetti audio/video, il browser effettua una richiesta di tipo "application/x-amf".


ustream.tv - wireshark

Pacchetti http in transito su ustream.tv, nella selezione: la richiesta application/x-amf


Cercando informazioni, si scopre che phpamf è un'applicazione installata sul sito che permette ad un oggetto flash di dialogare con il server secondo uno specifico protocollo, che in pratica costituisce uno strato di applicazione superiore all'http in cui viene incapsulato.

Visualizzando i dettagli vediamo che a seguito di questa richiesta il server invia una risposta che contiene, insieme al resto, anche l'url del file .flv del video:


POST /gateway.php HTTP/1.1
[...]
........Viewer.getVideo../1....
.......rpin...rpin.0.5536720022785292..videoId...840418..autoplay....pageUrl...
%http://www.ustream.tv/recorded/840418... brandId...1...



HTTP/1.1 200 OK
[...]
......AppendToGatewayUrl....6..3?PHPSESSID=3eb839f6fb482c896006b060d9b2d2f599f6
9f10..../1/onResult..null.......moduleConfig...meta...
[...] ..videoName...videos/
flvs/840418..flv..&http://cdn1.ustream.tv/flvs/840418.flv..userId...56554..serv erId...999..
[...] .........thumbnailUrl....success.....


Possiamo cercare di emulare il comportamento del browser con il comando wget, inviando al server una richiesta confezionata in tal modo così da ottenere un listato con l'url che andremo poi ad estrarre.


Wget e l'invio di post data con caratteri speciali.

Il problema principale è che il protocollo di phpamf non è basato su testo: la richiesta (in blu) è composta anche da caratteri speciali non stampabili che Wireshark visualizza come dei puntini.


stringa cruda

La richiesta x-amf visualizzata in vim


Il comando wget permette di inviare dati "crudi" specificandoli in nel parametro --post-data, ma abbiamo dei problemi siccome nella richiesta è presente, tra i vari caratteri speciali, anche il cosiddetto carattere nullo, ovvero il carattere il cui codice ascii è 0, che convezionamente rappresenta il carattere di fine stringa.

Un modo per ovviare al problema è quello di scrivere la richiesta in un file binario e usare il parametro --post-file che wget ci mette a disposizione per inviare al server non una stringa ma il contenuto di un file.

Il file binario della nostra richiesta, visualizzato in un editor esadecimale, è questo:


00000000 00 00 00 00 00 01 00 0F 56 69 65 77 ........View
0000000C 65 72 2E 67 65 74 56 69 64 65 6F 00 er.getVideo.
00000018 02 2F 31 00 00 00 85 0A 00 00 00 01 ./1.........
00000024 03 00 04 72 70 69 6E 02 00 17 72 70 ...rpin...rp
00000030 69 6E 2E 30 2E 35 35 33 36 37 32 30 in.0.5536720
0000003C 30 32 32 37 38 35 32 39 32 00 07 76 022785292..v
00000048 69 64 65 6F 49 64 02 00 06 38 34 30 ideoId...840
00000054 34 31 38 00 08 61 75 74 6F 70 6C 61 418..autopla
00000060 79 01 01 00 07 70 61 67 65 55 72 6C y....pageUrl
0000006C 02 00 25 68 74 74 70 3A 2F 2F 77 77 ..%http://ww
00000078 77 2E 75 73 74 72 65 61 6D 2E 74 76 w.ustream.tv
00000084 2F 72 65 63 6F 72 64 65 64 2F 38 34 /recorded/84
00000090 30 34 31 38 00 07 62 72 61 6E 64 49 0418..brandI
0000009C 64 02 00 01 31 00 00 09             d...1...



Dato che vogliamo creare uno script per scaricare tutti i video e non solo quello con id 840418, abbiamo la necessità di confezionare un file del genere "al volo" con l'id che vogliamo per poi inviarne il contenuto al server.

Un modo per scrivere un file contenente caratteri non stampabili da shell è quello di usare il comando printf, che ci dà la possibilità di menzionare un carattere con la notazione \xHH dove HH è il codice ascii in base 16 del carattere.


Tradurre in notazione esadecimale i caratteri non stampabili

Resta il problema di convertire il binario della richiesta, di cui disponiamo, in un testo in cui i caratteri non stampabili sono espressi in notazione \xHH. Un piccolo programma in c può essere utile a questo scopo.

#include 

/*
 * Print a file escaping unprintable characters (0-31, 127-?)
 * according to the PRINTF(1) hexadecimal format \xHH
 *
 * array at email.it - Public domain
 */

int main(int argc, char* argv[])
{
   FILE* in;
   unsigned int c;

   if (!(in = (argc == 1) ? stdin : fopen(argv[1], "r")))
   {
      printf("Error opening file\n", stderr);
      return 1;
   }

   while ((c = fgetc(in)) != EOF)
   {
      if((32 <= c) && (c <= 126))
         printf("%c", c);
      else
         printf("\\x%02x", c);
   }

   fclose(in);
   return 0;
}


Ecco la stringa che otteniamo in uscita:

\x00\x00\x00\x00\x00\x01\x00\x0fViewer.getVideo\x00\x02/1\x00\x00\x00\x85\x0a\x00\x00\x00\x01\x03\x00\x04rpin\x02\x00\x17rpin.0.5536720022785292\x00\x07videoId\x02\x00\x06840418\x00\x08autoplay\x01\x01\x00\x07pageUrl\x02\x00%http://www.ustream.tv/recorded/840418\x00\x07brandId\x02\x00\x011\x00\x00\x09


Creazione della richiesta x-amf

Possiamo utilizzarla nel comando printf per confezionare il file della richiesta. Disponendola in maniera un po' più intellegibile e confrontando le diverse stringhe di richiesta di più video possiamo accorgerci di qualche dettaglio:


stringa della richiesta

La stringa della richiesta viene stampata nel file req


Un po' di ingegneria inversa ci fa capire che il byte evidenziato in verde deve specificare la dimensione in caratteri dell'id del video. A questo punto siamo in grado di confezionare le richieste x-amf per ottenere l'url del documento .flv. Per estrarre quest'ultimo dalla risposta del server, basterà una semplice grep come si può vedere nel codice dello script.


Alternative.
Qui è disponibile il codice C equivalente a quello dello script proposto in questo articolo. Lo si può compilare con il seguente comando:

gcc ustream.c -o ustream

La sintassi è disponibile chiamando il programma senza parametri.

Qui è disponibile anche una estensione per Firefox: è un contenitore (wrapper) del programma in C, quindi utilizzabile su piattaforme i386, che fa comparire due voci nel menu Strumenti. Se siete i possessori di una distribuzione a 64 bit occorre scaricare il sorgente, compilarlo e sostituirlo all'eseguibile nella cartella dell'estensione.


Add this page to your favorite Social Bookmarking websites
Reddit! Del.icio.us! Mixx! Free and Open Source Software News Google! Live! Facebook! StumbleUpon! TwitThis Joomla Free PHP
Ultimo aggiornamento Giovedì 17 Giugno 2010 10:20
 

Aggiungi commento


Codice di sicurezza
Aggiorna

 
La toolbar di tuxbay.org
http://www.andromedafree.it/ Nuove stazioni TV!

http://www.tuxbay.org/images/toolbar.gif

Clicca qui per configurarla! Non vedi i canali televisivi? Clicca qui per risolvere il problema
Translate