ウェブ管理者の気まぐれ自作アクセス解析 ElasticsearchとKibanaを添えて

アクセス解析ツールmatomo

「がとらぼ」は長年にわたり、ウェブアクセス解析にmatomo (旧名Piwik)を使用していました。しかし、2022年夏頃に問題が発生し、全データを削除して再インストールしましたが、秋に再び不調になり、再々インストールすることになりました。その後、2022年末か2023年明け頃には新しいバージョンへの更新ができなくなり、2023年3月にはmatomo上でビジットログを見ることができなくなりました。再インストールしても短期間で利用不能になるため、matomoの代替を探すことになりました。

アクセス解析ツールmatomo

Google Analyticsは、ウェブサイトのパフォーマンスやユーザー行動を詳細に分析できる非常に強力なツールです。その豊富な機能を活用すれば、マーケティング戦略の最適化やユーザーエクスペリエンスの改善に大きく貢献することができます。しかし、その一方で、初心者にとっては扱いにくい部分も多く見られます。特にレポートの作成方法が複雑で、どこから手をつけてよいのか戸惑うことが多いです。データの可視化やカスタムレポートの設定には、ある程度の専門知識が求められ、初めて使う人にとっては敷居が高く感じられるでしょう。したがって、ウェブ解析に不慣れな一般ユーザーや小規模なビジネスオーナーにとっては、もっとシンプルで直感的に使えるツールが理想的です。

加えて、近年、Google Analyticsは特に欧州で規制が強化されており、使用に対して否定的な動きが広がっています。その背景には、欧州連合 (EU) が施行する一般データ保護規則 (GDPR) の存在が大きく関わっています。GDPRは、個人情報の取り扱いに対して非常に厳しい規制を設けており、ユーザーのデータが不適切に収集・利用されることを防ぐために制定されたものです。

Google Analyticsが欧州で問題視される理由は、主にデータの扱い方にあります。このツールは、ユーザーのIPアドレスやクッキー情報など、個人を特定できるデータを収集・送信しますが、その一部はアメリカのサーバーに送られることが多いです。これにより、EU内のデータが欧州外、特にアメリカに転送されることが問題視され、プライバシー保護の観点から違反の可能性が指摘されました。実際、2022年にはオーストリアやフランスなどのEU加盟国で、Google Analyticsの使用がGDPRに違反するとして正式に警告が出される事態にまで発展しています。

このような状況から、欧州ではGoogle Analyticsに代わるプライバシーに配慮したツールの需要が高まりつつあります。また、欧州以外の国々でも、データプライバシーに関する規制が厳しくなりつつあり、今後はGDPRに類似した法律が広がる可能性が考えられます。たとえば、アメリカではカリフォルニア州が独自のデータ保護法 (CCPA) を施行しており、他の州や国でも同様の動きが出てくるかもしれません。このような規制強化の流れを受け、今後はGoogle Analyticsの利用がさらに制約されるか、もしくは別の解析ツールに移行する企業や個人が増えることが予想されます。

したがって、特に欧州市場をターゲットとするビジネスにおいては、Google Analyticsに頼りすぎず、他の解析ツールやデータ収集の方法を検討することが重要になってくるでしょう。

幸いにも、アクセス解析ツールには、このページの最初の画像にあるサイト isgoogleanalyticsillegal.com で紹介されていて、十分に実用的な自己ホスティングのツールを含む、いくつかの選択肢があります。

ただし、今回は自分でアクセス解析ツールを作成することに決めました。(2023年1月)

自作アクセス解析ツールの仕組み

  1. ウェブページにJavascriptを置き、そのスクリプトで閲覧者のブラウザ情報を収集します
  2. ウェブサーバにPHPスクリプトを設置し、JavascriptはそのPHPスクリプトにデータを送ります
  3. PHPスクリプトは送信されたデータに閲覧者のIPアドレスなどを追加しElasticsearchに送信します
  4. Elasticsearchではデータに含まれるIPアドレスからgeoipによるネットワーク的位置を取得し追加します
  5. Kibanaでデータを可視化します

ウェブページに設置するJavascript

javascriptで収集する情報

  • ユーザーエージェント: window.navigator.userAgent
  • ユーザーの言語: language: window.navigator.language
  • ブラウザ画面横幅: screenWidth: window.screen.width
  • ブラウザ画面高さ: screenHeight: window.screen.height
  • プラットフォーム: platform: window.navigator.platform
  • ページタイトル: document.title
  • ページURL: window.location.href
  • ウェブサーバ(ホスト/ドメイン): location.hostname
  • リファラ: getResponseHeader("Referer")

取得するデータの種類は欲張らないことにしました。ページタイトル,ページURL,ウェブサーバのホスト名に至ってはユーザーの情報ですらありません。
リファラ(直前に表示していたページ)はwindow.document.referrerで取得する方が簡単でしょうが、今回は敢えて手間がかかるgetResponseHeader("Referer")で取得してみます。
getResponseHeader("Referer")を使う場合、HTTPヘッダーを直接取得するのでブラウザの挙動の違いが少なめ(ただし全てのブラウザで機能するとは限らない)、CORSの影響を受けます。window.document.referrerと併用するのもアリかもしれませんが、モダンブラウザはリファラが取りにくいものなので拘らないことにします。

リファラをwindow.document.referrerで取る場合
<script>
function collectInfo() {
    const browserInfo = {
        userAgent: window.navigator.userAgent,
        language: window.navigator.language,
        screenWidth: window.screen.width,
        screenHeight: window.screen.height,
        platform: window.navigator.platform,
        referrer: window.document.referrer,
        title: document.title,
        url: window.location.href,
        host: location.hostname,
    };
    // ブラウザの情報をサーバに送信するためのリクエストを生成する
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'https://送信先URL/collect.php', true);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.send(JSON.stringify(browserInfo));
}
// 1000ミリ秒の遅延実行でcollectInfo関数呼ぶ
setTimeout(collectInfo, 1000);
</script>

とてもシンプルです。

上のコードをウェブページ設置用にミニファイします。(下)

<script>
function collectInfo(){let e={userAgent:window.navigator.userAgent,language:window.navigator.language,screenWidth:window.screen.width,screenHeight:window.screen.height,platform:window.navigator.platform,referrer:window.document.referrer,title:document.title,url:window.location.href,host:location.hostname},t=new XMLHttpRequest;t.open("POST",'https://送信先URL/collect.php',!0),t.setRequestHeader("Content-Type","application/json"),t.send(JSON.stringify(e))}setTimeout(collectInfo,1e3);
</script>
リファラをgetResponseHeader("Referer")で取る場合
<script>
// 参照元ページのURLを取得する関数
function getReferrer(callback) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", window.location.href);
  xhr.send();
  xhr.onload = function() {
    var referrer = xhr.getResponseHeader("Referer");
    callback(referrer); // コールバック関数に参照元ページのURLを渡す
  };
}

// ユーザーエージェント、言語設定、画面サイズ、プラットフォーム、ページタイトル、ページURL、ホスト名を取得する関数
function getOtherData() {
  var userAgent = navigator.userAgent; // ユーザーエージェント
  var language = navigator.language; // 言語設定
  var screenWidth = window.screen.width; // 画面幅
  var screenHeight = window.screen.height; // 画面高さ
  var platform = window.navigator.platform; // プラットフォーム
  var title = document.title; // ページタイトル
  var url = window.location.href; // ページURL
  var hostname = location.hostname; // ホスト名
  return {userAgent: userAgent, language: language, screenWidth: screenWidth, screenHeight: screenHeight, platform: platform, title: title, url: url, hostname: hostname}; // オブジェクトとして返す
}

// 取得したデータを送信する関数
function sendData(data) {
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "https://送信先URL/collect.php"); // 送信先のURL
  xhr.setRequestHeader("Content-Type", "application/json"); // データの形式をJSONに指定
  xhr.send(JSON.stringify(data)); // データをJSONに変換して送信
}

// メインの処理
getReferrer(function(referrer) { // 参照元ページのURLを取得する
  var data = getOtherData(); // ユーザーエージェント、言語設定、画面サイズ、プラットフォーム、ページタイトル、ページURL、ホスト名を取得する
  data.referrer = referrer; // 参照元ページのURLをデータに追加する
  sendData(data); // データを送信する
});

