なまけもの

備忘録

Youtubeの自動ダウンロード環境を構築する(Python)

概要

Pythonで、Youtubeの動画を自動でダウンロードする環境を構築する。

  • 任意のチャンネルの動画を対象とする。
  • EDCBの録画開始によるスリープ復帰時ダウンロードを実行する。
  • 前回ダウンロード以降にアップロードされた動画をダウンロードする。

目次

環境

ソフトウェア

simple.hatenablog.jp

ハードウェア

  • とくになし

手順

Pythonをインストールする

この辺を参考に。

www.python.jp

Pythonのライブラリをインストールする

各項目に記述されているコマンドを、コマンドプロンプトから実行する。

oauth2client

GitHub - googleapis/oauth2client: This is a Python library for accessing resources protected by OAuth 2.0.

$ pip install --upgrade oauth2client

google-api-python-client

GitHub - googleapis/google-api-python-client: 🐍 The official Python client library for Google's discovery based APIs.

$ pip install --upgrade google-api-python-client

python-dotenv

GitHub - theskumar/python-dotenv: Get and set values in your .env file in local and production servers.

$ pip install -U python-dotenv

ライブラリをインストールできない場合の対処法

コマンドライン上のメッセージにpython -m pip install --upgrade pipと表示されている場合は、そのコマンドを実行しpipをアップデートする必要がある。

YoutubeのAIPキー(DeveloperKEY)を発行する

承認の認証情報を取得するの手順に従いAPIキーを発行する。

コードの内容

Youtubeの動画を検索する

from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from oauth2client.tools import argparser

def youtube_search(options):
   youtube = build("youtube", "v3", developerKey=<YoutubeのAIPキー>)

    search_response = youtube.search().list(
        q               = options["q"],
        part            = "id,snippet",
        maxResults      = options["max_results"],
        channelId       = options["channel_id"],
        publishedAfter  = options["published_after"]
        ).execute()

    videos = []

    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
            videos.append({"title": search_result["snippet"]["title"], "videoId": search_result["id"]["videoId"]})

    for video in videos:
        print(video["videoId"], video["title"])

    return videos

Pythonからyoutube-dlを実行する

import subprocess

def exec_youtube_dl(url):
    result = subprocess.check_output( [<yutube-dlのフルパス>,
                                      "--ffmpeg-location",
                                      <ffmpegのフルパス>,
                                      #"-f",    # mp4に限定する場合は有効
                                      #"mp4",   # mp4に限定する場合は有効
                                      url
                                      ] )
    print(result)
    return result

ビデオをダウンロードする

def download_videos(video_ids):
    for video_id in video_ids:
        exec_youtube_dl( "https://www.youtube.com/watch?v=" + video_id )

ビデオのIDを取得する

from youtube_search_api import youtube_search
from googleapiclient.errors import HttpError

def get_video_ids(channelId, date, max_results, q):
    options = {
        "channel_id": channelId,
        "published_after": date,
        "max_results": max_results,
        "q": q
    }

    try:
        results = youtube_search(options)
        video_ids = [result["videoId"] for result in results]
    except HttpError as e:
        print("An HTTP error %d occurred:\n%s" % (e.resp.status, e.content))
        exit(-1)
    if video_ids is not None:
        return video_ids

メイン関数

from datetime import datetime, date, timedelta

if __name__ == "__main__":
    date = ""
    try:
        with open("date.txt","r") as f:
            date = f.read()
    except:
        date = datetime.strftime(datetime.today(), "%Y-%m-%dT00:00:00Z")

    with open("date.txt","w") as f:
        f.write(datetime.strftime(datetime.now(), "%Y-%m-%dT%H:%M:00Z"))

    channels = {
        "<任意の名称>"   : "<チャンネルID>",
        "<任意の名称>"   : "<チャンネルID>"
    }
    max_results = 50
    q = ""

    video_id_all = []

    for name, channelId in channels.items():
        video_id_all += get_video_ids(channelId, date, max_results, q)

    download_videos(video_id_all)
  • 4~9行目 : 前回の実行時間を取得する。
    • 8~9行目 : ファイルが無い場合に、本日の0時以降の動画を対象にしている。https://www.youtube.com/channel/ABCDEFGABCDEFGの部分。
  • 11~12行目 : 今回の実行時間をファイルに記述する。
  • 14~19行目 : ダウンロードするチャンネルを設定する。
    • 14~17行目 : 対象にするチャンネルを記述する。
    • 18行目 : 基本的に変更不要。
    • 19行目 : 特定のキーワードを含む動画のみを対象としたい場合に、キーワードを記述する。

スリープから復帰時にダウンロードを実行する

  1. タスクスケジューラを開く。
  2. メニューから、操作⇒タスクの作成 を選択する。
  3. 以下の設定を行う。
    • "全般"タブ
      • 名前 : 任意の名称
    • "トリガー"タブ ⇒ "新規"ボタン
      • タスクの開始 : イベント時
      • 設定 : 基本
      • ログ : システム
      • ソース : Power-Troubleshooter
      • イベントID : 1
    • "操作"タブ ⇒ "新規"ボタン
      • 操作 : プログラムの開始
      • プログラム/スクリプト : python
      • 引数の追加 : main.pyのフルパス
      • 開始(オプション) : main.pyのフォルダパス
  4. "OK"ボタンを押下し、タスクを登録する。

参考


そのうち、ソースコード自体をgithubに上げたり、コードの詳しい内容を充実させたい。
以上。