📚

Claude Code × SharePointで授業動画を自動要約してレポート化する

に公開

はじめに(事前の免責事項)

この記事は 自分のアカウントで正規にアクセスできるコンテンツに対して、ローカルで自動化を試みた話 です。

  • 対象は 自分の大学が正規に自分に配布した授業動画 で、自分の端末・自分のChromeで普通に視聴できる範囲 の操作です
  • 動画ファイルの ダウンロードやアップロードはしていません。ブラウザ上で再生中のフレームをローカルに保存し、手元で解析しています
  • 記事中のスクリーンショットや板書内容は 本記事には一切含めていません(個人が特定される情報・著作物の転載は避けています)
  • 所属組織のポリシー動画の利用規約 を必ず確認してください。自動化ツールでのアクセスや二次利用を禁止している組織もあります
  • 本記事はあくまで 個人環境でのローカル自動化の一例 であり、他者のアカウントや組織のセキュリティ境界を越える行為を推奨するものではありません

何を作ったか

授業の予習動画(自分のアカウントで視聴できるSharePoint動画)を、自分の端末のChromeで開き、
そのフレームをローカル保存してAIで要約、Wordの予習レポートにまとめる仕組みをClaude Codeで作りました。

自分のChromeで視聴中の動画 → [ローカル処理] → 予習レポート.docx(数式付き)

この記事は、同じ構成を自分で組めるように 手順と試行錯誤をまとめた備忘録です。


なぜ作ったか

予習授業では、授業前に動画を見て予習レポートを書いて提出します。
毎回これが地味に時間を食う。動画見て、要点まとめて、Wordに数式書いて…で軽く1時間。

自分の手元で自分が視聴できるコンテンツなら、手作業を自動化してもよいはず
そこでClaude Codeを使って、普段ブラウザでやっている作業を手元で自動化することにしました。


最初に考えたこと:Claudeはリンクから動画を「読めない」

「ClaudeにSharePointの動画URLを渡せば中身が分かるのでは?」と最初思いましたが、無理でした

理由はシンプルで、Claude自体は私のMicrosoftアカウントにログインしていない から。
Claude のサーバーから匿名でアクセスしても、ログイン画面にリダイレクトされて中身は取れません。

これはSharePointに限らず、認証が必要なすべてのサイトで同じです。
これはZen向けには設計として妥当で、AIが勝手に他人の認証壁を越えられない方が安全です。

じゃあどうするか:「自分のブラウザ」で視聴中のものを対象にする

私のPCのChromeは、私自身が普段使っている状態で、私のログインcookieを持っています。
Claudeに代わってブラウザを「自動操作」させるのではなく、自分のブラウザに任意秒へのシーク+フレームキャプチャを指示する仕組み を組むのが素直です。

これはE2EテストやWebスクレイピングのブラウザ自動化と同じ発想で、手作業で普段やっていることをローカルで再現する だけです。


ブラウザ操作で遠回りした話(学びが多かった部分)

最初は「マウスで再生ボタン押して、キーボードでスキップ」で済ませようとして、詰まりました。

❌ 失敗1: 画面をスクショする

VSCodeでPython動かしてたので、VSCodeが映り込む。Chromeが裏にあると動画が撮れない。

❌ 失敗2: Chromeを強制的に前面化

Windowsの「フォーカスの盗み防止」に阻まれる。VSCodeが出力を受け取るたびに前面に戻ってくるので、数秒ごとに主導権が行ったり来たり

❌ 失敗3: キーボードで10秒スキップ

SharePoint Streamは Alt + → で +10秒スキップ。Pythonからキーを送ると…
Chrome本体の「進む」ショートカットに奪われる。動画は動かない。

❌ 失敗4: 再生バーを座標クリック

再生バーは数ピクセル幅しかなく、コントロールはマウス動かすと一瞬で隠れる
座標計算が信用できない。

このあたりで、「UIを外から叩く方法は信頼性が低い」と割り切りました。


正解:Chromeの開発者向け機能(DevTools Protocol)を使う

Chromeには開発者ツール(F12)が内部で使っている DevTools Protocol (CDP) という仕組みがあります。
これは 自分のChromeの開発者機能を自分のPythonから叩くだけ で、ブラウザ内部のWeb API(document.querySelector など)を呼び出せます。

chrome.exe --remote-debugging-port=9222

これで起動すると、

document.querySelector('video').currentTime = 600;  // 10分位置に飛ぶ