// 1000ミリ秒の遅延実行でgetReferrer関数呼ぶ
setTimeout(getReferrer, 1000);
</script>

上のコードをウェブページ設置用にミニファイします。(下)

<script>
function getReferrer(e){var t=new XMLHttpRequest;t.open("GET",window.location.href),t.send(),t.onload=function(){e(t.getResponseHeader("Referer"))}}function getOtherData(){var e,t=navigator.userAgent,n=navigator.language,r=window.screen.width,a=window.screen.height,o=window.navigator.platform,i=document.title;return{userAgent:t,language:n,screenWidth:r,screenHeight:a,platform:o,title:i,url:window.location.href,hostname:location.hostname}}function sendData(e){var t=new XMLHttpRequest;t.open("POST","https://送信先URL/collect.php"),t.setRequestHeader("Content-Type","application/json"),t.send(JSON.stringify(e))}getReferrer(function(e){var t=getOtherData();t.referrer=e,sendData(t)});setTimeout(getReferrer,1e3);
</script>

リファラの取り方のどちらか好きな方を選択してウェブページの </body> 直前にでも置けば良いでしょう。

このページではsetTimeout()を使って遅延実行させていますが、scriptタグにdefer属性を指定してやれば自動的に遅延実行相当にすることもできます。
上の例では setTimeout(getReferrer, 1000); のように関数を呼ぶ部分を getRefferer(); に書き換え、<script> になっている部分を<script defer> にします。

なお、非同期にしたいからとasync属性を付けたがる人がいますが、それだと(非同期なので)想定外に早く実行されてしまい収集データが未定義状態で送信される可能性があるのでdeferにしましょう。

ウェブサーバでアクセスデータを受け取るPHPスクリプト

データ送信先のPHPスクリプトcollect.php
<?php
// Elasticsearchに情報を送信するための関数
function sendToElasticsearch($data) {
    // ElasticsearchのURLとポート番号を指定
    $elasticsearch_url = 'https://192.168.0.1'; //Elasticsearchの待受けURLに変更
    $elasticsearch_port = 9200;

    // Elasticsearchの認証情報を指定
    $username = 'elasticaccount'; //Elasticsearchにアクセスするアカウント
    $password = 'a1b2c3d4e5f6g7h8i9'; //Elasticsearchにアクセスするパスワード

    // ElasticsearchのCA証明書を指定
    $certificate_file = '/usr/local/www/hoge/http_ca.crt';

    // Elasticsearchへ送信するJSONデータ
    $timestamp = gmdate('Y-m-d\TH:i:s.v\Z'); //Elasticsearchに送るデータのタイムスタンプ (UTCで)
    //このスクリプトにアクセスしてきたIPアドレスを取得し配列に追加、上のタイムスタンプも配列に追加
    $dataWithIPTS = array_merge($data, array('ip' => $_SERVER['REMOTE_ADDR']), array('@timestamp' => $timestamp));
    $json_data = json_encode($dataWithIPTS); //データはJsonで

    // cURLセッションを初期化
    $ch = curl_init();

    // ElasticsearchにアクセスするURLを作成
    $index = 'accesslog-' . gmdate('Y.m.d');  //インデックスは access-2023.04.01 のような形式とする(日付変わりはUTCで)
    // _docは型なので指定忘れないよう
    //  ?pipeline=geoip-pipelineは後述のパイプラインの指定
    $url = "{$elasticsearch_url}:{$elasticsearch_port}/$index/_doc?pipeline=geoip-pipeline";

    // cURLオプションを設定    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Authorization: Basic ' . base64_encode("$username:$password"),
    ));
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_CAINFO, $certificate_file);

    // ElasticsearchにJSONデータを送信
    $response = curl_exec($ch);

    // cURLセッションを閉じる
    curl_close($ch);

    return $response;
}

// 受信したJSONデータを解析する
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    //ブラウザ(Javascript)から情報を取得する
    $data = file_get_contents('php://input');
    $json = json_decode($data, true);
    //Elasticsearchに送信する
    sendToElasticsearch($json);
}
?>

Elasticsearch GeoIP用インジェストパイプラインの作成

最近のElasticsearchは標準でGeoipが入っているのでGeoipプラグインをインストールする必要はありません。
データのちょっとした加工にLogstashを挟むことが多いでしょうが、Geoipで座標追加する程度であればLogstashを使わずにElasticsearchに簡単なパイプラインで十分かと思います。

PUT _ingest/pipeline/geoip-pipeline
{
  "description" : "Add geoip info",
  "processors" : [
    {
      "geoip" : {
        "field" : "ip",
        "target_field" : "geoip"
      }
    }
  ]
}

Kibanaの「開発ツール」「コンソール」で上の12行をペーストして1行目にフォーカスしてその右の をクリックして実行します。これでgeoip-pipelineという名前のパイプラインが作成されます。
このパイプラインでは、フィールド名「ip」でIPアドレスが入ったデータからgeoip.locationフィールド下に緯度/経度、geoip.continent_nameに地域名(アジアなど)、geoip.country_nameに国名(Japanなど)、geoip.country_iso_codeにISOの国コード(JPなど)、geoip.region_nameに県名など、geoip.city_nameに都市名などの情報が追加されます。
パイプラインを作成しても使用を明示しなければ勝手には使用されません。先のPHPコードでURLクエリーの最後に指定したパイプラインがこれです。

Elasticsearch インデックスのマッピングの変更

緯度と経度の情報がデータに含まれればKibanaの地図で可視化できそうなものですが、実際には座標データが見つからないということで地図にプロットできません。座標データはgeoip.location下入りますが、普通にElasticsearchにデータを送信して自動でインデックスが作成されるとgeoip.locationのproperties下でlat(緯度),lon(経度)の型がfloatでマッピングされてしまいます。正常そうに思えますがKibanaの地図のプロット用として使うには全く違うようです。
geoip.locationにgeo_pointという型を指定するのが良いようですが、ここで注意しなければならないのは、accesslog-*インデックスにデータがある状態では型の変更ができないことです。
Kibanaの「開発ツール」「コンソール」で下の20行をペーストします。そして、1行目にフォーカスしてその右の をクリックして実行し、ただちに2行目にフォーカスしてその右の をクリックして実行します。

DELETE /accesslog-*
PUT /_template/accesslog
{
  "index_patterns": "accesslog-*",
  "mappings": {
    "properties": {
      "geoip": {
        "properties": {
           "location": {
             "type": "geo_point"
            },
            "ip": {
              "type": "ip"
            }
          }
        }
      }
    }
  }
}

12,13行目でついでにipフィールドの型をip (IPアドレスの型)に変更しています。自動でマッピングされるとIPアドレスの型がただのtextになってしまうので気持ち悪いですからね。

マッピングの確認
Kibanaのメニューから「スタック管理」「インデックス管理」「インデックス」タブを選択し、検索欄に「accesslog」を入力、インデックスリストからaccesslog-YYYYmmddのリンクをクリック。上部の「マッピング」タブを選択すると現在のインデックスに適用されているマッピングが表示されます。これで geoip.properties.locationの型がgeo_pointでipの型がipであれば指定したマッピングが正しく適用されています。

geoip.locationは下のようなデータが入るようになります。(マッピングではなく実データ)

    "geoip.location": [
      {
        "coordinates": [
          139.7539,
          35.6838
        ],
        "type": "Point"
      }
    ],

Elasticsearchは何をしなければならないかは判らないことが多いですが、やることは簡単です。

Kibanaで地図にプロットする

ビジュアライズでマップ作成 1
Kibanaのメニューから「Visualize Library」右上の「 Create ビジュアライゼーション」「マップ」をクリックします。

ビジュアライズでマップ作成 2
地図が表示されます。座標データをプロットする「レイヤーを追加」をクリックします。

ビジュアライズでマップ作成 3
プロット方法を選べます。今回はヒートマップを選択しました。

ビジュアライズでマップ作成 4
データビューの選択ドロップダウンメニューで「accesslog-*」を選択します。

ビジュアライズでマップ作成 5
プロット可能と認識される形式の座標データがインデックスに含まれるならクラスターフィールドにフィールドが自動選択される筈です。または、ドロップダウンメニューでgeoip.locationフィールドを選択します。選択したフィールドがプロット可能な座標データであると認められないと選択させて貰えません。そこで前述のマッピングの変更が必要となります。
右下の「レイヤーを追加」をクリックします。

