fpunktk
Anmeldungsdatum: 24. Oktober 2007
Beiträge: 142
|
Ich habe einige Kanäle von youtube in meinem rss-Reader abonniert und hatte es satt, die Videos immer einzeln per Hand mit youtube-dl herunter zu laden. Also musste ein kleines Script her, dass automatisch die Feeds auf neue Videos überprüft und diese dann herunterlädt. Meine Lösung ist recht kurz, aber ich finde sie ganz elegant, deswegen stelle ich sie hier vor. 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
33
34
35 | #!/bin/dash
# Script um automatisiert neue Videos aus youtube-rss-Feeds herunter zu laden
# Copyright (C) 2011 Felix Kästner, youtube-feed-downloader @ f p u n k t k . de
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program; if not, see http://www.gnu.org/licenses/.
feedlist_filename='/pfad/zur/liste/mit/den/feeds'
downloaded_list_filename='/pfad/zur/liste/mit/den/heruntergeladenen/videos'
# Pfad zu youtube-dl mit passenden Optionen
ytdl_bin_opts='/pfad/zu/youtube-dl --max-quality=34 --no-mtime --no-part -o /zielpfad/füe/die/heruntergeladenen/videos/%(uploader)s-%(stitle)s-%(id)s.%(ext)s'
# wenn die feedlist nur youtube-Feeds enthält:
vids="$(/usr/bin/wget -O - -nv -i "$feedlist_filename" | /bin/grep -Eo 'http://www.youtube.com/watch\?v=[^&"]*' | /usr/bin/sort -u)"
# Wenn die feedlist nicht nur youtube-Feeds enthält:
vids="$(/bin/grep -F 'http://gdata.youtube.com/feeds/' "$feedlist_filename" | /usr/bin/wget -O - -nv -i - | /bin/grep -Eo 'http://www.youtube.com/watch\?v=[^&"]*' | /usr/bin/sort -u)"
# $vids enthält jetzt jeden Link zu einem Video aus den Feeds genau ein mal
oldvids="$(/bin/cat "$downloaded_list_filename" "$downloaded_list_filename")"
# $oldvids enthält jetzt alle Links zu bereits heruntergeladenen Videos (genau) zwei mal
# jetzt werden aus den bereits heruntergeladenen Links und den Links aus den Feeds diese herausgesucht, die nur genau ein mal vorhanden sind, das sind die neuen Links
newvids="$(echo "$oldvids\n$vids" | /usr/bin/sort | /usr/bin/uniq -u)"
if [ "$newvids" != "" ]
then
# die neuen Links an die Liste der bereits heruntergeladenen Links anhängen
echo "$newvids" >> "$downloaded_list_filename"
# die neuen Links mit youtube-dl herunterladen
$ytdl_bin_opts $newvids
else
echo "es gibt keine neuen Videos"
fi
|
Zu beachten ist, dass das Script für Dash gemacht ist. Bei Verwendung der Bash muss man zumindest die Option -e an das echo in Zeile 25 anhängen. Über meinungen, Kritik und Lob freue ich mich ☺
|
Mobai
Anmeldungsdatum: 4. Februar 2011
Beiträge: 259
|
http://www.youtube.com/t/terms Also ist es verboten, Videos runterzuladen...
Oder nicht?
|
kutteldaddeldu
Anmeldungsdatum: 1. Juli 2008
Beiträge: 3586
|
Du bist, wie es bei einem solchen Thema natürlich ist, selbstverständlich nicht der/die Erste, der/die sich diese Frage stellt – was Du mit einer kurzen Foren-/Google-/Was-auch-immer-Suche leicht herausfinden hättest können. @fpunktk: Nettes Skript!
|
fpunktk
(Themenstarter)
Anmeldungsdatum: 24. Oktober 2007
Beiträge: 142
|
Kleines Update: Es hat mich noch genervt, dass der Download recht lange dauert, weil die Geschwindigkeit seitens youtube begrenzt wird. Also wollte ich, dass mehrere Downloads parallel laufen. Erster Ansatz dafür war, die Liste der Videos aufzuteilen. Das funktionierte aber nicht so gut. Der zweite Ansatz ist eine FIFO-Warteschlange und folgt jetzt hier: 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 | #!/bin/dash
# Script um automatisiert neue Videos aus youtube-rss-Feeds herunter zu laden
# Copyright (C) 2011 Felix Kästner, youtube-feed-downloader @ f p u n k t k . de
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program; if not, see http://www.gnu.org/licenses/.
feedlist_filename='/pfad/zur/liste/mit/den/feeds'
downloaded_list_filename='/pfad/zur/liste/mit/den/heruntergeladenen/videos'
# Pfad zu youtube-dl mit passenden Optionen
ytdl_bin_opts='/pfad/zu/youtube-dl --max-quality=34 --no-mtime --no-part -o /zielpfad/füe/die/heruntergeladenen/videos/%(uploader)s-%(stitle)s-%(id)s.%(ext)s'
max_parallel="1 2 3 4 5" # Maximalzahl der parallel laufenden Instanzen von youtube-dl, eine for-Schleife iteriert durch diese Variable. Ein guter Wert scheint (verfügbare Bandbreite in kB/s durch 130 kB/s) zu sein.
# wenn die feedlist nur youtube-Feeds enthält:
vids="$(/usr/bin/wget -O - -nv -i "$feedlist_filename" | /bin/grep -Eo 'http://www.youtube.com/watch\?v=[^&"]*' | /usr/bin/sort -u)"
# Wenn die feedlist nicht nur youtube-Feeds enthält:
vids="$(/bin/grep -F 'http://gdata.youtube.com/feeds/' "$feedlist_filename" | /usr/bin/wget -O - -nv -i - | /bin/grep -Eo 'http://www.youtube.com/watch\?v=[^&"]*' | /usr/bin/sort -u)"
# $vids enthält jetzt jeden Link zu einem Video aus den Feeds genau ein mal
oldvids="$(/bin/cat "$downloaded_list_filename" "$downloaded_list_filename")"
# $oldvids enthält jetzt alle Links zu bereits heruntergeladenen Videos (genau) zwei mal
# jetzt werden aus den bereits heruntergeladenen Links und den Links aus den Feeds diese herausgesucht, die nur genau ein mal vorhanden sind, das sind die neuen Links
newvids="$(echo "$oldvids\n$vids" | /usr/bin/sort | /usr/bin/uniq -u)"
if [ "$newvids" != "" ]
then
# die neuen Links an die Liste der bereits heruntergeladenen Links anhängen
echo "$newvids" >> "$downloaded_list_filename"
# fifo-pipe aufbauen:
pipename="$(/bin/mktemp -u)" # einen (hoffentlich) sicheren temporären Dateinamen erzeugen
# fifo-pipe erzeugen, an FD 3 zuweisen, fifo-pipe löschen, Zuweisung bleibt erhalten
/usr/bin/mkfifo "$pipename"
exec 3<>"$pipename"
/bin/rm "$pipename"
# die Links zeilenweise in die Pipe schreiben
for vid in $newvids
do
echo $vid >&3
done
pids=""
for i in $max_parallel
do
echo "stop" >&3 # damit die folgende while-Schleife auch irgendwann abbricht (read wartet sonst ewig auf Eingabe)
{ # Kindprozess im Hintergrund
ytdl_err=0
while read vid
do
[ "$vid" = "stop" ] && break
$ytdl_bin_opts $vid || ytdl_err="$?"
done <&3
return $ytdl_err
} &
pids="$pids $!"
done
echo "pids: $pids" # die PIDs der Kindprozesse ausgeben
trap "echo; echo kill $pids; /bin/kill $pids; exec 3>&-; exit" INT TERM # Signale Abfangen, um das Script und die Kindprozesse ordnungsgemäß beenden zu können (z.B. mit Strg + c)
# einzeln auf die Kindprozesse warten, Exitcodes bereits beendeter Prozesse werden auch beachtet
ytdl_err=0
for pid in $pids
do
wait $pid || ytdl_err="$?"
done
exec 3>&- # FD 3 schließen
[ $ytdl_err -ne 0 ] && echo "Probleme beim Download" && exit $ytdl_err
else
echo "es gibt keine neuen Videos"
fi
|
Ein paar kleine Nachteile hat das aber noch:
Die Ausgabe der einzelnen Instanzen von youtube-dl überlagern sich. Das finde ich aber nicht weiter schlimm. Es ist nicht reproduzierbar vorgekommen, dass die Warteschlange falsch befüllt wurde, also Zeilenumbrüche fehlten. Wenn das passiert, kann das Script hängen bleiben. Dafür habe ich keine Lösung.
Man kann das Script natürlich auch umbauen, um parallel mehrere Videos herunter zu laden, die man per Kommandozeilenoption oder in einer Datei übergibt. Die Umsetzung überlasse ich dem Leser als Übung ☺
|