2012-01-19 10 views
16

Sto provando a scrivere uno script di bash che scaricherà tutti i video di youtube da una playlist e li salverà su un nome di file specifico basato sul titolo del video stesso. Finora ho due pezzi di codice separati che fanno ciò che voglio ma non so come combinarli insieme per funzionare come una unità.Shell Script per scaricare i file di youtube dalla playlist

questo pezzo di codice trovano i titoli di tutti i video di YouTube su una determinata pagina:

curl -s "$1" | grep '<span class="title video-title "' | cut -d\> -f2 | cut -d\< -f1 

E questo pezzo di codice scarica i file ad un nome di file proposta dal ID del Video YouTube (ad esempio, il nome del file data dal youtube.com/watch?v= CsBVaJelurE & funzione = relmfu sarebbe CsBVaJelurE.flv)

curl -s "$1" | grep "watch?" | cut -d\" -f4| while read video; 
do youtube-dl "http://www.youtube.com$video"; 
done 

voglio uno script che sarà in uscita il file .flv youtube per un nome di file in t itle del video (in questo caso BASH lesson 2.flv) piuttosto che semplicemente il nome dell'ID video. Grazie in anticipo per tutto l'aiuto.

+0

+1 per ur domanda –

+0

Questo è senza dubbio il miglior script scaricare Youtube là fuori: https://bitbucket.org/rg3/youtube-dl/wiki/Home Poiché tutti questi script si riferiscono alle pagine di scraping, è necessario rimanere aggiornati sulla struttura del sito. Può includere il titolo del video nel nome del file. –

+0

Buona telefonata a Niklas alla consegna del link dl per la sceneggiatura; Ecco un link dedicato con maggiori informazioni, documentazione e dati degli sviluppatori: http://rg3.github.com/youtube-dl/. La gente dovrebbe assolutamente scaricare, è un ottimo script – wvandaal

risposta

21

OK quindi dopo ulteriori ricerche e aggiornamento della mia versione di youtube-dl, si scopre che questa funzionalità è ora integrata direttamente nel programma, annullando la necessità di uno script di shell per risolvere il problema di download della playlist su youtube. La documentazione completa può essere trovata qui: (http://rg3.github.com/youtube-dl/documentation.html) ma la soluzione semplice alla mia domanda originale è la seguente:

1) youtube-dl elaborerà automaticamente un collegamento di playlist, non è necessario alimentarlo singolarmente gli URL di i video in esso contenuti (questo nega la necessità di usare grep per cercare "watch?" per trovare l'id univoco

2) c'è ora un'opzione inclusa per formattare il nome file con una varietà di opzioni tra cui:

  • id: la sequenza verrà sostituita dall'identificatore video.
  • url: la sequenza verrà sostituita dall'URL del video.
  • uploader: la sequenza verrà sostituita dal nickname della persona che ha caricato il video.
  • upload_date: la sequenza verrà sostituita dalla data di caricamento nel formato AAAAMMGG.
  • titolo: la sequenza verrà sostituita dal titolo del video letterale.
  • stitle: la sequenza verrà sostituita da un titolo video semplificato, limitato a caratteri alfanumerici e trattini.
  • ext: la sequenza verrà sostituita dall'estensione appropriata (come flv o mp4).
  • epoca: la sequenza verrà sostituita dall'epoca Unix durante la creazione del file .
  • numero autonum .: la sequenza verrà sostituita da un numero a cinque cifre che verrà aumentato a ogni download con il numero a partire da zero.

la sintassi per questa opzione di uscita è la seguente (dove NOME è una delle opzioni mostrate sopra):

youtube-dl -o '%(NAME)s' http://www.youtube.com/your_video_or_playlist_url 

A titolo di esempio, di rispondere alla mia domanda iniziale, la sintassi è la seguente:

youtube-dl -o '%(stitle)s.%(ext)s' http://www.youtube.com/playlist?list=PL2284887FAE36E6D8&feature=plcp 

Grazie ancora a coloro che hanno risposto alla mia domanda, il vostro aiuto è molto apprezzato.

1

