youtube-dlのextractor書き方講座 3/4


あけましておめでとうございます

あけましておめでとうございます。
色々忙しくて気づいたら年末どころか年を越していました。

今年もよろしくお願いします。

前回の続き

また見てない方は前回はここからどうぞ。
前回はエラー処理を書きました。
今回は、最低限以上の情報の取得をやって行きます。

最終目標

これを作ります。

ウェブサイトから何が見えるのか

また適当な配信を持ってきました。開いてみましょう。

第一巻と同様、開発者ツールを開き、それっぽい通信を探してみましょう。
ChromeでもCtrl+Shift+Iで開きます。

とりあえず投稿者名で検索

少しスクロールすると、投稿者名や説明文などが出てきました。
これをDevToolsで検索すると、こんな感じ。

投稿者名などが出てきました。
このAPIエンドポイントのURLはhttps://api.whowatch.tv/lives/19199115でした。

この情報を抽出する

まず、'https://api.whowatch.tv/lives/' + video_idをダウンロードして、JSONとしてパースさせます。

metadata = self._download_json('https://api.whowatch.tv/lives/' + video_id, video_id)

さて、_real_extractの返り値はdictで返していたのを覚えていますか?
このdictのキーには一定の取り決めがあり、これはREADME.mdOUTPUT TEMPLATEセクションに掲載されています。

例えば、今回取り扱う投稿者名と投稿者のニックネームは、それぞれuploaderuploader_idになります。

この規則を守ってdictを設定していきます。

# その他の情報を取り出す
uploader = metadata['live']['user']['name']
uploader_id = metadata['live']['user']['user_path']

return {
    # (略)
    # 投稿者情報
    'uploader': uploader,
    'uploader_id': uploader_id,
}

同様に、thumbnailキーで(--write-thumbnailオプションで書き出すことができる)サムネイルを設定できます。

thumbnail = metadata['live']['latest_thumbnail_url']

return {
    # (略)
    # サムネイル
    'thumbnail': thumbnail,
}

おわりに

今回は、最低限以上の情報の取得を書きました。
これで、最終目標と同じようなextractorが完成したので、次はyoutube-dlのコーディング規則を簡単にやりたいと思います。
KeyErrorなどのエラーハンドリングは、youtube-dlで容易に行う方法が用意されているので、皆さんへの課題にしたいと思います。

ここまでご覧いただきありがとうございました。

次: 第4巻

付録: 今回のコード

# coding: utf-8
from __future__ import unicode_literals

from .common import InfoExtractor
from ..utils import ExtractorError


class WhoWatchIE(InfoExtractor):
    _VALID_URL = r'https?://whowatch\.tv/viewer/(?P<id>\d+)/?'

    def _real_extract(self, url):
        video_id = self._match_id(url)

        # URL、IDの順で指定する
        live_data = self._download_json('https://api.whowatch.tv/lives/' + video_id + '/play', video_id)
        metadata = self._download_json('https://api.whowatch.tv/lives/' + video_id, video_id)

        # デバッグ用: live_dataを表示する
        # self.to_screen(live_data)

        # HLSのURL
        hls_url = live_data.get('hls_url')

        # hls_urlが無ければエラーを投げる
        if not hls_url:
            raise ExtractorError(live_data.get('error_message'), expected=True)

        # とりあえずHLSのフォーマットを検索する
        formats = self._extract_m3u8_formats(
            hls_url, video_id, ext='mp4', entry_protocol='m3u8_native',
            m3u8_id='hls')
        # 並び替える。これによって何も設定しない状態で最高画質をダウンロードするようにする
        self._sort_formats(formats)

        # その他の情報を取り出す
        uploader = metadata['live']['user']['name']
        uploader_id = metadata['live']['user']['user_path']
        thumbnail = metadata['live']['latest_thumbnail_url']

        return {
            'id': video_id,
            # 鉤括弧があったので同時に外してしまう
            'title': live_data['share_info']['live_title'][1:-1],
            # フォーマット一覧
            'formats': formats,
            # これは生放送です
            'is_live': True,
            # 投稿者情報
            'uploader': uploader,
            'uploader_id': uploader_id,
            # サムネイル
            'thumbnail': thumbnail,
        }

今回のコードはここにも置いておきます。