0

我希望有两个 youtube-dl 进程(或尽可能多的)并行运行。请告诉我如何。提前致谢。

#!/bin/bash
#package: youtube-dl axel

#file that contains youtube links
FILE="/srv/backup/temp/youtube.txt"

#number of lines in FILE
COUNTER=`wc -l $FILE | cut -f1 -d' '`

#download destination
cd /srv/backup/transmission/completed

if [[ -s $FILE ]]; then
  while [ $COUNTER -gt 0 ]; do

    #get video link
    URL=`head -n 1 $FILE`

    #get video name
    NAME=`youtube-dl --get-filename -o "%(title)s.%(ext)s" "$URL" --restrict-filenames`

    #real video url
    vURL=`youtube-dl --get-url $URL`

    #remove first link
    sed -i 1d $FILE

    #download file
    axel -n 10 -o "$NAME" $vURL &

    #update number of lines
    COUNTER=`wc -l $FILE | cut -f1 -d' '`
  done
else
  break
fi
4

4 回答 4

2

这应该适用于 GNU Parallel:

cd /srv/backup/transmission/completed
parallel -j0 'axel -n 10 -o $(youtube-dl --get-filename -o "%(title)s.%(ext)s" "{}" --restrict-filenames) $(youtube-dl --get-url {})' :::: /srv/backup/temp/youtube.txt

了解更多:https ://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

于 2013-02-16T01:42:59.503 回答
1

解决方案

您需要在子shell 中运行您的命令,即将您的命令放入( cmd ) &.

定义

shell 脚本本身可以启动子进程。这些子shell 让脚本进行并行处理,实际上同时执行多个子任务。

代码

对你来说,我猜它看起来像这样(我添加引号$vURL):

( axel -n 10 -o "$NAME" "$vURL" ) &
于 2013-02-15T18:05:00.190 回答
0

我不知道这是否是最好的方法,你可以定义一个函数,然后在后台调用它

像这样的东西:

#!/bin/bash
#package: youtube-dl axel

#file that contains youtube links
FILE="/srv/backup/temp/youtube.txt"

# define a function
download_video() {
  sleep 3
  echo $1
}

while read -r line; do
  # call it in background, with &
  download_video $line &
done < $FILE

脚本快速结束但功能仍在后台运行,3秒后将显示回声

还使用了 read 和 while 循环来简化文件读取

于 2013-02-15T18:29:27.227 回答
0

这是我的看法。通过避免使用几个命令,您应该会看到速度的一些小改进,尽管它可能并不明显。我确实添加了错误检查,可以节省您处理损坏 URL 的时间。

#file that contains youtube links
FILE="/srv/backup/temp/youtube.txt"

while read URL ; do
    [ -z "$URL" ] && continue

    #get video name
    if NAME=$(youtube-dl --get-filename -o "%(title)s.%(ext)s" "$URL" --restrict-filenames) ; then
        #real video url
        if vURL=$(youtube-dl --get-url $URL) ; then
            #download file
            axel -n 10 -o "$NAME" $vURL &
        else
            echo "Could not get vURL from $URL"
        fi
    else
        echo "Could not get NAME from $URL"
    fi
done << "$FILE"

根据要求,这是我将 vURL 和 NAME 获取以及下载并行的建议。注意:由于下载依赖于 vURL 和 NAME,因此创建三个进程没有意义,两个为您提供最佳回报。下面我将 NAME fetch 放在它自己的进程中,但如果结果证明 vURL 始终更快,那么将它与 NAME fetch 交换可能会有一点回报。(这样下载过程中的 while 循环甚至不会浪费一秒钟的睡眠时间。) 注意 2:这是相当粗糙的,未经测试,它只是即兴发挥,可能需要工作。无论如何,可能有一种更酷的方式。害怕...

#!/bin/bash

#file that contains youtube links
FILE="/srv/backup/temp/youtube.txt"

GetName () {  # URL, filename
    if NAME=$(youtube-dl --get-filename -o "%(title)s.%(ext)s" "$1" --restrict-filenames) ; then
        # Create a sourceable file with NAME value
        echo "NAME='$NAME'" > "$2"
    else
        echo "Could not get NAME from $1"
    fi
}

Download () {  # URL, filename
    if vURL=$(youtube-dl --get-url $1) ; then
        # Wait to see if GetName's file appears
        timeout=300  # Wait up to 5 minutes, adjust this if needed
        while (( timeout-- )) ; do
            if [ -f "$2" ] ; then
                source "$2"
                rm "$2"
                #download file
                if axel -n 10 -o "$NAME" "$vURL" ; then
                    echo "Download of $NAME from $1 finished"
                    return 0
                else
                    echo "Download of $NAME from $1 failed"
                fi
            fi
            sleep 1
        done
        echo "Download timed out waiting for file $2" 
    else
        echo "Could not get vURL from $1"
    fi
    return 1
}


filebase="tempfile${$}_"
filecount=0

while read URL ; do
    [ -z "$URL" ] && continue
    filename="$filebase$filecount"
    [ -f "$filename" ] && rm "$filename" # Just in case
    (( filecount++ ))
    ( GetName "$URL" "$filename" ) &
    ( Download "$URL" "$filename" ) &
done << "$FILE"
于 2013-02-15T18:54:49.587 回答