Se si desidera utilizzare il titolo della pagina di youtube come nome file, è possibile utilizzare l'opzione -t di youtube-dl. Se si desidera utilizzare il titolo dalla pagina "lista dei video" e assicurarsi che ci sia esattamente un watch? URL per ogni <span class="title video-title" titolo, quindi si può usare qualcosa di simile:

#!/bin/bash 

TMPFILE=/tmp/downloader-$$ 

onexit() { 
    rm -f $TMPFILE 
} 

trap onexit EXIT 

curl -s "$1" -o $TMPFILE 

i=0 
grep '<span class="title video-title "' $TMPFILE | cut -d\> -f2 | cut -d\< -f1 | while read title; do 
    titles[$i]=$title 
    ((i++)) 
done 

i=0 
grep "watch?" $TMPFILE | cut -d\" -f4 | while read url; do 
    urls[$i]="http://www.youtube.com$url" 
    ((i++)) 
done 

i=0; while ((i < ${#urls[@]})); do 
    youtube-dl -o "${titles[$i]}.%(ext)" "${urls[$i]}" 
    ((i++)) 
done 

non ho provato perché Non ho un esempio di pagina "elenco video".

+0

Grazie per la risposta praetorian, l'opzione -t funziona per il tempo ma lo script che hai fornito contiene degli errori che dovrò controllare. Attualmente i file stessi non vengono scaricati ma non ho ancora avuto il tempo di testare il tuo script e vedere perché. Terrò questo thread aggiornato se trovo qualcosa. – wvandaal

+0

Bene, come ho detto, non ho esempi di dati di input per testare lo script ... –

-2
#!/bin/bash 
# Coded by Biki Teron 
# String replace command in linux 

echo "Enter youtube url:" 
read url1 

wget -c -O index.html $url1 
################################### Linux string replace ################################################## 
sed -e 's/%3A%2F%2F/:\/\//g' index.html > youtube.txt 
sed -i 's/%2F/\//g' youtube.txt 
sed -i 's/%3F/?/g' youtube.txt 
sed -i 's/%3D/=/g' youtube.txt 
sed -i 's/%26/\&/g' youtube.txt 
sed -i 's/%252/%2/g' youtube.txt 
sed -i 's/sig/&signature/g' youtube.txt 
## command to get filename 
nawk '/<title>/,/<\/title>/' youtube.txt > filename.txt ## Print the line between containing <title> and <\/title> . 
sed -i 's/.*content="//g' filename.txt 
sed -i 's/">.*//g' filename.txt 
sed -i 's/.*<title>//g' filename.txt 
sed -i 's/<.*//g' filename.txt 
######################################## Coding to get all itag list ######################################## 

nawk '/"fmt_list":/,//' youtube.txt > fmt.html ## Print the line containing "fmt_list": . 
sed -i 's/.*"fmt_list"://g' fmt.html 
sed -i 's/, "platform":.*//g' fmt.html 
sed -i 's/, "title":.*//g' fmt.html 

# String replace command in linux to get correct itag format 
sed -i 's/\\\/1920x1080\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/1920x1080\/99\/0\/0 by blank . 
sed -i 's/\\\/1920x1080\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/1920x1080\/9\/0\/115 by blank. 
sed -i 's/\\\/1280x720\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/1280x720\/99\/0\/0 by blank. 
sed -i 's/\\\/1280x720\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/1280x720\/9\/0\/115 by blank. 
sed -i 's/\\\/854x480\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/854x480\/99\/0\/0 by blank. 
sed -i 's/\\\/854x480\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/854x480\/9\/0\/115 by blank. 
sed -i 's/\\\/640x360\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/640x360\/99\/0\/0 by blank. 
sed -i 's/\\\/640x360\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/640x360\/9\/0\/115 by blank. 
sed -i 's/\\\/640x360\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/640x360\/9\/0\/115 by blank. 
sed -i 's/\\\/320x240\\\/7\\\/0\\\/0//g'  fmt.html ## Replace \/320x240\/7\/0\/0 by blank. 
sed -i 's/\\\/320x240\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/320x240\/99\/0\/0 by blank. 
sed -i 's/\\\/176x144\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/176x144\/99\/0\/0 by blank. 

# Command to cut a part of a file between any two strings 
nawk '/"url_encoded_fmt_stream_map":/,//' youtube.txt > url.txt 
sed -i 's/.*url_encoded_fmt_stream_map"://g' url.txt 

#Display video resolution information 
echo "" 
echo "Video resolution:" 
echo "[46=1080(.webm)]--[37=1080(.mp4)]--[35=480(.flv)]--[36=180(.3gpp)]" 
echo "[45=720 (.webm)]--[22=720 (.mp4)]--[34=360(.flv)]--[17=144(.3gpp)]" 
echo "[44=480 (.webm)]--[18=360 (.mp4)]--[5=240 (.flv)]" 
echo "[43=360 (.webm)]" 
echo "" 
echo "itag list= "`cat fmt.html` 
echo "Enter itag number: " 
read fmt 

####################################### Coding to get required resolution ################################################# 
## cut itag=? 

sed -e "s/.*,itag=$fmt//g" url.txt > "$fmt"_1.txt 
sed -e 's/\u0026quality.*//g' "$fmt"_1.txt > "$fmt".txt 
sed -i 's/.*u0026url=//g' "$fmt".txt ## Ignore all lines before \u0026url= but print all lines after \u0026url=. 
sed -e 's/\u0026type.*//g' "$fmt".txt > "$fmt"url.txt ## Ignore all lines after \u0026type but print all lines before \u0026type. 
sed -i 's/\\/\&/g' "$fmt"url.txt ## replace \ by & 
sed -e 's/.*\u0026sig//g' "$fmt".txt > "$fmt"sig.txt ## Ignore all lines before \u0026sig but print all lines after \u0026sig. 
sed -i 's/\\/\&ptk=machinima/g' "$fmt"sig.txt ## replace \ by & 
echo `cat "$fmt"url.txt``cat "$fmt"sig.txt` > "$fmt"url.txt ## Add string at the end of a line 
echo `cat "$fmt"url.txt` > link.txt ## url and signature content to 44url.txt 
rm "$fmt"sig.txt 
rm "$fmt"_1.txt 
rm "$fmt".txt 
rm "$fmt"url.txt 
rm youtube.txt 
########################################### Coding for filename with correct extension ##################################### 
if [ $fmt -eq 46 ] 
then 
    echo `cat filename.txt`.webm > filename.txt 

elif [ $fmt -eq 45 ] 
    then 
    echo `cat filename.txt`.webm > filename.txt 

elif [ $fmt -eq 44 ] 
    then 
    echo `cat filename.txt`.webm > filename.txt 

elif [ $fmt -eq 43 ] 
    then 
    echo `cat filename.txt`.webm > filename.txt 

elif [ $fmt -eq 37 ] 
    then 
    echo `cat filename.txt`.mp4 > filename.txt 

elif [ $fmt -eq 22 ] 
    then 
    echo `cat filename.txt`.mp4 > filename.txt 

elif [ $fmt -eq 18 ] 
    then 
    echo `cat filename.txt`.mp4 > filename.txt 

elif [ $fmt -eq 35 ] 
    then 
    echo `cat filename.txt`.flv > filename.txt 

elif [ $fmt -eq 34 ] 
    then 
    echo `cat filename.txt`.flv > filename.txt 

elif [ $fmt -eq 5 ] 
    then 
    echo `cat filename.txt`.flv > filename.txt 

elif [ $fmt -eq 36 ] 
    then 
    echo `cat filename.txt`.3gpp > filename.txt 

else 
    echo `cat filename.txt`.3gpp > filename.txt 

fi 
rm fmt.html 
rm url.txt 
filename=`cat filename.txt` 
linkdownload=`cat link.txt` 
wget -c -O "$filename" $linkdownload 
echo "Download Finished!" 
read 
+1

Sto imparando lo script di bash nel download di video di youtube basato sull'ultimo algoritmo di youtube. Visualizzerà tutta la risoluzione video disponibile. È possibile scaricare i formati di file .webm, .mp4, .flv, .3gpp. – Teron

+0

Scusa ma questo non ha nulla a che fare con la domanda originale, -1. – etuardu

0

questa seguente metodo di lavoro e si gioca titanico da youtube

youtube-downloader.sh youtube-video-url.sh

#!/bin/bash 
decode() { 
    to_decode='s:%([0-9A-Fa-f][0-9A-Fa-f]):\\x\1:g' 
    printf "%b" `echo $1 | sed 's:&:\n:g' | grep "^$2" | cut -f2 -d'=' | sed -r $to_decode` 
} 
data=`wget http://www.youtube.com/get_video_info?video_id=$1\&hl=pt_BR -q -O-` 
url_encoded_fmt_stream_map=`decode $data 'url_encoded_fmt_stream_map' | cut -f1 -d','` 
signature=`decode $url_encoded_fmt_stream_map 'sig'` 
url=`decode $url_encoded_fmt_stream_map 'url'` 
test $2 && name=$2 || name=`decode $data 'title' | sed 's:+: :g;s:/:-:g'` 
test "$name" = "-" && name=/dev/stdout || name="$name.vid" 
wget "${url}&signature=${signature}" -O "$name" 






#!/usr/bin/env /bin/bash 
function youtube-video-url { 
    local field= 
    local data= 
    local split="s:&:\n:g" 
    local decode_str='s:%([0-9A-Fa-f][0-9A-Fa-f]):\\x\1:g' 
    local yt_url="http://www.youtube.com/get_video_info?video_id=$1" 
    local grabber=`command -v curl` 
    local args="-sL" 
    if [ ! "$grabber" ]; then 
     grabber=`command -v wget` 
     args="-qO-" 
    fi 
    if [ ! "$grabber" ]; then 
     echo 'No downloader available.' >&2 
     test x"${BASH_SOURCE[0]}" = x"$0" && exit 1 || return 1 
    fi 
    function decode { 
     data="`echo $1`" 
     field="$2" 
     if [ ! "$field" ]; then 
      field="$1" 
      data="`cat /dev/stdin`" 
     fi 
     data=`echo $data | sed $split | grep "^$field" | cut -f2 -d'=' | sed -r $decode_str` 
     printf "%b" $data 
    } 
    local map=`$grabber $args $yt_url | decode 'url_encoded_fmt_stream_map' | cut -f1 -d','` 
    echo `decode $map 'url'`\&signature=`decode $map 'sig'` 
} 
[ $SHLVL != 1 ] && export -f youtube-video-url 

bash youtube-player.sh saalGKY7ifU

#!/bin/bash 
decode() { 
    to_decode='s:%([0-9A-Fa-f][0-9A-Fa-f]):\\x\1:g' 
    printf "%b" `echo $1 | sed 's:&:\n:g' | grep "^$2" | cut -f2 -d'=' | sed -r $to_decode` 
} 


data=`wget http://www.youtube.com/get_video_info?video_id=$1\&hl=pt_BR -q -O-` 


url_encoded_fmt_stream_map=` decode $data 'url_encoded_fmt_stream_map' | cut -f1 -d','` 

signature=` decode $url_encoded_fmt_stream_map 'sig'` 

url=`decode $url_encoded_fmt_stream_map 'url'` 
test $2 && name=$2 || name=`decode $data 'title' | sed 's:+: :g;s:/:-:g'` 


test "$name" = "-" && name=/dev/stdout || name="$name.mp4" 

# // wget "${url}&signature=${signature}" -O "$name" 

mplayer -zoom -fs "${url}&signature=${signature}" 

Usa decode e bash, che potresti avere installato.

0

Io uso questo script bash per scaricare un dato insieme di canzoni da un dato playlist di YouTube

#!/bin/bash 
downloadDirectory = <directory where you want your videos to be saved> 
playlistURL = <URL of the playlist> 
for i in {<keyword 1>,<keyword 2>,...,<keyword n>}; do 
    youtube-dl -o ${downloadDirectory}"/youtube-dl/%(title)s.%(ext)s" ${playlistURL} --match-title $i 
done 

Nota: "parola chiave i" è il titolo (in parte tutto o, se parte, dovrebbe essere unico a quella playlist) di un determinato video in quella playlist.

Edit: è possibile installare youtube-dl da Pip installare youtube-dl

Problemi correlati