Shell Script для загрузки файлов youtube из плейлиста - программирование
Подтвердить что ты не робот

Shell Script для загрузки файлов youtube из плейлиста

Я пытаюсь написать bash script, который загрузит все видеоролики youtube из списка воспроизведения и сохранит их до определенного имени файла, основанного на заголовке самого видео YouTube. Пока у меня есть два отдельных фрагмента кода, которые делают то, что я хочу, но я не знаю, как их объединить, чтобы функционировать как единое целое.

Этот фрагмент кода находит заголовки всех видеороликов YouTube на данной странице:

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

И этот кусок кода загружает файлы в имя файла, заданное идентификатором видео YouTube (например, имя файла, данное youtube.com/watch?v= CsBVaJelurE&feature=relmfu, будет CsBVaJelurE.flv)

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

Я хочу script, который выведет файл youtube.flv в имя файла, заданное заголовком видео (в данном случае bash урок 2.flv), а не просто имя идентификатора видео. Заранее благодарим за помощь.

4b9b3361

Ответ 1

Итак, после дальнейших исследований и обновления моей версии youtube-dl, оказывается, что эта функциональность теперь встроена непосредственно в программу, что отрицает необходимость использования оболочки script для решения проблемы загрузки списка воспроизведения на youtube. Полная документация может быть найдена здесь: (http://rg3.github.com/youtube-dl/documentation.html), но простое решение для моего первоначального вопроса выглядит следующим образом:

1) youtube-dl автоматически обработает ссылку списка воспроизведения, нет необходимости индивидуально подавать URL-адреса содержащихся в нем видео (это отрицает необходимость использования grep для поиска "watch?", чтобы найти уникальный идентификатор видео

2) теперь имеется опция для форматирования имени файла с различными параметрами, включая:

  • id: последовательность будет заменена идентификатором видео.
  • url: последовательность будет заменена URL-адресом видео.
  • uploader: последовательность будет заменена псевдонимом человека, который загрузил видео.
  • upload_date: последовательность будет заменена датой загрузки в формате YYYYMMDD.
  • title: Последовательность будет заменена буквальным заголовком видео.
  • stitle: Последовательность будет заменена упрощенным названием видео, ограничено буквенно-цифровыми символами и тире.
  • ext: последовательность будет заменена соответствующим расширением (например, flv или mp4).
  • epoch: последовательность будет заменена эпохой Unix при создании файл.
  • autonumber: последовательность будет заменена пятизначным числом, которое будет увеличена при каждой загрузке, начиная с нуля.

синтаксис для этой опции вывода следующий (где NAME - любой из приведенных выше параметров):

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

В качестве примера, чтобы ответить на мой первоначальный вопрос, синтаксис выглядит следующим образом:

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

Еще раз спасибо тем, кто ответил на мой вопрос, ваша помощь очень ценится.

Ответ 2

Если вы хотите использовать заголовок на странице youtube в качестве имени файла, вы можете использовать -t вариант youtube-dl. Если вы хотите использовать заголовок со своей страницы "список видео", и вы уверены, что для каждого заголовка <span class="title video-title" имеется ровно один URL watch?, вы можете использовать что-то вроде этого:

#!/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

Я не тестировал его, потому что у меня нет примера с "списком видео".

Ответ 3

этот следующий метод работает и играет на вас титаник с 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}"

Он использует декодирование и bash, которые вы, возможно, установили.

Ответ 4

Я использую этот bash script для загрузки определенного набора песен из данного списка воспроизведения 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

Примечание. "Ключевое слово i" - это заголовок (целиком или частично, если часть, она должна быть уникальной для этого списка воспроизведения) данного видео в этом списке воспроизведения.

Изменить: вы можете установить youtube-dl с помощью pip install youtube-dl

Ответ 5

#!/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