といった普通のWeb API呼び出しを外部から送れるようになります。
要するに 自分のChromeのDevToolsコンソールで自分で打つのを自動化するだけ
UIクリックのような不安定な操作は一切介さず、ブラウザ内部のAPIをそのまま呼びます。

CDPを使うときのセキュリティ配慮

CDPを有効にしたChromeは、ローカル上の任意プロセスから接続可能 になります。
公開サーバーで使う機能ではなく、使う時だけ起動し、使い終わったら閉じる のが基本です。

私が採った対策:

  • ローカルループバックのみで動作させる(ポート9222は外部から絶対に届かない設定)
  • 一時プロファイル (--user-data-dir=<一時フォルダ>) で起動し、普段使いのChromeとは分離
  • 初回のMicrosoft認証は手動で1回だけ(その後はこの一時プロファイルの cookie で動く)
  • 使い終わったらChromeプロセスを終了(タスクマネージャで確認)
  • この一時プロファイルは 他の用途で使わない--user-data-dir に他の用途を混ぜない

また、--remote-allow-origins フラグは、何でも許可する * ではなく 必要最小の origin(例: http://localhost:9222)に絞ると安全度が上がります。

絶対にやらないこと:

  • CDPポートをルーターでポート開放する、LAN内他PCから繋がる状態にする
  • 普段使いのChromeプロファイル(--user-data-dir に default 指定)でCDPを有効化する
  • cookie や Local State を他の場所にコピーする(App-Bound Encryption で元々できないようになっていますが、そういった回避は試みない方針)

動画の10分割キャプチャ

CDPで使えるようになった操作:

  1. 動画を任意の秒数にジャンプ (currentTime = 600)
  2. 動画ウィンドウの現在フレームをローカルのPNGとして取得 (Page.captureScreenshot)

これを組み合わせて、動画を10分割して各区間の中央でフレーム保存します。
保存先は自分のローカルの一時フォルダのみ。外部送信はしません。

ポイントは play() → seek → pause() の順。先に再生しないと静止画(サムネイル)のままでフレームが更新されない落とし穴があります。


AIで板書内容を構造化(Claude Code の並列Agent)

保存したフレームをClaude Codeに渡して、板書に書かれた定理番号・例題の構造 を抽出してもらいます。
30枚(3動画×10枚)をまとめて送って、Claude Codeの Agent機能で並列処理

このとき、AIに渡す情報AIに渡さない情報 を意識しました:

  • ✅ 渡すもの: フレーム画像(手元で保存したPNG)
  • ❌ 渡さないもの: 動画URL、アカウント識別子、個人情報

また、各自の組織で認識されているポリシー に従うべきです:

  • 学生本人・職員本人が作成した自分向けのメモであれば、多くの場合は個人利用の範囲
  • 動画そのもの(元ファイル)を外部サービスに送るのはやめる
  • 組織の データガバナンス規定 が外部AI利用を制限している場合は従う

Word組版:数式をちゃんと描画(OMML)

レポートはWord形式。行列や分数を文字列じゃなく本物の数式として描画したい。

Wordの数式機能はOMMLというXML形式で表現されます。
python-docxに直接サポートが無いので、XMLを組み立てるヘルパーを書きました。

# 行列式 |a b; c d|
m_det([[m_ri('a'), m_ri('b')],
       [m_ri('c'), m_ri('d')]])

これでWordで開いた時に数式として正しく表示されます。


最終的な仕組み

Claude Codeの「スキル」としてパッケージ化しました。

~/.claude/skills/preview-report/
├── SKILL.md         ← Claudeへの指示書
├── smoke_test.py    ← 動作確認(3秒で17項目チェック)
├── preview.py       ← コマンドライン入口
├── chrome_cdp.py    ← Chrome起動・終了
├── cdp_seek.py      ← 動画シーク・キャプチャ
├── omml_lib.py      ← 数式ヘルパー
└── report_gen.py    ← Word組版

話しかけるだけでOK:

ユーザー: 予習レポートを作成してください
         <自分が視聴できる動画のURL>

Claude: [スキル起動]
        動作確認 → Chrome起動 → 10分割キャプチャ
        → 並列Agent解析 → Word生成 → 自動で開く

全体の流れ

ユーザー: 動画URL [1〜N個]


[1] 一時プロファイルでChrome起動(初回のみ認証)


[2] 各動画を10分割してフレームを手元に保存


[3] 並列エージェントで板書を構造化


[4] 解析結果から Word を組版(数式はOMMLで本物)


[5] Wordが自動で開く


[6] Chromeプロセス終了・一時プロファイルを閉じる

所要時間の内訳:

  • Chrome起動+認証: 10秒(初回のみ)
  • キャプチャ: 90秒(3動画×10枚)
  • 並列解析: 60秒
  • Word生成: 5秒
  • 合計: 3分弱

再現の手順

前提

  • Windows 11(macOS/Linuxでも大枠は同じ)
  • Python 3.11以上
  • Chrome 110以上
  • 自分のアカウントで正規にアクセスできるコンテンツを対象とする
  • 所属組織のポリシー・利用規約を確認済みである

1. ライブラリ

pip install python-docx websocket-client requests numpy pillow

2. 一時プロファイルでChromeを起動

"C:\Program Files\Google\Chrome\Application\chrome.exe" ^
  --remote-debugging-port=9222 ^
  --remote-allow-origins=http://localhost:9222 ^
  --autoplay-policy=no-user-gesture-required ^
  --user-data-dir="%TEMP%\chrome_cdp_profile" ^
  --no-first-run ^
  "<対象のURL>"

初回はログイン画面が出るので普通に認証。この一時プロファイルは自動化以外では使わないこと

3. PythonからCDPに接続(ローカル限定)

import requests, websocket, json

# ローカルループバックのみに接続
tabs = requests.get("http://localhost:9222/json").json()
tab = [t for t in tabs if t['type'] == 'page'][0]
ws = websocket.create_connection(tab['webSocketDebuggerUrl'])

ws.send(json.dumps({
    "id": 1, "method": "Runtime.evaluate",
    "params": {"expression": "document.title"}
}))
print(ws.recv())

4. 使い終わったらプロセス終了

taskkill /IM chrome.exe /F

必ずプロセスを終了してCDPポートを閉じる。


この仕組みが使える他の場面

同様に 「自分の権限で普段ブラウザでやっている作業」の自動化 に応用できます:

  • 自分のメールに来るレポートから要約を作る
  • 自分が管理者の社内ポータルの一覧を取得する
  • 自分のGoogleドライブの自分のファイルを整理する

いずれも 他者のアカウント・他者のデータを狙うものではない 点が重要です。
自分の手作業を時短するローカル自動化として使うと、だいぶ日常が楽になります。


得られた学び

技術的な話

  • UIを外から叩くのは脆い。Webアプリは内部API(JavaScript)のほうが安定
  • Chromeの普通のプロファイルではCDPは意図的に使えない設計(セキュリティ上妥当)
  • 専用プロファイルを一時的に立てるのが正解、cookieの不正コピーはしない
  • 動画は play()seekpause() の順でないとフレームが更新されない
  • 背景タブは描画停止されるので Page.bringToFront が必須

セキュリティ面

  • CDPポートはローカルループバックのみで運用、外部に絶対に開けない
  • --remote-allow-origins* ではなく必要最小のオリジンに絞る
  • 専用の一時プロファイルを使い、他の用途と混ぜない
  • 使用後はChromeプロセスを終了してポートを閉じる
  • AIに渡すのはローカル保存したフレーム画像のみ、元動画ファイルは送らない
  • 組織のデータガバナンス・利用規約を確認してから実装する

Claude Code特有

  • Agentツールの並列起動で解析時間が激減
  • スキルの description にトリガーキーワードを書くと自然発話で起動する
  • smoke_test.py を常備して毎回の動作確認を自動化
  • skill-memoryに「今回の気づき」を残すと次回以降の精度が上がる

まとめ

自分の権限で普段ブラウザでやっている作業は、自分のブラウザに指示を出すローカル自動化 で代替できます。
Claude Codeの並列処理と組み合わせれば、予習レポート作成のような
「地味に時間を食うタスク」が3分で終わるようになります。

ただし、

  • 対象は自分のアカウントで正規にアクセスできるコンテンツに限定する
  • 所属組織のポリシー・利用規約を確認する
  • CDPポートは使うときだけ・ローカル限定で、使い終わったら閉じる
  • 元ファイルや認証情報を外部サービスに送らない
  • 個人情報・組織特定情報を記事等で公開しない

の5点は、使う前に自分で確認してから取り組むのが前提です。

同じような「自分の手作業を時短したい」と思っている方の参考になれば嬉しいです。


この記事は実装から執筆までClaude Codeと対話しながら書きました。

Discussion