Youtube-dlで1080p動画ダウンロード手順を簡略化するスクリプトを書いた
かいた。
内容的にはタイトルで全部です。というのも流石に何なので、簡単に説明を書きます。
以前、youtube-dlで1080p画質でDLする手順を簡単にまとめた。
メモ:youtube-dlで1080p - あくぽろぐ aqpolog
実際日常的に使っていて、やっぱり手順が多くてめんどくさい
(そもそもなんで(best)指定で1080pを落としてくれないのか…1)。
というわけで、URL与えたら一発で1080pでDLするところまでやってくれるスクリプトを書いた。
もともとの手順
- 対象動画のURLをコピー
- コマンドライン上で
youtube-dl -f <URL>
を実行 - 実行結果から対象(1080p)の動画フォーマットコードと音声フォーマットコードを見つける
- 見つけたフォーマットコードを元に
youtube-dl -F <vcd>+<acd> --merge-output-fomart mp4 <URL>
のようなコマンドを実行
スクリプト使用時の手順
- 対象動画のURLをコピー
- コマンドライン上で
python ydl1080p.py <URL>
を実行
実行に必要なもの
- python 3.n (2.7環境でyoutube-dlが動かなくなってるっぽい?ので。動くなら2.nでも多分平気です)
- youtube-dl 最新版
- ffmpeg(--merge-output-format利用時に必要)
- 多少の知識
動作確認は以下環境で実施。他環境の場合はよしなにしてください。
- MacOS X Mojave 10.14
- python 3.7.1 (pyenv)
- 確か初回で失敗して [MacOS Mojave]pyenvでpythonのインストールがzlibエラーで失敗した時の対応 - Qiita を参考にした(うろ覚え)
- youtube-dl 2018.11.23
- ffmpeg 4.0.2
スクリプト(ydl1080p.py)
やってる内容としては、
- subprocessモジュールでyoutube-dlを実行、フォーマットコードリストを取得
- フォーマットコードリストを単純に一行ずつfindで検索して1080pのビデオフォーマットコード(とオーディオコード)を取得
- 取得したコードで
youtube-dl -F <vcd>+<acd> --merge-output-fomart mp4 <URL>
コマンドを生成 - 生成したコマンドをsubprocessで実行(動画のDL実施)
という単純なやつです。コードも雑なので適当に参考にしてください。
- 以下コードをテキストファイルにコピペして保存
- テキストをydl1080.pyなどにリネーム
- 動画をDLしたいフォルダに置く
- コマンドプロンプトやターミナルでスクリプト置いたフォルダにcd
python ydl1080p.py <URL>
を実行
#!/usr/bin/env python3 # last-update:2018/12/06 # import import subprocess import sys class YoutubeDlSupport: def __init__(self): pass @classmethod def get_fmt_cd(cls, param_url=''): """ get_fmt_cd: 1080p動画フォーマットを自動判定してDL :param param_url: 対象動画のURL :return: """ if not param_url: print('Need "param_url" option to run this method') return # command = 'python ayd_sub.py {0}'.format(param_url) command = 'youtube-dl {0} -F'.format(param_url) with subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc: print('youtube-dl return code : {0}'.format(proc.returncode)) outs, errs = proc.communicate() print('outs:{0} errs:{1}'.format(len(outs), len(errs))) if len(outs) == 0: return list_ex = outs.splitlines() # list_ex = str_return.readlines() # initialize audio_fmt_cd = '' video_fmt_cd = '' best_video_fmt_cd = '' p60_fmt_cd = '' no_audio_flg = False # get 1080p fmt code for i, elem in enumerate(list_ex): elem = elem.decode() if elem.find('m4a') >= 0: print('Found audio(m4a) format! On:{0}L -> {1}'.format(i, elem)) audio_fmt_cd = elem[:3].strip() print('"{0}"'.format(audio_fmt_cd)) if elem.find('x1080') >= 0 and elem.find('mp4') >= 0: print('Found 1080p(mp4)! On:{0}L -> {1}'.format(i, elem)) if elem.find('p60') >= 0: print('Found 1080p60(mp4)!') p60_fmt_cd = elem[:3].strip() print('"{0}"'.format(p60_fmt_cd)) continue video_fmt_cd = elem[:3].strip() print('"{0}"'.format(video_fmt_cd)) if elem.find('(best)') >= 0: print('Found best! On:{0}L -> {1}'.format(i, elem)) best_video_fmt_cd = elem[:3].strip() print('"{0}"'.format(best_video_fmt_cd)) if not audio_fmt_cd: audio_fmt_cd = 'Not found...' no_audio_flg = True if not video_fmt_cd: print('Target video format is not found, so set BEST instead.') video_fmt_cd = best_video_fmt_cd if len(p60_fmt_cd) > 0: print('1080p60Hz video format is found, so set p60 instead.') video_fmt_cd = p60_fmt_cd # make ydl command if no_audio_flg: param_f = '-f {0}'.format(video_fmt_cd) else: param_f = '-f {0}+{1}'.format(video_fmt_cd, audio_fmt_cd) video_fmt_suffix = 'mp4' param_merge = '--merge-output-format {0}'.format(video_fmt_suffix) # param_out = '-o [%(timestamp)s] %(title)s(%(duration)s).%(ext)s' # TODO: Windowsの場合は%文字列二重にする必要あり?(要検証) # TODO: Linuxの場合はfmt_template部分はクオートで囲む必要あり?(要検証) # cmd_fmt = 'youtube-dl {0} {1} {2} {3}'.format(url, param_f, param_merge, param_out) cmd_fmt = 'youtube-dl {0} {1} {2}'.format(url, param_f, param_merge) # 'youtube-dl <VID or URL> -f nnn+nnn --merge-output-format mp4 -o hogehoge' print('Make cmd : {0}'.format(cmd_fmt)) return cmd_fmt @classmethod def run_ydl(cls, cmd_ydl): if not cmd_ydl: print('Need "cmd" option to run this method') return # call youtube-dl with cmd-args print(cmd_ydl) with subprocess.Popen(cmd_ydl, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc: proc.wait() # 起動パラメータ取得 args = sys.argv # インスタンス化 ydls = YoutubeDlSupport() url = '' if len(args) > 0: url = args[1] print(url) cmd = ydls.get_fmt_cd(url) ydls.run_ydl(cmd) print('done')
-
bestを指定した場合、最高画質でDLする仕様となっているが、best=720p止まり↩