連載ストックリスト:Android版「見開きPDFビューア」開発記録
この記事は、ChatGPTと壁打ちしながら、Android Studio内のGeminiの会話履歴、ChatGPTの会話履歴、Gitの変更履歴・ソースコード、保存した成果物を調べて作成しました。
第7回では、Geminiでユーティリティの操作動画を試作し、必要な操作が映らないまま試行を終えました。本稿では、10月28日にWorkモードへ引き継ぎ、動画5本を完成・公開し、その実装を次の撮影に使う教材にまとめるまでを振り返ります。
Workモードで5本を完成させ、YouTubeで公開する
10月28日14時36分頃、ChatGPTからWorkモードへ作業を引き継ぎました。対象はユーティリティで、既存スクリプトを参照し、実際のUIを調べ、scripts/build_shorts.pyを実装して全5本を生成する依頼です。
元のChatGPT会話「ショーツ動画生成実装」では、筆者の入力として次の実行指示が記録されています。Workモードへの引き継ぎにも、この指示が含まれていました。
筆者のプロンプト(抜粋)
python3 scripts/build_shorts.py --scene all を実行し、
./shorts_output/ にナレーション・テロップ付きの完成版MP4
(scene_01_final.mp4 〜 scene_05_final.mp4)を出力してください。
この引用は実際の指示の実行部分を抜き出して改行したものです。最初の引き継ぎに含まれた対象フォルダの取り違えも、実行時にはユーティリティへ訂正されています。
Workモードは実画面のUI階層から操作対象を特定し、撮影した操作区間の時刻を編集に利用しました。英語ナレーションとテロップを付け、14時56分に5本の生成を報告しています。
Workモードの最初の完成報告(抜粋):
全5本を生成しました。英語ナレーション・テロップ付きで、再生検査も成功しています。
報告を受け取った後も、内容の確認は必要でした。まず、概ね意図どおりにできていた例を示します。
図1:Work版では一覧から見開き表示への切替が確認できた
図1は、Scene 1の完成動画の1.0秒と10.0秒です。8ページの一覧から、表紙を単独で置き、次の2・3ページを対にした右綴じの見開き表示へ変わっています。これはこの場面の確認例で、5本すべてが初回から正しかったという意味ではありません。
撮影の途中では、保存が成功したように見えてもPDFが0バイトになる問題も見つかりました。読み込み用と保存用の処理が同じPDF処理インスタンスを使うようアプリを修正し、8ページの実体のあるPDFを保存できたことまで確認しています。保存画面が出たことと、保存が完了したことは別でした。
Scene 3は、私の指摘で再撮影した
最初にできた動画は概ね意図どおりでしたが、Scene 3には分割の実演が映っていませんでした。15時16分、私は次のように依頼しました。
筆者のプロンプト(全文)
Scene 3について、サンプルPDFには分割を試せるページがありません。シナリオを修正して、再撮影してください。
指定していたサンプルの対象ページは、分割を実演するための内容ではありませんでした。1枚の表紙を選んでおり、左右2ページ分を含む見開き原稿を分ける様子を見せられません。事前に、分割を実演できるデータを用意するべきでした。
初回版のコード(6b1321d)も確認すると、Split Pagesを開いて画面を保存した後、Androidの「戻る」を送っていました。Runを押して分割する処理ではありません。字幕やナレーションが分割を紹介していても、実際の分割は実行されていませんでした(図2)。
図2:分割用データの準備不足と、初回版で分割が実行されなかった流れ
ここでの準備不足は、機能を分かりやすく実演するための入力データの選び方です。この動画だけでアプリの分割機能が動かないと結論付けるものではありません。私はシナリオの修正と再撮影を依頼しました。これを受けて、Workモードは分割の紹介を外す構成を選び、撮り直しました。
15時18分のWorkモードの回答(抜粋):
分割の紹介を削除し、Scene 3を再撮影しました。
「回転 → 白紙挿入・見開き確認 → 挿入した白紙の削除」の20秒構成です。ナレーション・テロップも修正し、再生検査済みです。
再撮影後の5本は、次の内容になりました。
| 動画 | 内容 | 長さ |
|---|---|---|
| Scene 1 | 一覧から見開き表示へ切替 | 15秒 |
| Scene 2 | PDFの読み込みと編集メニュー | 15秒 |
| Scene 3 | 回転・白紙挿入・削除(再撮影版) | 20秒 |
| Scene 4 | 表示切替とツールバー設定 | 15秒 |
| Scene 5 | 保存先の操作とPDF生成 | 17秒 |
YouTube登録情報の作成と、アップロードの担当は別だった
15時20分、私はWorkモードへYouTubeへのアップロード準備を依頼しました。その後、Geminiにまとめてもらった登録情報と依頼文を渡しています。
筆者のプロンプト(全文)
Geminiから、登録に必要な情報をまとめてもらいました。参考にしてください。
筆者の記憶では、登録資料をまとめたのはAndroid Studio内のGeminiです。Workモードの履歴には、私がGeminiから受け取った資料を渡した記録があります。確認したAndroid Studioの履歴からは、同じ資料を生成したやり取りを特定できませんでした。
チャンネル作成と動画5本の非公開アップロードは、私の承認後にWorkモードが実行しました。当時の記録では、17時24分に非公開アップロード完了、18時04分に動画の公開完了、18時32分に再生リストの公開完了が報告されています。
後からAndroid StudioのGeminiへupload_report_ja.txtを渡し、チュートリアルのボタンを公開動画へ結び付けました。Geminiの履歴にYouTubeの動画IDが残っているのは、このアプリ側の対応も含むためです。
図3に、登録資料の作成、筆者による引き継ぎ、Workモードでの公開、アプリ側の対応という役割分担を示します。
図3:YouTube登録情報の引き継ぎと、アップロード・公開・アプリ連携の担当
| 担当 | 今回確認できた作業 |
|---|---|
| Android StudioのGemini | 撮影の初期実装と修正、後にCodex修正のコミット、アプリ内の動画リンク設定 |
| Gemini(利用画面は未確定) | YouTube登録用情報と作業依頼文の作成 |
| ChatGPTのWorkモード | 成功した撮影・編集処理の実装と実行、保存不具合修正、再撮影、アップロードと公開設定 |
| 私 | 成果物への修正指示、チャンネル作成・アップロード・公開の承認と依頼 |
完成動画5本は、Workモードの出力、プロジェクト内の保存ファイル、アップロード一覧に記録されたSHA-256がすべて一致しました。Scene 3も修正版の記録です。公開した1本目を含む5本の登録記録を確認しています。これは当時の公開記録と保存ファイルの照合であり、今回YouTube上の全動画を改めて視聴したという意味ではありません。
完成した後で、成功した実装を教材にする
比較調査を始めたのは、動画を完成・公開した後の10月28日夜です。Geminiに正常に動作する撮影スクリプトの作り方を教える目的で、失敗中の実装と成功した実装を比較しました。
操作動画はユーティリティのGemini版とWorkモード版、補助資料としてストア掲載用スクリーンショットはビューアのGemini版とCodex版を確認しました。静止画の撮影・検品・登録の経緯は第5回補足で扱います。ここからは、動画制作後の比較で整理した、次の依頼に使う確認条件を紹介します。図4〜10は、確認できた問題と改善方針を論点別に示したもので、図の順に対策を実装・実行した記録ではありません。
このユーティリティの作業では、完成した実装を比較して教材をまとめましたが、教材を使ってGeminiに再撮影を依頼するリトライは行っていません。次のビューアでは、作業フォルダに教材を置き、参照するよう指示していました。その実際のプロンプトと回答は、第9回で紹介します。
最初に教えること:成功を具体的に定義する
調査して分かったのは、次の状態だけでは撮影成功といえないことです。
-
スクリプトが最後まで動いた
-
テストが成功した
-
画像や動画ファイルが生成された
必要なのは、要求された画面や操作結果が、成果物に正しく映っていることです。
例えば、保存ボタンを押して保存先ダイアログが開いただけでは、PDFの保存は終わっていません。検索処理を呼んだだけでは、検索結果が表示されたとは限りません。
ユーティリティでの撮影結果を比較すると、手順の詳しさに加え、必要な操作と結果が映ったかを確かめる条件が重要でした。
次にGeminiへ依頼するときは、コードを書く前に、シーンごとの成功条件も記述してもらいたいと考えました。
図4に、処理の完了と、操作説明動画としての成功条件の違いを示します。
図4:スクリプトの完走・ファイル生成と、必要な操作・結果が動画に映ることの違い
| シーン | 成功条件の例 |
|---|---|
| PDF表示 | 指定したPDFの対象ページが描画されている |
| 検索 | 指定ページに検索結果があり、強調表示が見える |
| 削除 | 確認ダイアログが閉じ、ページ数が減っている |
| 保存 | 保存先の操作が完了し、今回の出力PDFが存在する |
静止画と操作動画では、必要な処理が違う
当初は、Gemini版がアプリ内部の処理を直接呼び出していることに注目しました。
動画用テストでは、ページの選択や回転、空白ページの挿入をViewModelへ直接指示していました。これでは結果が変わっても、利用者が行うタップやメニュー操作を説明できません。
ただし、内部APIの利用を一律に禁止するのも適切ではありません。
正常動作したCodexのスクリーンショット撮影テストも、目的の状態を準備するために内部APIを使っていました。
Geminiには、撮影前の準備処理と、撮影して見せたい操作を区別するよう伝えます。
操作説明動画でUI操作に失敗したとき、内部APIで結果だけ作って先へ進めると、動画としての目的を満たせなくなります。
図5に、静止画での状態準備と、操作動画で見せるUI操作の違いを示します。
図5:静止画の状態準備に使う内部APIと、操作動画で省略できないUI操作
「待った」ではなく「完了した」を確認する
スクリーンショット用の旧テストには、ページ移動や検索の後に、PDFの読み込み元が存在することを待つ処理がありました。
しかし、その条件はPDFを開いた時点で成立しています。検索が終わる前でも先へ進めます。
次は待機条件の違いを示す疑似コードです。旧コードの条件そのものではなく、「PDFが開いている」という、操作前から成立し得る状態に単純化しています。
# この条件は、操作前から成立しているかもしれない
search(query)
wait_until(lambda: document_is_open())
capture()
検索を撮影したいなら、待つ条件も検索結果に対応させます。
search(query)
wait_until(
lambda: query_matches()
and target_page_has_results()
and highlight_is_rendered(),
timeout=30,
)
capture()
成功したCodex版では、対象ページの検索ヒットや描画更新、ハイライトを確認していました。
固定の待ち時間は、操作結果を視聴者に見せるための滞在時間には使えます。しかし、処理完了を保証する条件は別に必要です。待機期限までに成立しなければ、撮影へ進まず、画面やログを残して失敗として扱います。
図6に、経過時間や操作前から成立する条件だけで進む場合と、今回の検索結果・描画・ハイライトの完了を待つ場合の違いを示します。
図6:固定時間・既存状態での待機と、検索結果・描画の完了を確認する待機
入力を検証しても、別のファイルを使っていた
スクリーンショットの旧実装では、ホスト側がPDFを端末へ転送し、存在を確認していました。
ところが、Android側のテストが読むのは、テストAPKに組み込んだ別のPDFでした。
これでは、転送したファイルを確認しても、撮影に使う入力が正しい証拠になりません。
成功したCodex版は、転送したPDFとテストが読むPDFをハッシュで照合していました。図7に、旧実装でPDFが食い違っていた経路と、Codex版で照合した対象を示します。
図7:端末に転送したPDFと、撮影テストが実際に読むPDFの照合
Geminiへの指示では、次のように具体化します。
依頼文の例
入力ファイルの存在確認だけで終わらず、アプリが実際に読むファイルと一致していることを確認してください。
同様に、アプリIDも実際の設定から調べる必要があります。旧スクリプトには、画像回収先のアプリIDの大文字・小文字が、実際のapplicationIdと異なる箇所がありました。
Kotlinのpackage名を、そのままAndroidのアプリIDとして使えるとは限りません。
失敗を無視すると、間違った画面を保存できてしまう
旧スクリーンショットテストには、設定画面を開く処理の失敗を無視して、そのまま撮影する構造がありました。
これでは、設定画面が開いていなくても「設定画面」という名前の画像を保存できます。
第7回の削除操作でも見たように、内部データが変わっても、確認ボタンが担当する画面の後始末まで完了するとは限りません。UI操作の失敗を内部処理で代用する前に、何を成果物へ映すのかを決める必要があります。
Geminiには、操作失敗時の方針も教える必要があります。
-
必要なUIが見つからなければ停止する
-
その時点の画面、UIツリー、ログを保存する
-
別の処理で結果だけ作って成功扱いにしない
-
再試行する場合は状態を戻し、回数を制限する
図8に、失敗を無視して撮影を続けた場合と、その場で止めて証拠を残す場合の違いを示します。失敗した場所を特定できれば、次にどこを直すべきかが分かります。
図8:失敗を無視して保存する旧実装と、停止して証拠を残す方針
動画編集には、実際の操作時刻を使う
第7回で見た固定カット・固定字幕の問題から、撮影と編集をつなぐ時刻の記録が必要だと分かりました。
起動や読み込みの所要時間が変わっても、見せたい操作の前後を選べるようにするためです。
成功したWorkモード版は、操作イベントの実測時刻を記録し、その区間を使って編集していました。図9に、固定時刻で編集する場合と、実際の操作時刻に合わせる場合の違いを示します。
図9:固定時刻でずれた編集と、操作ログを使った編集の比較
Geminiには、録画だけでなく、次の記録も要求します。
操作開始時刻
操作結果を確認した時刻
次の操作へ移った時刻
録画と操作ログの時間基準
生動画は残し、編集結果は別ファイルにします。完成動画では、操作前後、編集区間の境界、最後の操作結果まで確認します。
検証スクリプトにも合格基準が必要
第7回のフレーム検証は、画像の読み込み・明るさといった確認に留まっていました。次の依頼では、画像の内容や操作結果にも対応した合格条件が必要です。
画像が読めることと、目的の画面が撮れていることは別です。
図10では、旧実装の検証範囲と、ファイル・アプリの結果・成果物の内容を順に確かめる方針を比べます。各段階で確認する項目は、下の表にまとめました。
図10:画像の読み込みで終わる検証と、3段階の合格基準
| 段階 | 検証内容 |
|---|---|
| ファイル | 存在、形式、破損、寸法、映像・音声の長さ |
| アプリの結果 | ページ数、検索結果、保存PDF、ダイアログ終了 |
| 成果物の内容 | 目的の画面、操作の見やすさ、字幕と音声の対応 |
既存スクリーンショットでは、保存画像と検品記録のハッシュを照合しました。これは記録とファイルの整合性の確認で、今回すべての画面を目視検品したという意味ではありません。撮影セットの拡大と版の対応は第5回補足で扱います。
Geminiの報告でも、何を自動確認し、何を目視確認したのかを分けてもらいます。
次の依頼に使うための整理案
ここまでの比較を、次の撮影依頼に使える形へまとめます。以下は、10月28日の比較調査に、30日の追加確認とビューアで分かった課題を加えた提案文です。28日夜に実際に渡した教材とは区別してください。このまま実行して成功を確認したプロンプトではありません。実際のやり取りと具体的な失敗例は、第9回・第10回で扱います。
Androidアプリの撮影スクリプトを作成してください。
まず、実際のソースからapplicationId、Activity、Runner、
使用PDF、UI要素、対象端末、言語、向きを調べてください。
実装前に、各シーンについて次を記述してください。
・初期状態
・操作
・操作後の期待状態
・撮影する範囲
・成果物の合格条件
最初は1端末・1言語・1シーンで動作を確認してください。
初期状態の画像確認、1操作の前後確認、短い生録画、編集済み動画の順に進め、
前段が不合格なら次の工程へ進まないでください。
開始状態は毎回確認し、アプリを起動すれば表紙に戻るなどと仮定しないでください。
操作後は、その操作固有の結果を期限付きで待ってください。
固定sleepや、操作前から成立する条件だけで先へ進めないでください。
静止画の準備には内部APIを使って構いませんが、
目的の画面の描画完了を確認してください。
操作説明動画では、説明対象の操作を実際のUIで行ってください。
確認ダイアログや保存先の操作も完了してください。
操作に失敗した場合は、画面・UIツリー・ログを保存して停止してください。
内部APIで迂回して成功扱いにしないでください。
入力ファイルと実際に使うファイルの一致を確認し、
今回の実行と成果物を識別できる記録を残してください。
動画は実測した操作時刻を編集に使い、生動画を保持してください。
完成画像・動画を開き、要求内容が映っていることを確認してください。
検証レポートでは「期待する内容」と「実際に観測した内容」を分けてください。
観測内容と合否を、固定の成功文で埋めないでください。
合否を導く条件と、証拠画像・UIツリー・状態の参照を示してください。
ページ変更はハッシュ差だけで判断せず、ページ番号や本文の変化を確認してください。
画像内容を確認できるツールが使えない場合は、未確認と報告してください。
検証コード自身にも、無条件の合格判定がないかレビューしてください。
最後に、実行条件、確認した成果物、検証結果、
未確認事項を報告してください。
実行していないものを動作確認済みと書かないでください。
次は、ビューアでの試行と中止判断へ
今回は、Geminiでの撮影がうまくいかなかったユーティリティで、Workモードを使って動画5本を完成・公開し、その実装を比較材料にしました。既存ログや動画の確認、私からの修正指示も含む結果であり、モデル名だけで成否が決まったと結論付けるものではありません。
10月28日夜には、この比較をもとにした教材をビューアの作業フォルダに置き、Geminiに参照を指示しました。第9回では、同日夜の計画から、29日のGeminiによる撮影の試行を紹介します。
図版の出典と引用の扱い
図1はWork版Scene 1、図2は再撮影前のWork版Scene 3の保存動画からフレームを抽出しました。時刻は各動画内の値です。図1では、2枚とも画面の上部を同じ縮尺で切り出して並べました。
図2の左・中央は初回動画の画面を切り出し、右には保存コード(6b1321d)に基づく操作の流れを示しました。
画面内の作品はThe Try-It Club / Episode 1、作者はKomairo Hiyoriです。©2026 Komairo Hiyori。CC BY 4.0に基づき表示し、図ではフレーム抽出・縮小・比較配置を行いました。
図3は資料と作業の受け渡し、図4〜10は比較結果と改善方針を整理した模式図です。実画面を再現したものではありません。図3の公開時刻は当時の完了報告に基づき、登録資料を生成したGeminiの利用画面は未特定です。
プロンプトと回答は、当時のユーザー入力と表示された回答に基づき、全文・抜粋を各箇所に明記しています。後半の「次の依頼に使うための整理案」は後日の提案文であり、当時の実行済みプロンプトと区別しています。
関連する記事
関連:第5回補足「スクリーンショットを撮って、ストアに届けるまで」