配信のコメントは、流れてしまうと読み返せない
こんばんは。辛子屋 芥子と申します。
配信のコメントは、流れてしまいます。読んでいる間は楽しいのですが、終わってから「あの話をもう一度読みたい」と思っても、たいていは残っていません。スクロールを遡って探すこともできますが、目で追うのは骨が折れます。読んでいる最中は追えても、あとから拾い直すのは、思っているより難しいものです。
特に困るのが、同じ方が続けて書いてくださった分です。一つのお話を、三つ四つに分けて書いてくださる方がいます。「こんばんは」で始まって、「音が良いですね」と続いて、「前は少し割れていました」で終わる。その三つが、間に他の方のコメントを挟みながら、別々に流れていきます。あとから拾い集めようとすると、一つ目と三つ目の間に何が入っていたかを、目で確かめながら遡ることになります。
わたくしが思っていたのは、それだけでした。同じ方が書いてくださった分を、あとからまとめて読みたい。一つのまとまりとして、順番どおりに並んでいてほしい。
先に、自分のことを書いておきます。わたくしは配信をしていません。V として名乗ってはいますが、配信の予定は未定でして……。ですので、この記事は「配信で使ってみたらこうでした」という話ではありません。手元で道具を試した記録です。そこは最初に区切っておきます。
今回試すもの:GitHub Copilot SDK を、コメント整理の場面に当てる
試すのは GitHub Copilot SDK です。GitHub 社(GitHub, Inc.)が提供している、Copilot の機能を自分の書いたプログラムから呼び出すための道具です。くわしい説明と、いま使える範囲は、GitHub の公式サイトと公式ドキュメントにあります。名前も対応も変わりやすいので、試す前にそちらを見てください。この記事から先に進む時は、公式の説明を正としてください。
使う場面は、配信のコメントを整理するところです。もう少し細く言うと、同じ方が続けて書いた分を一つのまとまりにして、そのまとまりに短い見出しを付けてもらう。ここまでです。コメント全体の要約や、話の流れの分析までは広げません。広げると、どこまで試したのかが分からなくなるからです。
この記事で試す範囲を、先に並べておきます。
- 手元にあるコメントのテキストを、スクリプトから読める形にする
- 同じ方が続けて書いた分を、一つのまとまりにまとめる
- そのまとまりを、SDK に渡す文の形に組み立てる
- SDK を呼んで、まとまりごとに見出しを付けてもらう
4 番は、今回動かせていません。3 番までは動きました。この区別は、最後まで崩さずに書きます。読む方にとっては、3 番までと 4 番の間が、いちばん知りたいところだと思います。そこを「試しました」と書いてしまうのは、いちばん避けたいことでした。
準備:コメントのテキストを、スクリプトから読める形にする
準備は、コメントのテキストを一つ用意するだけです。特別な道具は要りません。
まず、行の形を決めます。1行に1コメント。行の先頭に時刻、次に名前、そのあとに本文。区切りは角かっことコロンです。
[00:12:03] みかん: こんばんは
[00:12:10] みかん: 今日は音が良いですね
[00:12:22] みかん: 前は少し割れていました
形を決めてから書くのが楽でした。決めずに始めると、読む側のプログラムに例外が増えていきます。時刻の書き方が揃っていない行、名前に記号が付いている行、本文が長い行。一つひとつに手当てを足していくと、まとめる前に力を使い切ってしまいます。
次に、この形のテキストをファイルとして保存します。ふつうのテキストファイルです。保存したら、短いスクリプトから開いて読めることを確かめます。数行だけ読み込んで、中身をそのまま出すところまで確かめると安心です。ここまでで準備は終わりです。
実際の配信のコメントを扱う時は、書いてくださった方の名前が入ります。誰のものか、どこに置くか、いつまで残すか。触る前に決めておくのがよいと思います。ここを後回しにすると、あとから全部をたどり直すことになります。
書いたコード:同じ方が続けて書いた分を、まとめて並べる
書いたのは、次の短いスクリプトです。わたくしが書いたもので、他所から持ってきたものではありません。SDK を入れていない手元でも、そのまま動いて結果が出るようにしてあります。
"""
配信のコメントを、同じ方が続けて書いた分ごとにまとめて並べる。
GitHub Copilot SDK に渡す文も、このまとめた形から組み立てます。SDK を入れていない手元でも、そのまま動いて結果が出ます。使い方:python comment_blocks.py おまけのサンプルで動きますpython comment_blocks.py ファイル名 手元のテキストで動きます"""
import reimport sys
# 1行の形:[00:12:03] みかん: こんばんは
ONE_LINE = re.compile(r"^\[(\d{2}:\d{2}:\d{2})\]\s*([^::]+?)\s*[::]\s*(.*)$")
SAMPLE_COMMENTS = """[00:12:03] みかん: こんばんは[00:12:10] みかん: 今日は音が良いですね[00:12:22] みかん: 前は少し割れていました[00:12:35] たけのこ: わたくしも聞こえました[00:12:50] みかん: あ、たけのこさん、こんばんは[00:13:04] みかん: マイクを替えたんです[00:13:20] たけのこ: なるほど[00:13:31] みかん: 明日も同じ時間に配信します[00:13:45] かぼす: 待っています"""
RULE = "─" * 34
def read_comments(text):"""テキストを読み、時刻・名前・本文の組に分ける。"""comments = []for raw in text.splitlines():line = raw.strip()if not line:continuefound = ONE_LINE.match(line)if not found:continuetime, name, body = found.groups()comments.append((time, name.strip(), body.strip()))return comments
def group_by_speaker(comments):"""同じ方が続けて書いた分を、1つのかたまりにまとめる。"""blocks = []for time, name, body in comments:if blocks and blocks[-1]["name"] == name:blocks[-1]["lines"].append(body)blocks[-1]["end"] = timeelse:blocks.append({"name": name,"start": time,"end": time,"lines": [body],})return blocks
def build_prompt(blocks):"""GitHub Copilot SDK に渡す文。かたまりごとに見出しを付けてもらいます。"""lines = ["次の配信コメントを、かたまりごとに短い見出しを付けて整えてください。","",]for number, block in enumerate(blocks, 1):lines.append("かたまり%d:%s(%s 〜 %s)"% (number, block["name"], block["start"], block["end"]))for body in block["lines"]:lines.append(" " + body)lines.append("")return "\n".join(lines)
def main():if len(sys.argv) > 1:with open(sys.argv[1], encoding="utf-8") as handle:text = handle.read()else:text = SAMPLE_COMMENTS
comments = read_comments(text)blocks = group_by_speaker(comments)
print("まとめた配信コメント")print("読み込んだコメント:%d件" % len(comments))print("まとめたかたまり:%d件" % len(blocks))print()
for block in blocks:print(RULE)print("発言者:%s" % block["name"])print("発言した時刻:%s 〜 %s" % (block["start"], block["end"]))print("まとめた発言:%d件" % len(block["lines"]))for body in block["lines"]:print(" ・%s" % body)print(RULE)
if __name__ == "__main__":
main()
順に説明します。
ONE_LINE は、行の形を一つだけ決めた正規表現です。先頭の角かっこに時刻、次に名前、コロンのあとに本文。三つを括弧でくくってあるので、あとから取り出せます。名前のところは「コロン以外の文字」という書き方にしてあります。名前に使われる文字を一つずつ並べるより、短く済むからです。全角のコロンも受け取るようにしてあります。日本語のコメントでは、半角と全角が混ざるからです。
SAMPLE_COMMENTS は、動作を確かめるための見本です。記事のために書いた作りごとで、実際の配信のコメントではありません。9件入れてあります。名前は3人分です。
read_comments は、テキストを行ごとに分けて、ONE_LINE に合う行だけを拾います。拾えたら、時刻と名前と本文に分けて、組にして返します。空行は飛ばします。形に合わない行も、ここで飛ばします。飛ばしたことを記録していない点は、あとで書きます。
group_by_speaker が、この記事の中心です。前のまとまりと名前が同じなら、そのまとまりに本文を足し、終わりの時刻を更新します。名前が違ったら、新しいまとまりを始めます。比べているのは、直前のまとまりだけです。全体を見て同じ名前を探しているのではありません。ですので、途中に他の方が一言入ると、そこで切れます。切れ方については、あとで正直に書きます。
build_prompt は、SDK に渡す文を組み立てます。まとまりごとに、番号と名前と時刻を書き出して、その下に本文を並べます。最後に「かたまりごとに短い見出しを付けて整えてください」と頼む一文を置きます。見出しを付けるのは SDK 側で、まとめるのは手元のコード側です。この分担にしておくと、SDK を呼べない時でも、まとめた結果だけは手元で見られます。実際、今回わたくしが確かめられたのは、この分担の手前まででした。
main は、引数があればそのファイルを読み、無ければ見本を読みます。読み込んだ件数と、まとめたかたまりの数を出してから、まとまりごとに中身を並べます。件数を二つ出しているのは、取りこぼしに気づくためです。読み込んだ数と、まとめた数が食い違っていれば、どこかで落ちています。
動かした結果:うまくいったところ、いかなかったところ
動かした結果を、そのまま載せます。
まとめた配信コメント
読み込んだコメント:9件
まとめたかたまり:6件
──────────────────────────────────
発言者:みかん
発言した時刻:00:12:03 〜 00:12:22
まとめた発言:3件
・こんばんは
・今日は音が良いですね
・前は少し割れていました
──────────────────────────────────
発言者:たけのこ
発言した時刻:00:12:35 〜 00:12:35
まとめた発言:1件
・わたくしも聞こえました
──────────────────────────────────
発言者:みかん
発言した時刻:00:12:50 〜 00:13:04
まとめた発言:2件
・あ、たけのこさん、こんばんは
・マイクを替えたんです
──────────────────────────────────
発言者:たけのこ
発言した時刻:00:13:20 〜 00:13:20
まとめた発言:1件
・なるほど
──────────────────────────────────
発言者:みかん
発言した時刻:00:13:31 〜 00:13:31
まとめた発言:1件
・明日も同じ時間に配信します
──────────────────────────────────
発言者:かぼす
発言した時刻:00:13:45 〜 00:13:45
まとめた発言:1件
・待っています
──────────────────────────────────
うまくいったのは、まとめる部分です。9件のコメントが、6つのかたまりになりました。みかんさんの3件が一つにまとまり、間に入ったたけのこさんの発言で切れて、そのあとのみかんさんの2件がまた一つにまとまっています。「こんばんは」「今日は音が良いですね」「前は少し割れていました」が、順番どおりに並びました。思っていたとおりに動きました。
いかなかったところ、動かせなかったところも書きます。
SDK を呼ぶところは、動かしていません。 手元に SDK を入れて動かす準備がまだ済んでいないためです。ですので、見出しが実際にどう付くかは、この記事では何も書けません。試していないことを、試したように書くのはやめました。ここを読みたかった方には、物足りない記事だと思います。すみません。
同じ方の分が、いつも一つになるとは限りません。 上の結果で、たけのこさんの2件は別々のかたまりになっています。間にみかんさんの発言が入ったからです。たけのこさんの「わたくしも聞こえました」と「なるほど」は、同じ方が続けて書いたものですが、一つにはなりませんでした。狙ったのは「続けて書いた分をまとめる」ことでしたので、これは狙いどおりではあります。ただ、同じ方の言葉を一望したい時には、物足りない結果になります。
かたまりの切り方が、名前の変わり目で必ず切れます。 会話が続いていても、別の方が一言入れば切れます。切れること自体は悪くないのですが、「切れたところが話の切れ目」とは限りません。上の結果でも、みかんさんの最初の3件と次の2件は、話としてはつながっています。
名前の書き方が少し違うと、別の方になります。 同じ方が、名前の後ろに記号を付けたり外したりすると、二つに分かれてしまいます。ここは何もしていません。
形に合わない行は、黙って読み飛ばされます。 読み飛ばした件数は出していません。この見本ではたまたま読み飛ばしが無かっただけで、実際のコメントでは起きます。数えて出すべきでした。次の機会の宿題にします。
本文に区切りの記号が入っていると、そこで切れます。 本文に URL が入っていると、途中で切れてしまいます。ここも手当てが要ります。
使うならここに気をつける
読む方が自分の手元で試す時のために、気をつけたい点を挙げます。
- コメントは、書いてくださった方のものです。 保存する場所、残す期間、見せる範囲を、触る前に決めておく。ここを決めないまま始めると、あとで全部をたどり直すことになります。
- 名前のゆれを先に決める。 同じ方の表記をどう寄せるか。別の一覧を用意する、記号を落とす、など。今回わたくしは何もしていません。
- 切れ方の決め方を、一つに決めない。 名前の変わり目で切る、時間の間が空いたところで切る、話題で切る。作りによって読みやすさが変わります。
- 読み飛ばしを数えて出す。 合わなかった行を黙って捨てると、コメントが減っていることに気づけません。
- SDK に渡す文には、コメントの全文が入ります。 渡す範囲と、渡した先での扱いを、先に確かめてから。丸ごと渡す前に、一度確かめたほうがよいと思います。
- 見出しを付けた結果を、そのまま公開しない。 見出しが外れていることがあります。人が読んでから出してください。
おわりに
道具そのものの説明は、GitHub 社の公式サイトと公式ドキュメントにあります。この記事は、その道具をコメント整理という一場面に置いてみた記録です。載せたコードはわたくしが書いたもので、他所から持ってきたものではありません。
繰り返しますが、SDK を呼ぶところは、まだ動かせていません。動かせたら、続きを書きます。
配信のコメントは、流れて消えていきます。読むのは一瞬で、残るのは少しだけです。同じ方の言葉が三つ並んで残るだけで、あとから読むのが随分らくになります。そのくらいの手伝いなら、わたくしにもできそうです。


コメント