web-dev-qa-db-ja.com

youtube-dlコマンドでビデオの一部をダウンロードするにはどうすればよいですか?

私はUbuntuを使用しており、youtube-dlコマンドは完全に正常に機能しています。

しかし、今は長すぎるビデオの一部のみをダウンロードしたいと思います。だから私はそのビデオの数分だけをダウンロードしたいと思います。 13分から17分まで。

それを行う方法はありますか?

87
user3181614

youtube-dlだけでは、あなたが望んでいることはできないと思います。ただし、ffmpegなどのコマンドラインユーティリティと組み合わせることができます。

まず、youtube-dlを使用して実際のURLを取得します。

youtube-dl -g "https://www.youtube.com/watch?v=V_f2QkBdbRI"

コマンドの出力をコピーして、次のコマンドの-iパラメータの一部として貼り付けます。

ffmpeg -ss 00:00:15.00 -i "OUTPUT-OF-FIRST URL" -t 00:00:10.00 -c copy out.mp4

この位置の-ssパラメータは、ビデオへの15秒までのすべての入力を破棄することを示しています。 -tオプションは、10秒間キャプチャすることを示しています。コマンドの残りの部分は、mp4として保存するように指示します。

ffmpegは一般的なツールであり、一般的なOSリポジトリ/パッケージマネージャーのいずれかにあるはずです。

67
Johnnie

ジョニーの答えに追加:

youtube-dl -g "URL"を使用して、ビデオおよびオーディオストリームを取得します。

今使用してください:

ffmpeg -ss 12:15 -i "1st-URL" -ss 12:15 -i "2nd-URL" -t 5:15 -map 0:v -map 1:a -c:v libx264 -c:a aac output.mkv

ストリームごとに-ssオプションを使用する必要があります。また、キーフレームが失われないように、約30秒前に実行してから、別の-ss 30を使用することをお勧めします。これが私のYouTubeビデオの1つを使用した実際の例です。

ビデオ

youtube-dl -g https://www.youtube.com/watch?v=gESHIrvIQQo

出力:

https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/signature/4FFB9B0B7E1703B31F5D07DAD579B55F17EF7BAA.0CB63905C89DD4D33F90CF3AAD728F1ECDFCB9B3/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/
https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/signature/4CD42047D1D5C714377350905C1CC5CBA37C0009.6EED1FC92D17A096235C32E48F4B15DEF7DD99B0/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/

43:00から50:10にカットしたかったので、両方の入力で-ss 42:30(適切なキーフレームをキャッチするのに数秒かかる)を実行し、その後に-ss 30を実行します。 43:00に開始する入力。

次に、mapを使用して、ビデオ0:vとオーディオ1:aをマップします(0は最初の入力、つまりビデオであり、1は2番目の入力であり、オーディオです)。次に、エンコードオプションを選択します。

