2012-01-19 75 views
16

我正在尝试编写一个bash脚本,它将从播放列表中下载所有的youtube视频,并根据YouTube视频本身的标题将它们保存到特定的文件名。到目前为止,我有两个独立的代码片段,可以完成我想要的功能,但我不知道如何将它们组合在一起以作为一个单元。Shell脚本从播放列表下载YouTube文件

这段代码找到一个给定的页面上所有的YouTube视频的标题:

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

这一段代码下载文件由YouTube视频ID给出的文件名(如文件名通过youtube.com/watch?v= CsBVaJelurE &功能给出= relmfu将CsBVaJelurE.flv)

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

我想一个脚本,将在YouTube的FLV文件输出到由给定t文件名视频(在这种情况下是BASH课程2.flv)而不是简单的视频ID名称。预先感谢所有的帮助。

+0

+1乌拉圭回合问题 –

+0

这是手了最好的YouTube下载脚本在那里:https://bitbucket.org/rg3/youtube-dl/wiki/Home由于所有这些脚本都是通过抓取页面进行转发的,因此需要在网站结构上保持最新状态。它可以在文件名中包含视频标题。 –

+0

好的电话Niklas发送脚本的dl链接;以下是有关更多信息,文档和开发人员数据的专用链接:http://rg3.github.com/youtube-dl/。人们应该肯定下载,这是一个伟大的脚本 – wvandaal

回答

21

好的,在进一步研究和更新我的YouTube版本之后,事实证明,此功能现在直接构建到程序中,无需使用shell脚本解决YouTube上的播放列表下载问题。完整的文档可以在这里找到:(http://rg3.github.com/youtube-dl/documentation.html),但我原来的问题的简单解决方案如下:

1)youtube-dl会自动处理播放列表链接,没有必要单独给它的URL其中包含的视频(这不需要使用grep来搜索“手表?”以找到唯一的视频ID

2)现在有一个选项可用于格式化包含以下各种选项的文件名:

  • id:序列将被视频标识替换。
  • url:该序列将被视频URL替换。
  • 上传者:该序列将被上传视频的人的昵称取代。
  • upload_date:该序列将被上传日期替换为YYYYMMDD格式。
  • 标题:该序列将被文字视频标题取代。
  • 标题:该序列将被简化视频标题替换, 仅限于字母数字字符和破折号。
  • ext:序列将被替换为适当的扩展名(如 flv或mp4)。
  • epoch:创建 文件时,序列将被Unix纪元取代。
  • 自动编号:该序列将由一个五位数字代替, 将在每次下载时从零开始增加。

语法的该输出选项是如下(其中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 

再次感谢那些回复我的问题,你的帮助是非常感谢。

1

如果要将youtube页面中的标题用作文件名,可以使用-t选项youtube-dl。如果你想使用的标题从“视频列表”页面,你肯定恰好有一个watch?网址为每<span class="title video-title"冠军,那么你可以使用这样的事情:

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

我没有测试它,因为我没有“视频列表”页面的例子。

+0

感谢您的答案praetorian,-t选项适用于时间但你提供的脚本有一些错误,我需要检查。目前这些文件本身并没有下载,但我还没有时间来测试你的脚本,看看为什么。如果我发现任何东西,我会保持这个线程更新。 – wvandaal

+0

那么,正如我所说,我没有输入数据样本来测试脚本... –

-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

我正在学习bash脚本下载youtube视频,这是基于最新的youtube算法。它会显示所有可用的视频分辨率。您可以下载.webm,.mp4,.flv,.3gpp文件格式。 – Teron

+0

对不起,但这与原始问题无关,-1。 – etuardu

0

这下面的方法工作,并从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 

庆典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,你可能已经安装。

0

我用这个bash脚本从给定的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安装YouTube-DL