ビジュアライズでマップ作成 6
必要に応じてメトリックのアグリゲーションを変更します。基本的には「カウント」で良いかと思われます。
右下の「 保存して閉じる」をクリックします。

ビジュアライズでマップ作成 7
右上の「 保存」をクリックします。 「マップを保存」ポップアップ画面で分かりやすいビジュアライズの名前を入力します。右側でビジュアライズを既存のダッシュボードに追加する新しいダッシュボードに追加するかダッシュボードに追加しないか選択します。「なし」でダッシュボードに追加しない場合でも後からダッシュボードの編集でこのビジュアライズを追加することができます。
右下の「保存してダッシュボードを開く」(表示される文字列は変わります)をクリックします。

ビジュアライズでマップ作成 8
画像はアクセスログのダッシュボード(作成中)に地図のビジュアライズを追加した状態です。
ヒートマップは表示にクセがあるようで、上の画像のような世界地図状態では日本とアメリカ中央とフロリダの3箇所しか光っていません。特に欧州には全く色の違いはないように見えます。(次)

ビジュアライズでマップ作成 9
表示データの条件を変えずに地図の欧州部分を拡大表示しました。イスタンブールが最もはっきり光っていますが、それ以外にも数箇所にぼんやりと色が付いています。つまり、地図を拡大しないと確認できないということです。これではひと目で情報を確認できないということになります。ヒートマップ以外のプロットを選択する方が良いかもしれません。

Elasticsearch + Kibanaではグラフや表は特に難しい部分はなく初見でも容易に作成できる筈ですが、IPアドレスを元に地図にプロットするのはコツがあることを知らないと難しい部分があるのでこの記事では地図にプロットする部分に注力しました。

2023年4月18日追記:
この記事では getResponseHeader("Referer") を使ってリファラを取ると書いておきながら、そのコードを貼り忘れていたので追加して修正しました。
併せてscriptタグにdefer属性を付ける場合についても追加しました。

yt-dlpの使い方備忘録

yt-dlpの使い方備忘録

以前、youtube-dlの使い方備忘録の記事を投稿しましたが、最近になって、そのyoutube-dlがエラーを起こしてうまく動作しなくなりました。特に、このエラーはPython環境に関連している可能性があり、根本的な原因の特定には手間がかかりそうです。しかし、2023年現在、このエラーを修正するよりも、別の解決策に目を向ける方が効率的だと判断しました。

そこで注目したのが「yt-dlp」です。yt-dlpは、youtube-dlをベースにしたフォーク(派生プロジェクト)で、様々な改良や新機能が追加されています。このため、youtube-dlのエラーを無理に解決するより、より進化したyt-dlpに乗り換える方が賢明だと考えました。

yt-dlpは、youtube-dlと同じ目的で開発されており、基本的な使い方はほとんど同じです。ただし、いくつかのオプションや機能に違いがあるため、乗り換えに際してもそれほど大きな学習コストはかかりません。yt-dlpは、より多くのウェブサイトに対応しているほか、ダウンロード速度の向上や、使いやすさを向上させるオプションが増えている点が大きな特徴です。

つまり、youtube-dlのトラブルに悩まされるくらいなら、より進化したyt-dlpを導入することで、今後のメンテナンスも楽になる可能性が高いと言えるでしょう。

yt-dlpのインストール

yt-dlpの使い方備忘録 1
yt-dlpはPython 3.7以上の環境で動作します。つまりyoutube-dlとは異なり古いPythonでは動作しません。youtube-dlと同じくffmpegもインストールしておきます。
python3 -m pip install -U yt-dlp (インストール/更新共に)

yt-dlpのインストール (最近のLinux用)

Ubuntu 24.04 LTS系のLinuxディストリビューションではおそらく旧来の方法だとPythonアプリのシステムへのインストールを断られるようになっています。回避方法はいろいろあるようですが、簡単なのはpipxを使う方法です。

$ sudo apt install pipx
$ pipx install yt-dlp (インストール こちらはsudoは使いません)
または
$ pipx upgrade yt-dlp (アップデート こちらはsudoは使いません)

2025年11月18日追記:
YouTubeについてはyt-dlpだけでは機能しなくなったようです。
外部JavascriptランタイムのDenoをインストールします。

$ cd ~
$ curl -fsSL https://deno.land/install.sh | sh

管理者になったりsudoを使う必要はないようです。
使い方の変更点についてはこのページの最後に。

yt-dlpの使い方

基本形
$ yt-dlp 動画URL
または
$ yt-dlp 動画ID
または
$ yt-dlp プレイリストID   (プレイリストIDの前に -i を追加するとエラーを無視するのでオススメ)

YouTubeだと https://www.youtube.com/watch?v=00000000000 のようなのが動画URL、そのv=の後の00000000000が動画ID。
https://www.youtube.com/watch?v=00000000000&list=AAAAAAAAAAAAA のlist=の後のAAAAAAAAAAAAAがプレイリストID。
基本的には最高品質の動画(と音声)をダウンロードするということになっています。これはyoutube-dlも同じです。特に考えずに利用する場合は上の様に単純に動画IDまたは動画URLを引数に指定するだけです。

プレイリストIDと動画IDが同時に含まれるURL(再生中のプレイリストURLなど)を指定するとプレイリストは無視され1つの動画だけが取得されるのでご注意ください。

yt-dlpのオプション

指定できるオプションは豊富すぎるほどあります。多くは使わないかもしれませんが、イザというときに使えるよう存在を知っておくのが良さそうです。

