Vtuberの配信アーカイブで盛り上がったところをPythonで探してみた。

# 背景
最近私は、YouTubeでにじさんじやホロライブの切り抜きを見ることにハマっている。
しかし、常々思うこととして本編を再生してないがいいのだろうかという疑問を抱えている。
かといって、配信アーカイブをすべて見る時間もない、、
ということで、配信アーカイブで盛り上がった部分をPythonを使い探すことはできないのかと思いプログラムを作ってみた。

# プログラムの概要
今回のプログラムはYouTubeのチャット欄でコメント数が多い時間を盛り上がった部分と仮定する。
YouTubeのチャット取得方法としては**chat-downloader**を使用した。
このライブラリはYouTubeのURLからチャットを取得しJOIN形式で返してくれるものになる。

### 補足
:::note warn
今回のソースコードは*YouTubeAPI*を使用していない理由としてはLIVE配信ではチャットを取得できるが、
アーカイブでは取得できないようなのだ。
:::
# ソースコード
さっそくだがソースコード
辞書型のデータを取得しやすくするためこちらのソースコードを貸していただいた。
ありがとうございます。

https://qiita.com/bstyle6130/items/6ceae33723bc2ba3cca3

```python:chat-downloader.py
from chat_downloader import ChatDownloader
from matplotlib import pyplot
import matplotlib.pyplot as plt


class FunctionUtils:

    # ネストデータにアクセスする関数
    @staticmethod
    def nested_item_value(parrent_object, nest_list):
        """ return nested data """

        if not nest_list: return parrent_object

        result = ""
        for nest_key in nest_list:
            object_type = type(parrent_object)
            if object_type is not dict and object_type is not list:
                result = None
                break
            elif object_type is list:
                if type(nest_key) is not int:
                    result = None
                    break
                result = parrent_object[nest_key] if nest_key < len(parrent_object) else None
            else:
                result = parrent_object.get(nest_key, None)

            if result is None:
                break

            parrent_object = result

        return result


def chat_count(lists):
    lists_count = []
    i = 0

    while i <= (max(lists)):
        if i in lists:
            lists_count.append(lists.count(i))
        else:
            lists_count.append(0)
        i += 1

    return lists_count


def main():
    fu = FunctionUtils()
    chat_time = []
    chat_member = []
    chat_mess = []

    def motion(event):
        x = event.xdata
        y = event.ydata
        try:
            ln_v.set_xdata(round(x))
        except TypeError:
            pass

        plt.draw()

    def onclick(event):
        print('event.xdata={}'.format(round(event.xdata)))
        print('message_count={}'.format(message_count[round(event.xdata)]))

    # URLからchatを読み込み
    # --------------------------------------------------------------------
    url = 'ここにYoutubeのURLを書き込む'
    start = 'ここに読み込みを開始する秒数を書き込む（0:00）'
    end = 'ここに読み込みを終了する秒数を書き込む（0:10）'
    chat = ChatDownloader().get_chat(url,
                                     start_time=start,
                                     end_time=end
                                     )

    # --------------------------------------------------------------------

    for message in chat:  # iterate over messages
        time_in_seconds = round(fu.nested_item_value(message, ["time_in_seconds"]))
        chat_mess.append(fu.nested_item_value(message, ["message"]))
        chat_time.append(time_in_seconds)

        if (fu.nested_item_value(message, ["author", "badges", 0, "title"])) is not None:
            chat_member.append(time_in_seconds)

    message_count = chat_count(chat_time)  # chat_count メソッドを呼び出す
    member_count = chat_count(chat_member)

    fig = plt.figure()

    c1, c2, c3, c4 = "blue", "green", "red", "black"

    pyplot.plot(member_count, "o-", picker=1, color=c3)
    pyplot.plot(message_count, "o-", picker=1, color=c1)

    ln_v = plt.axvline(0)

    plt.connect('motion_notify_event', motion)
    fig.canvas.mpl_connect('button_press_event', onclick)

    pyplot.show()


if __name__ == '__main__':
    main()

```

もし、このソースコードで直した方がいいと思われる箇所はコメント欄にてご指摘頂きたい。

# 導入
まずは、pip をインストール

```pip:pip
pip install chat-downloader
pip install matplotlib
```

その後に上記のソースコードをコピペした後、この部分を変更を行う。
最後まで読み込みたい場合は**end_time**を削除すれば最後まで読み込んでくれる
しかし、start_timeは（0:00）で設定しておいたほうがいい（それを前提にその他のプログラムを組んでいるので、、）

```python:change.py
    # URLからchatを読み込み
    # --------------------------------------------------------------------
    url = 'ここにYoutubeのURLを書き込む'
    start = 'ここに読み込みを開始する秒数を書き込む（0:00）'
    end = 'ここに読み込みを終了する秒数を書き込む（0:10）'
    chat = ChatDownloader().get_chat(url,
                                     start_time=start,
                                     end_time=end
                                     )

    # --------------------------------------------------------------------
```
# 参考結果
参考結果として最近良く見る**白上フブキ**のチャットを取得したいと思う。
秒数にして0:00~0:10秒間にする



https://www.youtube.com/watch?v=uttlxwdMYIk

### グラフの結果
赤色はチャンネルのメンバーのチャット数である

![スクリーンショット (137).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653601/dd0663b1-9f2f-6a7b-0355-27ba54f4f895.png)

# まとめ
今回はchat-downloaderでchatをダウンロードしてmatplotlibにグラフを描画できた。
これを元に切り抜き動画を作るのもいいかもしれません。