# The first URL
video_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/8CCFBF5CAB97341D0CB1F34E85AB6EE20FC7A03E.7679F39A8603CF41A95F10232E2A921EB0774101/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/"
# The second URL
audio_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/4AACC8E27F9036D36D4D623A771A9F2BAC4674BA.7E4F4FB4DC023E3FE491A991F0F9F2329648DE9D/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/"
ffmpeg -ss 42:30 -i "$video_url" -ss 42:30 -i "$audio_url" -map 0:v -map 1:a -ss 30 -t 7:10 -c:v libx264 -c:a aac gog-vs-triv.mkv
33
godofgrunts
ffmpeg $(youtube-dl -g 'https://www.youtube.com/watch?v=oHg5SJYRHA0' | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
27
Steve Goranson

この機能リクエストはまだyoutube-dlに実装されていません。 #622の問題 およびgithubにある多くの複製を参照してください。

14
ks1322

youtube-dlは、基になるポストプロセッサーへの引数の受け渡しをサポートしています(バージョン2017.08.27.1でテスト済み):

youtube-dl -x --postprocessor-args "-ss 00:13:00.00 -t 00:04:00.00" https://youtu.be/...

これは基本的に、最初にファイルをダウンロードした後に自分でffmpegを使用して後処理を行うのと同じです。

13
Kevin

これはOPの質問に完全に答えるものではありませんが、完全なストリームをダウンロードすることなく、最初から特定の期間までストリームをダウンロードする方法があります。 YouTubeは再開のサポートを提供しているため、Rangeヘッダーを使用して部分的なコンテンツをリクエストできます。

最初にストリームURLをフェッチします。

$ youtube-dl -g https://www.youtube.com/watch?v=yysk8s2vih8
https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu...
https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu...

これにより、2つのURLが出力されます(それぞれビデオストリームとオーディオストリーム用)。

次に、headリクエストを最初のURL(ビデオストリームにリンクしている)に送信して、このストリームのコンテンツ全体の長さを取得します。

$ curl "1st-URL" -sI | grep Content-Length
Content-Length: 64380504

次に、このコンテンツの長さの合計をビデオの合計秒数で割ります(YouTubeビデオの持続時間は4分7秒、つまり247秒です)。コンテンツの長さはおよそ1秒です。

64380504 / 247 ≈ 260650

この値に(最初からフェッチする秒数+ 1)を掛けます

(ストリームの最初に配置されるメタデータが占める余分なスペースも大まかに説明するために1つ追加します)

たとえば、最初の約10秒をフェッチするには、最初の260650 * 11 = 2867150バイトをフェッチする必要があるため、Rangeヘッダーを使用してリクエストを作成します。

$ curl "1st-URL" -H "Range: bytes=0-2867150" -o ten_secs.mp4

これにより、最初の10秒のみがダウンロードされます。ダウンロードしたファイルは再生できるはずですが、FFmpegに誤ったメタデータを修正させるのが最善です。

$ ffmpeg -i ten_secs.mp4 -c copy corrected_ten_secs.mp4

同様の方法で、オーディオの最初の部分(2nd-URL)のみをダウンロードすることもできます(コンテンツの長さは異なりますが、合計秒数は変わりません)。

動画から中央部分をダウンロードすることも可能ですが、YouTubeはメタデータをストリームの最初(最初の数バイト)に配置し、ダウンロードしたメディアに存在しないため、ストリームはまったく再生されません。

編集:これは、履歴書がサポートされているWebサイト(YouTubeなど)でのみ機能します。他のウェブサイトでは機能しません。

4
ritiek

-postprocessor-argsパラメーターを使用して、オーディオ/ビデオ出力をffmpegに渡して編集(プロセッサー)するため、ffmpegをインストールする必要があります。

-postprocessor-argsは、3つの引数と値を取ります(たとえば、それ以上の場合は、ffmpegのマニュアルページを確認してください)。

  • -ss HH:MM:SS:開始時間
  • -to HH:MM:SS:終了時間
  • -t HH:MM:SS:所要時間

例:

  • 15秒でエンコードを開始し、1分20秒で停止

$ youtube-dl --postprocessor-args "-ss 0:0:15 -to 0:1:20" '[video_URL]'

  • 15秒でエンコードを開始し、次の3分5秒だけを要します

$ youtube-dl --postprocessor-args "-ss 0:0:15 -t 0:3:5" '[video_URL]'

PS: youtube-dlは、メディア全体をダウンロードしてから処理し、後で削除します。

4
niainaLens

最初からポイントまでダウンロードできますなしすべてをダウンロードして編集します。それはこの質問が尋ねるものの半分です:

^Cでダウンロードを中断する

  • 私はmp4でのみこれを試しました
  • 別のビデオとオーディオでは機能しません。両方のフォーマットが必要です。デフォルトでは、ytdlは多くの場合、個別のビデオとオーディオを取得し、それらを結合します。 -Fを使用して利用可能な形式を確認し、両方を備えたmp4を選択します。例えば-f18または-f22は通常そこにあります。
  • ダウンロード率から推定する必要があります(線形ではありません。圧縮率は時間とともに変化します)。

はい。それはhackです。

さらに質問:個別のビデオ形式とオーディオ形式が必要な場合は、それぞれの一部を個別にダウンロードして(ここで^cを使用)、手動でマージできますか?一部のフォーマットでは機能しないと思います。

3
hyperpallium

@godofgruntsの回答を実装するスクリプトを作成しました ここ

#!/bin/bash
#taken from https://unix.stackexchange.com/a/388148/48971

if [ $# -lt 4 ]; then
        echo "Usage: $0 <youtube's URL> <HH:mm:ss from time> <HH:mm:ss to time> <output_file_name>"
        echo "e.g.:"
        echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
        exit 1
fi

echo "processing..."

from=$(date "+%s" -d "UTC 01/01/1970 $2")
to=$(date "+%s" -d "UTC 01/01/1970 $3")

from_pre=$(($from - 30))

if [ $from_pre -lt 0 ]
then
        from_pre=0
fi

from_pre_command_print=$(date -u "+%T" -d @$from_pre)
from_command_print=$(date -u "+%T" -d @$(($from - $from_pre)))$(grep -o "\..*" <<< $2)
to_command_print=$(date -u "+%T" -d @$(($to - $from_pre)))$(grep -o "\..*" <<< $3)

command="ffmpeg "

for uri in $(youtube-dl -g $1)
do
        command+="-ss $from_pre_command_print -i $uri "
done

command+="-ss $from_command_print -to $to_command_print $4"
echo "downloading with the following command:"
echo "$command" 
$command

Gitlab のスニペットにもアップロードしました

1
Nico Rodsevich

私はあなたが望むものにできるflaskアプリを作りました。私は投稿が古いことを知っていますが、問題は解決しません。

あなたはそれを見つけることができます ここ

YouTubeリンクのテキストも解析できます。あなたは単に例えばを供給します:

YouTube.com/blahblah start-1:20

これにより、ビデオが0-1:22からダウンロードされます(キーフレームが原因でわずかに違いが生じる場合があります)。ビデオ全体をダウンロードすることもできます。その場合は時間間隔を省略してください。

0
DinRigtigeFar

誰かが バッチスクリプト (Windowsの場合)を作成し、ファイルをダウンロードして目的の部分を抽出しました。

@ECHO off

:Input
ECHO.
SET url=
ECHO Enter Youtube-url:
SET /P url=
IF "%url%" EQU "" GOTO End
IF "%url: =%" NEQ "%url%" GOTO Input
ECHO Enter start time (in seconds, or in hh:mm:ss[.xxx] form):
SET /P start=
ECHO Enter duration (in seconds, or in hh:mm:ss[.xxx] form):
SET /P dur=
ECHO.
FOR /F "delims==" %%A IN ('youtube-dl.exe --no-warnings --get-filename "%url%"') DO SET filename=%%A
FOR /F %%B IN ('youtube-dl.exe -g "%url%"') DO (
ffmpeg.exe -hide_banner -ss "%start%" -i "%%B" -c copy -t "%dur%" "%filename%"
)
GOTO Input

:End
0
Jugurtha