Options:
  General Options:
    -h, --help                                              Print this help text and exit
    --version                                               Print program version and exit
    -U, --update                                            Check if updates are available. You installed yt-dlp with pip or using the
                                                            wheel from PyPi; Use that to update
    --no-update                                             Do not check for updates (default)
    -i, --ignore-errors                                     Ignore download and postprocessing errors. The download will be considered
                                                            successful even if the postprocessing fails
    --no-abort-on-error                                     Continue with next video on download errors; e.g. to skip unavailable
                                                            videos in a playlist (default)
    --abort-on-error                                        Abort downloading of further videos if an error occurs (Alias: --no-
                                                            ignore-errors)
    --dump-user-agent                                       Display the current user-agent and exit
    --list-extractors                                       List all supported extractors and exit
    --extractor-descriptions                                Output descriptions of all supported extractors and exit
    --use-extractors NAMES                                  Extractor names to use separated by commas. You can also use regexes,
                                                            "all", "default" and "end" (end URL matching); e.g. --ies
                                                            "holodex.*,end,youtube". Prefix the name with a "-" to exclude it, e.g.
                                                            --ies default,-generic. Use --list-extractors for a list of extractor
                                                            names. (Alias: --ies)
    --default-search PREFIX                                 Use this prefix for unqualified URLs. E.g. "gvsearch2:python" downloads
                                                            two videos from google videos for the search term "python". Use the value
                                                            "auto" to let yt-dlp guess ("auto_warning" to emit a warning when
                                                            guessing). "error" just throws an error. The default value "fixup_error"
                                                            repairs broken URLs, but emits an error if this is not possible instead of
                                                            searching
    --ignore-config                                         Don't load any more configuration files except those given by --config-
                                                            locations. For backward compatibility, if this option is found inside the
                                                            system configuration file, the user configuration is not loaded. (Alias:
                                                            --no-config)
    --no-config-locations                                   Do not load any custom configuration files (default). When given inside a
                                                            configuration file, ignore all previous --config-locations defined in the
                                                            current file
    --config-locations PATH                                 Location of the main configuration file; either the path to the config or
                                                            its containing directory ("-" for stdin). Can be used multiple times and
                                                            inside other configuration files
    --flat-playlist                                         Do not extract the videos of a playlist, only list them
    --no-flat-playlist                                      Extract the videos of a playlist
    --live-from-start                                       Download livestreams from the start. Currently only supported for YouTube
                                                            (Experimental)
    --no-live-from-start                                    Download livestreams from the current time (default)
    --wait-for-video MIN[-MAX]                              Wait for scheduled streams to become available. Pass the minimum number of
                                                            seconds (or range) to wait between retries
    --no-wait-for-video                                     Do not wait for scheduled streams (default)
    --mark-watched                                          Mark videos watched (even with --simulate)
    --no-mark-watched                                       Do not mark videos watched (default)
    --no-colors                                             Do not emit color codes in output (Alias: --no-colours)
    --compat-options OPTS                                   Options that can help keep compatibility with youtube-dl or youtube-dlc
                                                            configurations by reverting some of the changes made in yt-dlp. See
                                                            "Differences in default behavior" for details
    --alias ALIASES OPTIONS                                 Create aliases for an option string. Unless an alias starts with a dash
                                                            "-", it is prefixed with "--". Arguments are parsed according to the
                                                            Python string formatting mini-language. E.g. --alias get-audio,-X
                                                            "-S=aext:{0},abr -x --audio-format {0}" creates options "--get-audio" and
                                                            "-X" that takes an argument (ARG0) and expands to "-S=aext:ARG0,abr -x
                                                            --audio-format ARG0". All defined aliases are listed in the --help output.
                                                            Alias options can trigger more aliases; so be careful to avoid defining
                                                            recursive options. As a safety measure, each alias may be triggered a
                                                            maximum of 100 times. This option can be used multiple times

  Network Options:
    --proxy URL                                             Use the specified HTTP/HTTPS/SOCKS proxy. To enable SOCKS proxy, specify a
                                                            proper scheme, e.g. socks5://user:pass@127.0.0.1:1080/. Pass in an empty
                                                            string (--proxy "") for direct connection
    --socket-timeout SECONDS                                Time to wait before giving up, in seconds
    --source-address IP                                     Client-side IP address to bind to
    -4, --force-ipv4                                        Make all connections via IPv4
    -6, --force-ipv6                                        Make all connections via IPv6
    --enable-file-urls                                      Enable file:// URLs. This is disabled by default for security reasons.

  Geo-restriction:
    --geo-verification-proxy URL                            Use this proxy to verify the IP address for some geo-restricted sites. The
                                                            default proxy specified by --proxy (or none, if the option is not present)
                                                            is used for the actual downloading
    --geo-bypass                                            Bypass geographic restriction via faking X-Forwarded-For HTTP header
                                                            (default)
    --no-geo-bypass                                         Do not bypass geographic restriction via faking X-Forwarded-For HTTP
                                                            header
    --geo-bypass-country CODE                               Force bypass geographic restriction with explicitly provided two-letter
                                                            ISO 3166-2 country code
    --geo-bypass-ip-block IP_BLOCK                          Force bypass geographic restriction with explicitly provided IP block in
                                                            CIDR notation

  Video Selection:
    -I, --playlist-items ITEM_SPEC                          Comma separated playlist_index of the items to download. You can specify a
                                                            range using "[START]:[STOP][:STEP]". For backward compatibility, START-
                                                            STOP is also supported. Use negative indices to count from the right and
                                                            negative STEP to download in reverse order. E.g. "-I 1:3,7,-5::2" used on
                                                            a playlist of size 15 will download the items at index 1,2,3,7,11,13,15
    --min-filesize SIZE                                     Abort download if filesize is smaller than SIZE, e.g. 50k or 44.6M
    --max-filesize SIZE                                     Abort download if filesize is larger than SIZE, e.g. 50k or 44.6M
    --date DATE                                             Download only videos uploaded on this date. The date can be "YYYYMMDD" or
                                                            in the format [now|today|yesterday][-N[day|week|month|year]]. E.g. "--date
                                                            today-2weeks" downloads only videos uploaded on the same day two weeks ago
    --datebefore DATE                                       Download only videos uploaded on or before this date. The date formats
                                                            accepted is the same as --date
    --dateafter DATE                                        Download only videos uploaded on or after this date. The date formats
                                                            accepted is the same as --date
    --match-filters FILTER                                  Generic video filter. Any "OUTPUT TEMPLATE" field can be compared with a
                                                            number or a string using the operators defined in "Filtering Formats". You
                                                            can also simply specify a field to match if the field is present, use
                                                            "!field" to check if the field is not present, and "&" to check multiple
                                                            conditions. Use a "\" to escape "&" or quotes if needed. If used multiple
                                                            times, the filter matches if atleast one of the conditions are met. E.g.
                                                            --match-filter !is_live --match-filter "like_count>?100 &
                                                            description~='(?i)\bcats \& dogs\b'" matches only videos that are not live
                                                            OR those that have a like count more than 100 (or the like field is not
                                                            available) and also has a description that contains the phrase "cats &
                                                            dogs" (caseless). Use "--match-filter -" to interactively ask whether to
                                                            download each video
    --no-match-filter                                       Do not use generic video filter (default)
    --no-playlist                                           Download only the video, if the URL refers to a video and a playlist
    --yes-playlist                                          Download the playlist, if the URL refers to a video and a playlist
    --age-limit YEARS                                       Download only videos suitable for the given age
    --download-archive FILE                                 Download only videos not listed in the archive file. Record the IDs of all
                                                            downloaded videos in it
    --no-download-archive                                   Do not use archive file (default)
    --max-downloads NUMBER                                  Abort after downloading NUMBER files
    --break-on-existing                                     Stop the download process when encountering a file that is in the archive
    --break-on-reject                                       Stop the download process when encountering a file that has been filtered
                                                            out
    --break-per-input                                       Alters --max-downloads, --break-on-existing, --break-on-reject, and
                                                            autonumber to reset per input URL
    --no-break-per-input                                    --break-on-existing and similar options terminates the entire download
                                                            queue
    --skip-playlist-after-errors N                          Number of allowed failures until the rest of the playlist is skipped

  Download Options:
    -N, --concurrent-fragments N                            Number of fragments of a dash/hlsnative video that should be downloaded
                                                            concurrently (default is 1)
    -r, --limit-rate RATE                                   Maximum download rate in bytes per second, e.g. 50K or 4.2M
    --throttled-rate RATE                                   Minimum download rate in bytes per second below which throttling is
                                                            assumed and the video data is re-extracted, e.g. 100K
    -R, --retries RETRIES                                   Number of retries (default is 10), or "infinite"
    --file-access-retries RETRIES                           Number of times to retry on file access error (default is 3), or
                                                            "infinite"
    --fragment-retries RETRIES                              Number of retries for a fragment (default is 10), or "infinite" (DASH,
                                                            hlsnative and ISM)
    --retry-sleep [TYPE:]EXPR                               Time to sleep between retries in seconds (optionally) prefixed by the type
                                                            of retry (http (default), fragment, file_access, extractor) to apply the
                                                            sleep to. EXPR can be a number, linear=START[:END[:STEP=1]] or
                                                            exp=START[:END[:BASE=2]]. This option can be used multiple times to set
                                                            the sleep for the different retry types, e.g. --retry-sleep linear=1::2
                                                            --retry-sleep fragment:exp=1:20
    --skip-unavailable-fragments                            Skip unavailable fragments for DASH, hlsnative and ISM downloads (default)
                                                            (Alias: --no-abort-on-unavailable-fragments)
    --abort-on-unavailable-fragments                        Abort download if a fragment is unavailable (Alias: --no-skip-unavailable-
                                                            fragments)
    --keep-fragments                                        Keep downloaded fragments on disk after downloading is finished
    --no-keep-fragments                                     Delete downloaded fragments after downloading is finished (default)
    --buffer-size SIZE                                      Size of download buffer, e.g. 1024 or 16K (default is 1024)
    --resize-buffer                                         The buffer size is automatically resized from an initial value of
                                                            --buffer-size (default)
    --no-resize-buffer                                      Do not automatically adjust the buffer size
    --http-chunk-size SIZE                                  Size of a chunk for chunk-based HTTP downloading, e.g. 10485760 or 10M
                                                            (default is disabled). May be useful for bypassing bandwidth throttling
                                                            imposed by a webserver (experimental)
    --playlist-random                                       Download playlist videos in random order
    --lazy-playlist                                         Process entries in the playlist as they are received. This disables
                                                            n_entries, --playlist-random and --playlist-reverse
    --no-lazy-playlist                                      Process videos in the playlist only after the entire playlist is parsed
                                                            (default)
    --xattr-set-filesize                                    Set file xattribute ytdl.filesize with expected file size
    --hls-use-mpegts                                        Use the mpegts container for HLS videos; allowing some players to play the
                                                            video while downloading, and reducing the chance of file corruption if
                                                            download is interrupted. This is enabled by default for live streams
    --no-hls-use-mpegts                                     Do not use the mpegts container for HLS videos. This is default when not
                                                            downloading live streams
    --download-sections REGEX                               Download only chapters whose title matches the given regular expression.
                                                            Time ranges prefixed by a "*" can also be used in place of chapters to
                                                            download the specified range. Needs ffmpeg. This option can be used
                                                            multiple times to download multiple sections, e.g. --download-sections
                                                            "*10:15-inf" --download-sections "intro"
    --downloader [PROTO:]NAME                               Name or path of the external downloader to use (optionally) prefixed by
                                                            the protocols (http, ftp, m3u8, dash, rstp, rtmp, mms) to use it for.
                                                            Currently supports native, aria2c, avconv, axel, curl, ffmpeg, httpie,
                                                            wget. You can use this option multiple times to set different downloaders
                                                            for different protocols. E.g. --downloader aria2c --downloader
                                                            "dash,m3u8:native" will use aria2c for http/ftp downloads, and the native
                                                            downloader for dash/m3u8 downloads (Alias: --external-downloader)
    --downloader-args NAME:ARGS                             Give these arguments to the external downloader. Specify the downloader
                                                            name and the arguments separated by a colon ":". For ffmpeg, arguments can
                                                            be passed to different positions using the same syntax as --postprocessor-
                                                            args. You can use this option multiple times to give different arguments
                                                            to different downloaders (Alias: --external-downloader-args)

  Filesystem Options:
    -a, --batch-file FILE                                   File containing URLs to download ("-" for stdin), one URL per line. Lines
                                                            starting with "#", ";" or "]" are considered as comments and ignored
    --no-batch-file                                         Do not read URLs from batch file (default)
    -P, --paths [TYPES:]PATH                                The paths where the files should be downloaded. Specify the type of file
                                                            and the path separated by a colon ":". All the same TYPES as --output are
                                                            supported. Additionally, you can also provide "home" (default) and "temp"
                                                            paths. All intermediary files are first downloaded to the temp path and
                                                            then the final files are moved over to the home path after download is
                                                            finished. This option is ignored if --output is an absolute path
    -o, --output [TYPES:]TEMPLATE                           Output filename template; see "OUTPUT TEMPLATE" for details
    --output-na-placeholder TEXT                            Placeholder for unavailable fields in "OUTPUT TEMPLATE" (default: "NA")
    --restrict-filenames                                    Restrict filenames to only ASCII characters, and avoid "&" and spaces in
                                                            filenames
    --no-restrict-filenames                                 Allow Unicode characters, "&" and spaces in filenames (default)
    --windows-filenames                                     Force filenames to be Windows-compatible
    --no-windows-filenames                                  Make filenames Windows-compatible only if using Windows (default)
    --trim-filenames LENGTH                                 Limit the filename length (excluding extension) to the specified number of
                                                            characters
    -w, --no-overwrites                                     Do not overwrite any files
    --force-overwrites                                      Overwrite all video and metadata files. This option includes --no-continue
    --no-force-overwrites                                   Do not overwrite the video, but overwrite related files (default)
    -c, --continue                                          Resume partially downloaded files/fragments (default)
    --no-continue                                           Do not resume partially downloaded fragments. If the file is not
                                                            fragmented, restart download of the entire file
    --part                                                  Use .part files instead of writing directly into output file (default)
    --no-part                                               Do not use .part files - write directly into output file
    --mtime                                                 Use the Last-modified header to set the file modification time (default)
    --no-mtime                                              Do not use the Last-modified header to set the file modification time
    --write-description                                     Write video description to a .description file
    --no-write-description                                  Do not write video description (default)
    --write-info-json                                       Write video metadata to a .info.json file (this may contain personal
                                                            information)
    --no-write-info-json                                    Do not write video metadata (default)
    --write-playlist-metafiles                              Write playlist metadata in addition to the video metadata when using
                                                            --write-info-json, --write-description etc. (default)
    --no-write-playlist-metafiles                           Do not write playlist metadata when using --write-info-json, --write-
                                                            description etc.
    --clean-info-json                                       Remove some private fields such as filenames from the infojson. Note that
                                                            it could still contain some personal information (default)
    --no-clean-info-json                                    Write all fields to the infojson
    --write-comments                                        Retrieve video comments to be placed in the infojson. The comments are
                                                            fetched even without this option if the extraction is known to be quick
                                                            (Alias: --get-comments)
    --no-write-comments                                     Do not retrieve video comments unless the extraction is known to be quick
                                                            (Alias: --no-get-comments)
    --load-info-json FILE                                   JSON file containing the video information (created with the "--write-
                                                            info-json" option)
    --cookies FILE                                          Netscape formatted file to read cookies from and dump cookie jar in
    --no-cookies                                            Do not read/dump cookies from/to file (default)
    --cookies-from-browser BROWSER[+KEYRING][:PROFILE][::CONTAINER]
                                                            The name of the browser to load cookies from. Currently supported browsers
                                                            are: brave, chrome, chromium, edge, firefox, opera, safari, vivaldi.
                                                            Optionally, the KEYRING used for decrypting Chromium cookies on Linux, the
                                                            name/path of the PROFILE to load cookies from, and the CONTAINER name (if
                                                            Firefox) ("none" for no container) can be given with their respective
                                                            seperators. By default, all containers of the most recently accessed
                                                            profile are used. Currently supported keyrings are: basictext,
                                                            gnomekeyring, kwallet
    --no-cookies-from-browser                               Do not load cookies from browser (default)
    --cache-dir DIR                                         Location in the filesystem where yt-dlp can store some downloaded
                                                            information (such as client ids and signatures) permanently. By default
                                                            ${XDG_CACHE_HOME}/yt-dlp
    --no-cache-dir                                          Disable filesystem caching
    --rm-cache-dir                                          Delete all filesystem cache files

  Thumbnail Options:
    --write-thumbnail                                       Write thumbnail image to disk
    --no-write-thumbnail                                    Do not write thumbnail image to disk (default)
    --write-all-thumbnails                                  Write all thumbnail image formats to disk
    --list-thumbnails                                       List available thumbnails of each video. Simulate unless --no-simulate is
                                                            used

  Internet Shortcut Options:
    --write-link                                            Write an internet shortcut file, depending on the current platform (.url,
                                                            .webloc or .desktop). The URL may be cached by the OS
    --write-url-link                                        Write a .url Windows internet shortcut. The OS caches the URL based on the
                                                            file path
    --write-webloc-link                                     Write a .webloc macOS internet shortcut
    --write-desktop-link                                    Write a .desktop Linux internet shortcut

  Verbosity and Simulation Options:
    -q, --quiet                                             Activate quiet mode. If used with --verbose, print the log to stderr
    --no-warnings                                           Ignore warnings
    -s, --simulate                                          Do not download the video and do not write anything to disk
    --no-simulate                                           Download the video even if printing/listing options are used
    --ignore-no-formats-error                               Ignore "No video formats" error. Useful for extracting metadata even if
                                                            the videos are not actually available for download (experimental)
    --no-ignore-no-formats-error                            Throw error when no downloadable video formats are found (default)
    --skip-download                                         Do not download the video but write all related files (Alias: --no-
                                                            download)
    -O, --print [WHEN:]TEMPLATE                             Field name or output template to print to screen, optionally prefixed with
                                                            when to print it, separated by a ":". Supported values of "WHEN" are the
                                                            same as that of --use-postprocessor (default: video). Implies --quiet.
                                                            Implies --simulate unless --no-simulate or later stages of WHEN are used.
                                                            This option can be used multiple times
    --print-to-file [WHEN:]TEMPLATE FILE                    Append given template to the file. The values of WHEN and TEMPLATE are
                                                            same as that of --print. FILE uses the same syntax as the output template.
                                                            This option can be used multiple times
    -j, --dump-json                                         Quiet, but print JSON information for each video. Simulate unless --no-
                                                            simulate is used. See "OUTPUT TEMPLATE" for a description of available
                                                            keys
    -J, --dump-single-json                                  Quiet, but print JSON information for each url or infojson passed.
                                                            Simulate unless --no-simulate is used. If the URL refers to a playlist,
                                                            the whole playlist information is dumped in a single line
    --force-write-archive                                   Force download archive entries to be written as far as no errors occur,
                                                            even if -s or another simulation option is used (Alias: --force-download-
                                                            archive)
    --newline                                               Output progress bar as new lines
    --no-progress                                           Do not print progress bar
    --progress                                              Show progress bar, even if in quiet mode
    --console-title                                         Display progress in console titlebar
    --progress-template [TYPES:]TEMPLATE                    Template for progress outputs, optionally prefixed with one of "download:"
                                                            (default), "download-title:" (the console title), "postprocess:",  or
                                                            "postprocess-title:". The video's fields are accessible under the "info"
                                                            key and the progress attributes are accessible under "progress" key. E.g.
                                                            --console-title --progress-template "download-
                                                            title:%(info.id)s-%(progress.eta)s"
    -v, --verbose                                           Print various debugging information
    --dump-pages                                            Print downloaded pages encoded using base64 to debug problems (very
                                                            verbose)
    --write-pages                                           Write downloaded intermediary pages to files in the current directory to
                                                            debug problems
    --print-traffic                                         Display sent and read HTTP traffic

  Workarounds:
    --encoding ENCODING                                     Force the specified encoding (experimental)
    --legacy-server-connect                                 Explicitly allow HTTPS connection to servers that do not support RFC 5746
                                                            secure renegotiation
    --no-check-certificates                                 Suppress HTTPS certificate validation
    --prefer-insecure                                       Use an unencrypted connection to retrieve information about the video
                                                            (Currently supported only for YouTube)
    --add-headers FIELD:VALUE                               Specify a custom HTTP header and its value, separated by a colon ":". You
                                                            can use this option multiple times
    --bidi-workaround                                       Work around terminals that lack bidirectional text support. Requires bidiv
                                                            or fribidi executable in PATH
    --sleep-requests SECONDS                                Number of seconds to sleep between requests during data extraction
    --sleep-interval SECONDS                                Number of seconds to sleep before each download. This is the minimum time
                                                            to sleep when used along with --max-sleep-interval (Alias: --min-sleep-
                                                            interval)
    --max-sleep-interval SECONDS                            Maximum number of seconds to sleep. Can only be used along with --min-
                                                            sleep-interval
    --sleep-subtitles SECONDS                               Number of seconds to sleep before each subtitle download

  Video Format Options:
    -f, --format FORMAT                                     Video format code, see "FORMAT SELECTION" for more details
    -S, --format-sort SORTORDER                             Sort the formats by the fields given, see "Sorting Formats" for more
                                                            details
    --format-sort-force                                     Force user specified sort order to have precedence over all fields, see
                                                            "Sorting Formats" for more details (Alias: --S-force)
    --no-format-sort-force                                  Some fields have precedence over the user specified sort order (default)
    --video-multistreams                                    Allow multiple video streams to be merged into a single file
    --no-video-multistreams                                 Only one video stream is downloaded for each output file (default)
    --audio-multistreams                                    Allow multiple audio streams to be merged into a single file
    --no-audio-multistreams                                 Only one audio stream is downloaded for each output file (default)
    --prefer-free-formats                                   Prefer video formats with free containers over non-free ones of same
                                                            quality. Use with "-S ext" to strictly prefer free containers irrespective
                                                            of quality
    --no-prefer-free-formats                                Don't give any special preference to free containers (default)
    --check-formats                                         Make sure formats are selected only from those that are actually
                                                            downloadable
    --check-all-formats                                     Check all formats for whether they are actually downloadable
    --no-check-formats                                      Do not check that the formats are actually downloadable
    -F, --list-formats                                      List available formats of each video. Simulate unless --no-simulate is
                                                            used
    --merge-output-format FORMAT                            Containers that may be used when merging formats, separated by "/", e.g.
                                                            "mp4/mkv". Ignored if no merge is required. (currently supported: avi,
                                                            flv, mkv, mov, mp4, webm)

  Subtitle Options:
    --write-subs                                            Write subtitle file
    --no-write-subs                                         Do not write subtitle file (default)
    --write-auto-subs                                       Write automatically generated subtitle file (Alias: --write-automatic-
                                                            subs)
    --no-write-auto-subs                                    Do not write auto-generated subtitles (default) (Alias: --no-write-
                                                            automatic-subs)
    --list-subs                                             List available subtitles of each video. Simulate unless --no-simulate is
                                                            used
    --sub-format FORMAT                                     Subtitle format; accepts formats preference, e.g. "srt" or "ass/srt/best"
    --sub-langs LANGS                                       Languages of the subtitles to download (can be regex) or "all" separated
                                                            by commas, e.g. --sub-langs "en.*,ja". You can prefix the language code
                                                            with a "-" to exclude it from the requested languages, e.g. --sub-langs
                                                            all,-live_chat. Use --list-subs for a list of available language tags

  Authentication Options:
    -u, --username USERNAME                                 Login with this account ID
    -p, --password PASSWORD                                 Account password. If this option is left out, yt-dlp will ask
                                                            interactively
    -2, --twofactor TWOFACTOR                               Two-factor authentication code
    -n, --netrc                                             Use .netrc authentication data
    --netrc-location PATH                                   Location of .netrc authentication data; either the path or its containing
                                                            directory. Defaults to ~/.netrc
    --video-password PASSWORD                               Video password (vimeo, youku)
    --ap-mso MSO                                            Adobe Pass multiple-system operator (TV provider) identifier, use --ap-
                                                            list-mso for a list of available MSOs
    --ap-username USERNAME                                  Multiple-system operator account login
    --ap-password PASSWORD                                  Multiple-system operator account password. If this option is left out, yt-
                                                            dlp will ask interactively
    --ap-list-mso                                           List all supported multiple-system operators
    --client-certificate CERTFILE                           Path to client certificate file in PEM format. May include the private key
    --client-certificate-key KEYFILE                        Path to private key file for client certificate
    --client-certificate-password PASSWORD                  Password for client certificate private key, if encrypted. If not
                                                            provided, and the key is encrypted, yt-dlp will ask interactively

  Post-Processing Options:
    -x, --extract-audio                                     Convert video files to audio-only files (requires ffmpeg and ffprobe)
    --audio-format FORMAT                                   Format to convert the audio to when -x is used. (currently supported: best
                                                            (default), aac, alac, flac, m4a, mp3, opus, vorbis, wav). You can specify
                                                            multiple rules using similar syntax as --remux-video
    --audio-quality QUALITY                                 Specify ffmpeg audio quality to use when converting the audio with -x.
                                                            Insert a value between 0 (best) and 10 (worst) for VBR or a specific
                                                            bitrate like 128K (default 5)
    --remux-video FORMAT                                    Remux the video into another container if necessary (currently supported:
                                                            avi, flv, gif, mkv, mov, mp4, webm, aac, aiff, alac, flac, m4a, mka, mp3,
                                                            ogg, opus, vorbis, wav). If target container does not support the
                                                            video/audio codec, remuxing will fail. You can specify multiple rules;
                                                            e.g. "aac>m4a/mov>mp4/mkv" will remux aac to m4a, mov to mp4 and anything
                                                            else to mkv
    --recode-video FORMAT                                   Re-encode the video into another format if necessary. The syntax and
                                                            supported formats are the same as --remux-video
    --postprocessor-args NAME:ARGS                          Give these arguments to the postprocessors. Specify the
                                                            postprocessor/executable name and the arguments separated by a colon ":"
                                                            to give the argument to the specified postprocessor/executable. Supported
                                                            PP are: Merger, ModifyChapters, SplitChapters, ExtractAudio, VideoRemuxer,
                                                            VideoConvertor, Metadata, EmbedSubtitle, EmbedThumbnail,
                                                            SubtitlesConvertor, ThumbnailsConvertor, FixupStretched, FixupM4a,
                                                            FixupM3u8, FixupTimestamp and FixupDuration. The supported executables
                                                            are: AtomicParsley, FFmpeg and FFprobe. You can also specify "PP+EXE:ARGS"
                                                            to give the arguments to the specified executable only when being used by
                                                            the specified postprocessor. Additionally, for ffmpeg/ffprobe, "_i"/"_o"
                                                            can be appended to the prefix optionally followed by a number to pass the
                                                            argument before the specified input/output file, e.g. --ppa
                                                            "Merger+ffmpeg_i1:-v quiet". You can use this option multiple times to
                                                            give different arguments to different postprocessors. (Alias: --ppa)
    -k, --keep-video                                        Keep the intermediate video file on disk after post-processing
    --no-keep-video                                         Delete the intermediate video file after post-processing (default)
    --post-overwrites                                       Overwrite post-processed files (default)
    --no-post-overwrites                                    Do not overwrite post-processed files
    --embed-subs                                            Embed subtitles in the video (only for mp4, webm and mkv videos)
    --no-embed-subs                                         Do not embed subtitles (default)
    --embed-thumbnail                                       Embed thumbnail in the video as cover art
    --no-embed-thumbnail                                    Do not embed thumbnail (default)
    --embed-metadata                                        Embed metadata to the video file. Also embeds chapters/infojson if present
                                                            unless --no-embed-chapters/--no-embed-info-json are used (Alias: --add-
                                                            metadata)
    --no-embed-metadata                                     Do not add metadata to file (default) (Alias: --no-add-metadata)
    --embed-chapters                                        Add chapter markers to the video file (Alias: --add-chapters)
    --no-embed-chapters                                     Do not add chapter markers (default) (Alias: --no-add-chapters)
    --embed-info-json                                       Embed the infojson as an attachment to mkv/mka video files
    --no-embed-info-json                                    Do not embed the infojson as an attachment to the video file
    --parse-metadata [WHEN:]FROM:TO                         Parse additional metadata like title/artist from other fields; see
                                                            "MODIFYING METADATA" for details. Supported values of "WHEN" are the same
                                                            as that of --use-postprocessor (default: pre_process)
    --replace-in-metadata [WHEN:]FIELDS REGEX REPLACE       Replace text in a metadata field using the given regex. This option can be
                                                            used multiple times. Supported values of "WHEN" are the same as that of
                                                            --use-postprocessor (default: pre_process)
    --xattrs                                                Write metadata to the video file's xattrs (using dublin core and xdg
                                                            standards)
    --concat-playlist POLICY                                Concatenate videos in a playlist. One of "never", "always", or
                                                            "multi_video" (default; only when the videos form a single show). All the
                                                            video files must have same codecs and number of streams to be concatable.
                                                            The "pl_video:" prefix can be used with "--paths" and "--output" to set
                                                            the output filename for the concatenated files. See "OUTPUT TEMPLATE" for
                                                            details
    --fixup POLICY                                          Automatically correct known faults of the file. One of never (do nothing),
                                                            warn (only emit a warning), detect_or_warn (the default; fix file if we
                                                            can, warn otherwise), force (try fixing even if file already exists)
    --ffmpeg-location PATH                                  Location of the ffmpeg binary; either the path to the binary or its
                                                            containing directory
    --exec [WHEN:]CMD                                       Execute a command, optionally prefixed with when to execute it, separated
                                                            by a ":". Supported values of "WHEN" are the same as that of --use-
                                                            postprocessor (default: after_move). Same syntax as the output template
                                                            can be used to pass any field as arguments to the command. After download,
                                                            an additional field "filepath" that contains the final path of the
                                                            downloaded file is also available, and if no fields are passed,
                                                            %(filepath,_filename|)q is appended to the end of the command. This option
                                                            can be used multiple times
    --no-exec                                               Remove any previously defined --exec
    --convert-subs FORMAT                                   Convert the subtitles to another format (currently supported: ass, lrc,
                                                            srt, vtt) (Alias: --convert-subtitles)
    --convert-thumbnails FORMAT                             Convert the thumbnails to another format (currently supported: jpg, png,
                                                            webp). You can specify multiple rules using similar syntax as --remux-
                                                            video
    --split-chapters                                        Split video into multiple files based on internal chapters. The "chapter:"
                                                            prefix can be used with "--paths" and "--output" to set the output
                                                            filename for the split files. See "OUTPUT TEMPLATE" for details
    --no-split-chapters                                     Do not split video based on chapters (default)
    --remove-chapters REGEX                                 Remove chapters whose title matches the given regular expression. The
                                                            syntax is the same as --download-sections. This option can be used
                                                            multiple times
    --no-remove-chapters                                    Do not remove any chapters from the file (default)
    --force-keyframes-at-cuts                               Force keyframes at cuts when downloading/splitting/removing sections. This
                                                            is slow due to needing a re-encode, but the resulting video may have fewer
                                                            artifacts around the cuts
    --no-force-keyframes-at-cuts                            Do not force keyframes around the chapters when cutting/splitting
                                                            (default)
    --use-postprocessor NAME[:ARGS]                         The (case sensitive) name of plugin postprocessors to be enabled, and
                                                            (optionally) arguments to be passed to it, separated by a colon ":". ARGS
                                                            are a semicolon ";" delimited list of NAME=VALUE. The "when" argument
                                                            determines when the postprocessor is invoked. It can be one of
                                                            "pre_process" (after video extraction), "after_filter" (after video passes
                                                            filter), "video" (after --format; before --print/--output), "before_dl"
                                                            (before each video download), "post_process" (after each video download;
                                                            default), "after_move" (after moving video file to it's final locations),
                                                            "after_video" (after downloading and processing all formats of a video),
                                                            or "playlist" (at end of playlist). This option can be used multiple times
                                                            to add different postprocessors

  SponsorBlock Options:
    Make chapter entries for, or remove various segments (sponsor, introductions, etc.) from downloaded YouTube videos using the
    SponsorBlock API (https://sponsor.ajay.app)

    --sponsorblock-mark CATS                                SponsorBlock categories to create chapters for, separated by commas.
                                                            Available categories are sponsor, intro, outro, selfpromo, preview,
                                                            filler, interaction, music_offtopic, poi_highlight, chapter, all and
                                                            default (=all). You can prefix the category with a "-" to exclude it. See
                                                            [1] for description of the categories. E.g. --sponsorblock-mark
                                                            all,-preview [1] https://wiki.sponsor.ajay.app/w/Segment_Categories
    --sponsorblock-remove CATS                              SponsorBlock categories to be removed from the video file, separated by
                                                            commas. If a category is present in both mark and remove, remove takes
                                                            precedence. The syntax and available categories are the same as for
                                                            --sponsorblock-mark except that "default" refers to "all,-filler" and
                                                            poi_highlight, chapter are not available
    --sponsorblock-chapter-title TEMPLATE                   An output template for the title of the SponsorBlock chapters created by
                                                            --sponsorblock-mark. The only available fields are start_time, end_time,
                                                            category, categories, name, category_names. Defaults to "[SponsorBlock]:
                                                            %(category_names)l"
    --no-sponsorblock                                       Disable both --sponsorblock-mark and --sponsorblock-remove
    --sponsorblock-api URL                                  SponsorBlock API location, defaults to https://sponsor.ajay.app

  Extractor Options:
    --extractor-retries RETRIES                             Number of retries for known extractor errors (default is 3), or "infinite"
    --allow-dynamic-mpd                                     Process dynamic DASH manifests (default) (Alias: --no-ignore-dynamic-mpd)
    --ignore-dynamic-mpd                                    Do not process dynamic DASH manifests (Alias: --no-allow-dynamic-mpd)
    --hls-split-discontinuity                               Split HLS playlists to different formats at discontinuities such as ad
                                                            breaks
    --no-hls-split-discontinuity                            Do not split HLS playlists to different formats at discontinuities such as
                                                            ad breaks (default)
    --extractor-args IE_KEY:ARGS                            Pass ARGS arguments to the IE_KEY extractor. See "EXTRACTOR ARGUMENTS" for
                                                            details. You can use this option multiple times to give arguments for
                                                            different extractors

フォーマットを指定したダウンロード

YouTubeだと1つの動画と思っているものが実は複数の形式で保管されています。また、動画ファイルの種類が複数あるだけでなく、動画ファイルに含まれる動画・音声のフォーマットも複数あります。フォーマットを指定すれば期待通りの動画・音声を取得できます。

yt-dlpの使い方備忘録 2
yt-dlp -F 動画ID or 動画URL でその動画で利用できる映像/音声のフォーマットリストが表示されます。
行頭の緑の数字がフォーマットコードなので、上の例ではmp4の動画の1920x1080の解像度は137、音声の44kHzのm4aは140ということが判ります。
ダウンロードしたい動画によって存在するフォーマットが違うことがあるので、例えばどの動画でもフォーマットコード137のmp4動画1920x1080があるとは限りません。10年以上前の古い動画だとVGA解像度以下しかないのもザラです。
フォーマットによってはvideo only(音声なしの動画) / audio only(動画なしの音声) / 動画+音声があります。つまり1つのフォーマットだけでは完全な音声付き動画ではないことがあります。
今回はHD+解像度のMP4動画で音声付きのフォーマット番号22をダウンロードすることにします。(次)

yt-dlpの使い方備忘録 3

$ yt-dlp -f 22 動画ID or 動画URL  (小文字の-fです)

yt-dlpの使い方備忘録 4
今度は違う動画です。含まれるフォーマットの数が減っています。
動画は、322x240pxのMP4のフォーマットコード番号133、
音声は、44kのm4aのフォーマットコード番号140をダウンロードすることにします。(次)

yt-dlpの使い方備忘録 5
mp4動画とm4a音声の2つをダウンロードして1つのmp4動画にマージします。

$ yt-dlp -f 133+140 --merge-output-format mp4 動画ID or 動画URL

動画から音声だけをFLAC形式で取得する

$ yt-dlp -x --audio-format flac 動画ID or 動画URL (元のフォーマット未指定)

$ yt-dlp -f 251 -x --audio-format flac --audio-quality 0 動画ID or 動画URL (元のフォーマット指定)
--audio-quality 0で出力するFLACの最高品質を指定しています。

動画から音声とサムネイル(アートワーク/カバーアート)をFLAC形式で取得する

$ yt-dlp -x --embed-thumbnail --audio-format flac 動画ID or 動画URL (元のフォーマット未指定)

この場合、カバーアートという楽曲ファイルのタグを編集することになるため基本的にはpythonのmutagenモジュールが必要になります。
$ sudo apt isntall python3-mutagen (インストールしないでください、以下)

ただし、Debian, Ubuntuでは実際にはpython3-mutagenはアプリから上手く呼び出せないという問題があります。mutagenを使用する場合にはPythonの仮想環境を作成してyt-dlpとmutagenをその環境用にインストールするのが簡単です。(以下)

# === 既存ファイル削除 ===================================
# aptでインストールした mutagen / yt-dlp がもしあれば全部消す
$ sudo apt remove --purge python3-mutagen yt-dlp
$ sudo rm -f /usr/local/bin/yt-dlp

# pipでインストールしたユーザー用の mutagen があれば残骸を全削除
$ PYSITE=$(python3 -c "import site, sys; print(site.getusersitepackages())")
$ python3 -m pip uninstall -y mutagen
$ rm -rf "$PYSITE"/mutagen*
$ rm -rf "$PYSITE"/Mutagen-*.dist-info
$ rm -rf ~/.local/bin/yt-dlp
$ rm -rf ~/.local/bin/mutagen*

# pipx でインストールしたyt-dlp/mutagenがあれば削除
$ pipx uninstall mutagen
$ pipx uninstall yt-dlp

# === 専用仮想環境を新規作成 ====================
$ python3 -m venv ~/py-ve
$ ~/py-ve/bin/pip install --upgrade pip
$ ~/py-ve/bin/pip install mutagen
$ ~/py-ve/bin/pip install --upgrade yt-dlp

# === yt-dlp を普通に呼べるようにする ====================
$ sudo ln -sf ~/py-ve/bin/yt-dlp /usr/local/bin/yt-dlp
ユーザーディレクトリ下に作成する py-veが仮想環境用のディレクトリです。(名前は任意)
変数$PYSITEは一般的には ~/.local/lib/python3.12/site-packages のようなユーザーディレクトリ下の隠しディレクトリになる筈です。3.12の部分は使用中のPythonのバージョンに応じて変わります。
一度もyt-dlpやpython-mutagenを使用したことがないシステムであれば「専用仮想環境を新規作成」以下を実行するだけです。
yt-dlpはPythonの仮想環境にインストールされますが、/usr/local/bin/yt-dlpにシンボリックリンクしているためこれまでと同じく普通にyt-dlpというコマンドで呼び出せます。

mutagenモジュールを使用できない場合は、AtomicParsleyを使用することもできるようです。しかしこちらは詳細は不明です。

$ yt-dlp -x ---compat-options embed-thumbnail-atomicparsley --audio-format flac 動画ID or 動画URL (元のフォーマット未指定)

多くの動画をダウンロードする場合

多くの動画を一挙にダウンロードしようとすると、途中からボットを疑われてダウンロードがエラーになります。ボットではないことを示すためにブラウザのCookieを使用すると回避できます。

ブラウザのCookieはOSとブラウザによって格納Pathが異なるかと思われますが、OSがLinux (Debian/Ubuntu系)でChromeブラウザの場合 ~/.config/google-chrome/ や ~/.config/google-chrome-beta/ などになります。「 ~ 」はユーザーのホームディレクトリを意味するので /home/ユーザー名 等です。このPathはこのオプションを初めて使用する前に実際にCookieが格納されているか確認しておく方が良いと思われます。また、オプションを使用してダウンロードを実行する前にそのサービス(Youtubeなど)をブラウザで閲覧しておかなければ意味がないかと思われます。
以下のようなオプションを追加して実行します。

  --cookies-from-browser chrome:~/.config/google-chrome-beta/

黄文字部分は自身の使用しているブラウザのCookie保存ディレクトリのPathに置き換えてください。
Cookieを使用して大量にダウンロードする場合は、途中からThe provided YouTube account cookies are no longer valid.という警告が出るようになることがあります。警告なのでダウンロードは失敗にはなりませんが、中断して再ダウンロードする方が良いかもしれません。その場合は以下。

100以上の動画が登録されている巨大なプレイリストからダウンロードする場合、途中からダウンロードがおかしくなったり中断しなければならないことがあります。中断後、最初からダウンロードをやりなおすのではなく、ダウンロード済みはそのままで続きからダウンロードしたいということがあります。yt-dlpにはダウンロードアーカイブというダウンロード済み動画IDをメモする機能があり、ダウンロード済みとして記載されたIDの動画は再ダウンロードされないため、この機能を使うことで中断以降の(ダウンロードが完了していない)動画だけダウンロードすることができます。
以下のようなオプションを追加して実行します。

  --download-archive archive.txt

黄文字の部分は任意のファイル名です。
当然ですが、中断前からこのオプションを使用している必要があります。つまり、大きなプレイリストからダウンロードする場合は最初から指定しておくべきです。ダウンロードが完了したらアーカイブテキストは削除して構いません。

フォーマットリストを見るのが面倒な場合、 -f bestvideo+bestaudio (最高動画+最高音声)や -f bv.2;ba.2 (2番めに良い動画+2番めに良い音声)のような指定もできますが、最高動画+最高音声ならオプションなしと実質同じですし、2番めに良いというのは使い方としてはちょっと指定する動機がわかりません。
-f "best[height=720]" (HD解像度の最高動画)のような指定は動機として理解できます。

youtube-dlと同じく基本的にはこのフォーマット指定で動画と音声をマージする方法だけ憶えておけば良さそうです。

2025年11月18日追記:
Youtubeについてはyt-dlpだけでは機能しなくなったようです。
以下のようにJavascriptランタイムのオプションを指定します。

$ yt-dlp --js-runtimes deno:~/.deno/bin/deno https://www.youtube.com/watch?v=動画ID
他のオプションも必要に応じて追加してください。

~/.deno/bin/deno はDenoがインストールされたディレクトリです。(UNIX系OSでは ~ はユーザーのホームディレクトリを指します)
2025年11月18日現在、対応するJavascriptランタイムはDenoの他にNode, Bun, QuickJSがあるようです。
Javascriptランタイムをインストールしていない場合は、--js-runtimes deno:~/.deno/bin/deno の代わりに --remote-components ejs:github が使えるかもしれません。

Up