0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

エンジニア2年目がAIで動画編集アプリを開発し、自動E2Eテストして公開するまで

0
Posted at

01. はじめに

エンジニアとして2年目を迎えました。

普段はJavaやKotlinを使い、Androidアプリの開発を担当しています。

最近、私が参画しているプロジェクトでもAI活用が進んでおり、評価軸に「AIの活用度」が含まれるなど、仕事の進め方が大きく変わってきているのを感じます。

ただ、実際に業務でAIを使おうとすると、セキュリティや権限の都合で、使えるツールや入力できる情報に制限があります。

「もっと自由に使ってみたいけど、業務ではなかなか難しい……」

そんなもどかしさがありました。

そこで、

プライベートの開発なら、制限を気にせず好きなだけAIを使えるのでは?

と思い、個人開発で試してみることにしました。

今回挑戦したのは、ブラウザ上で動く動画編集サイトの設計、実装、テスト、公開です。

自分でコードを一から書くのではなく、AIとの対話を中心に進めた場合、どこまで実際に使えるものを作れるのかを検証しました。

⚠️ 本記事のスコープについて

この記事では、IDEへのAIプラグイン導入や、MCPサーバーの構築といったAI開発環境そのものについては扱いません。

基本的には、AIに質問したり、要件や修正内容を伝えてコードを書いてもらったりする、シンプルな対話形式で開発を進めています。

「AIに指示を出しながら、どこまで設計・実装・テスト・公開を進められるのか」を試した記録です。

02. やりたいこと

今回作ろうと思ったのは、簡単に動画を編集できるWebサイトです。
制作物:https://capca-web.pages.dev/

将来的には、Web版をもとにFlutterでAndroid・iOSアプリも作りたいと考えています。

動画編集ソフトはいろいろありますが、個人的には少し学習コストが高いと感じていました。

例えば、動画にテロップを入れて、不要な部分をトリミングして、効果音を追加する。

やりたいことはそれだけでも、動画編集ソフトの操作を覚えたり、プロジェクトを作成したり、書き出し設定を確認したりと、それなりに時間がかかります。

もっと簡単に、

  • 動画を読み込む
  • 必要な部分だけ切り取る
  • テロップや効果音を追加する
  • MP4で保存する

という流れだけで使えるツールが欲しいと思いました。

なければ、自分で作ってしまおうという魂胆です。

また、動画をサーバーへアップロードする形式ではなく、できるだけブラウザ内で処理を完結させることも目標にしました。

個人の動画や、外部へアップロードしたくない動画を扱う場合にも使いやすくしたかったためです。

さらに、テストの自動化はやってみたいと思っていました。
普段の開発では、テスト駆動かつ手作業でテストをしているので、その工程を省くことが本当に可能なのか、興味がありました。

使用したAIは以下になります。

ChatGPT
要件整理
実装方針の相談
実装方針の相談
不具合の原因調査
修正内容やテスト観点の整理
Codex
コードの実装・修正
Playwrightを使ったE2Eテストの作成と実行
テスト結果をもとにした不具合調査

03. 設計よりも先に、とりあえず作らせてみる

本来であれば、最初に要件を整理して、画面設計や技術選定を行うべきだと思います。

ただ、今回はAIを活用した開発の検証です。

正直なところ、

細かい設計をするのは面倒なので、ざっくり指示を出したら作ってくれないかな

という気持ちがありました。

そこで、まずはAIに開発中のルールを伝えました。

これからの会話では以下を遵守すること

・指示通りに動作すること
・実装は仕様通りに実施すること
・ユニットテストを実施すること
・保守、エンハンスがあることを前提とした実装をすること
・優秀なエンジニア兼プランナーであること
・プラン通りに実施していくこと

今見ると、かなり抽象的な指示です。

「優秀なエンジニア兼プランナーであること」と書けば、本当に優秀な設計になるのかは怪しいところですが、この時点ではとりあえず投げてみました。

続いて、作りたいアプリの概要とロードマップを伝えました。

Web、Android、iOSで利用できる動画編集アプリを作成したい。

以下の流れで開発を進める。

1. Web版のプロトタイプを作成する
2. Web版を公開する
3. Web版をもとにFlutterでAndroid・iOSアプリを開発する
4. Android・iOSアプリを公開する

まずはWeb版のプロトタイプを作成してほしい。
不足している仕様は補い、適切な動画編集サイトとすること。

必要な機能は以下。

・編集用キャンバスの作成
・動画の読み込み
・動画のトリミング
・動画の拡大、縮小、移動
・テロップの追加
・BGM、効果音の追加
・動画と音声の音量調整
・動画の上下、左右反転
・編集した動画のMP4書き出し

かなりざっくりしています。

画面構成や使用するライブラリ、データの持ち方などは、ほとんど指定していません。

この状態でAIがどの程度補完してくれるのか確認するため、最初はあえて細かく決めずにプロトタイプを作らせました。

04. とりあえず、それっぽいものはできた

最初に作られたのは、HTML、CSS、JavaScriptで動くWebアプリでした。

その後、機能追加と修正を繰り返し、最終的には次のような機能を実装しました。

  • 動画ファイルの読み込み
  • キャンバスサイズの変更
  • 動画のトリミング
  • 動画の移動、拡大、縮小
  • 複数テロップの追加
  • 文字色、縁色、縁幅の変更
  • BGM、効果音の追加
  • 動画と音声の音量調整
  • 動画の上下、左右反転
  • 編集内容のUndo
  • MP4形式での書き出し

動画の書き出しには、ブラウザ上でFFmpegを動かせるffmpeg.wasmを利用しています。

サイト名はcapcaとしました。

ここまで書くと、AIに指示を出したら順調に完成したように見えるかもしれません。

もちろん、そんなことはありませんでした。

05. 当然、一発では動かなかった

最初のプロトタイプを動かしてみると、いろいろな問題が発生しました。

  • 動画が読み込めない
  • JavaScriptで未定義関数のエラーが出る
  • テロップを追加してもキャンバスに表示されない
  • テロップのドラッグが途中で止まる
  • 動画を書き出しても再生できない
  • 音量調整を入れると、書き出した動画の音が消える
  • プロジェクトを読み込んでも編集内容が反映されない
  • ローカルでは動くが、公開環境ではFFmpegが初期化できない

特に困ったのが、修正を依頼した箇所とは別の機能が壊れることでした。

一つの不具合を直すためにAIへコードを修正させたところ、以前は動いていた機能が動かなくなることがあります。

AIは指示した部分のコードを書くことは得意ですが、プロジェクト全体の意図や、これまでの経緯を常に完全に理解しているわけではなさそうです。

「直った」と回答されても、実際に動かすと直っていないこともありました。

このあたりから、単に「修正して」と依頼するだけでは厳しいと感じ始めました。

06. AIに任せるために、ルールを増やした

開発を続ける中で、AIへの依頼方法も少しずつ変わりました。

最終的には、次のようなルールを明示するようにしました。

・修正意図が明確な場合のみ実装すること
・意図が不明な場合は、勝手に仕様を変更しないこと
・既存機能への影響を確認すること
・修正後は必ず動作確認を実施すること
・修正後のファイル一式をまとめて渡すこと
・ZIPを作成した場合は、展開できることを確認すること
・必要ファイルがそろっていることを確認すること
・index.htmlからアプリを起動できることを確認すること
・実装した修正箇所が動作することを確認すること

最初の「優秀なエンジニアであること」より、こちらの方がはるかに効果がありました。

AIにとっても完了条件が具体的な方が動きやすいようです。

また、エラーを伝えるときも、エラーメッセージだけを貼るのではなく、次の情報をセットで伝えるようにしました。

発生環境:
Cloudflare Pages Preview

実際の結果:
FFmpeg Workerの初期化に失敗する

期待する結果:
動画を読み込んだ後、MP4を書き出せる

確認済み事項:
ローカル環境では動作する

変更条件:
既存の編集機能は変更しない

テスト条件:
動画読み込みからMP4再生確認まで実施する

AIを使う上では、プロンプトのうまさというより、問題を整理して完了条件を言語化する力が重要だと感じました。

07. ローカルで動いても、公開すると動かない

Web版は、GitHubとCloudflare Pagesを連携して公開しました。

GitHubへPushするとCloudflare Pagesへ自動デプロイされる構成です。

しかし、ローカルでは動いていた動画書き出しが、Cloudflare Pages上では動きませんでした。

原因を追っていくと、ffmpeg.wasm周辺には複数の要素が関係していました。

  • Web Workerの読み込み元
  • FFmpeg Core JavaScriptのオリジン
  • WASMファイルの配信元
  • MIME Type
  • Content Security Policy
  • ライブラリのバージョン差

最終的には、次の構成へ整理しました。

  • @ffmpeg/ffmpeg0.12.15に固定
  • @ffmpeg/core0.12.10に固定
  • FFmpeg Core JavaScriptを同一オリジンから配信
  • WASMファイルは固定バージョンのjsDelivrから取得
  • CSPのscript-src'wasm-unsafe-eval'を追加
  • WASMがapplication/wasmで配信されることを確認

このあたりは、Android開発だけをしていた自分にはあまり馴染みがない分野でした。

AIへ質問しながら、Worker、CSP、MIME Type、同一オリジンといった概念を一つずつ確認していきました。

AIがなければ、エラー文を見た時点でかなり長い間止まっていたと思います。

一方で、AIが出した修正案をそのまま適用しても直らないことがありました。

最終的には、ブラウザのConsole、Network、配信されたレスポンスヘッダーを確認しながら、原因を切り分ける必要がありました。

08. 「ユニットテストをして」だけでは足りなかった

最初のプロンプトでは「ユニットテストを実施すること」と書いていました。

ただ、今回の動画編集サイトでは、ユニットテストだけでは確認できない部分が多くあります。

例えば、次のようなケースです。

  • 実際にブラウザから動画を読み込めるか
  • FFmpeg Workerが公開環境で初期化できるか
  • WASMファイルが正しいMIME Typeで取得できるか
  • MP4を書き出せるか
  • ブラウザからファイルをダウンロードできるか
  • ダウンロードしたMP4を再生できるか

ボタンを押したときに関数が呼ばれることを確認するだけでは、動画編集サイトとして動いているとは言えません。

そこで、ブラウザを実際に操作するE2Eテストを追加しました。

09. CodexにPlaywrightを使ったE2Eテストを実行させる

今回のE2EテストにはPlaywrightを使用しました。

ここは少し紛らわしいのですが、Playwright自体がAIというわけではありません。

  • Playwright:ブラウザ操作を自動化するためのテストフレームワーク
  • Codex:テストコードの作成や実行を依頼したAI

という関係です。

CodexへCloudflare PagesのPreview URLとテスト動画を渡し、次の内容を確認するよう依頼しました。

capcaのCloudflare PreviewをE2Eテストしてください。

確認内容:
1. 動画読込
2. FFmpeg Worker初期化
3. MP4書き出し
4. MP4ダウンロード
5. ダウンロードしたMP4の再生確認
6. Consoleエラー確認

テスト成功まではmasterへマージしないでください。

テストでは、おおまかに次の流れを自動化しています。

Preview URLへアクセス
    ↓
テスト動画を選択
    ↓
動画が読み込まれることを確認
    ↓
FFmpeg Workerの初期化を待つ
    ↓
MP4書き出しを実行
    ↓
ダウンロードイベントを取得
    ↓
出力されたMP4を保存
    ↓
MP4が再生可能であることを確認
    ↓
Console、Page、Networkエラーを確認

動画の書き出しには時間がかかるため、単純に数秒待つのではなく、画面状態やダウンロードイベントを基準に待機します。

例えばPlaywrightでは、次のようにファイルを選択できます。

const videoPath = path.resolve("tests/assets/sample.mp4");

await page
  .locator('input[type="file"]')
  .setInputFiles(videoPath);

ダウンロードもイベントとして待機できます。

const downloadPromise = page.waitForEvent("download", {
  timeout: 120_000,
});

await page.getByRole("button", {
  name: "MP4を書き出す",
}).click();

const download = await downloadPromise;
await download.saveAs("test-results/output.mp4");

さらに、ファイルが存在するだけではなく、ブラウザから動画として読み込めることも確認します。

書き出し完了のメッセージが出ても、生成されたMP4が壊れている可能性があるためです。

10. 実際のE2Eテスト結果

最終的なテスト結果は次の通りでした。

結果:成功
テスト:1 passed
実行時間:約1.4分

CSP:
script-src 'self' 'wasm-unsafe-eval' を確認

FFmpeg WASM MIME:
application/wasm

Console error:なし
Page error:なし

Network error:
Blob動画URLへのGETが net::ERR_ABORTED 1件

Network上ではBlob動画URLに対するnet::ERR_ABORTEDが1件ありましたが、確認した結果、今回問題としていたCSP、MIME、WebAssembly、FFmpeg Worker関連のエラーには該当しないと判断しました。

また、書き出されたMP4を実際にダウンロードし、再生できることまで確認しました。

これにより、少なくとも次の一連の処理は公開環境上で動作していると確認できました。

  • 動画を読み込む
  • FFmpegを初期化する
  • MP4を書き出す
  • ファイルをダウンロードする
  • 出力したMP4を再生する

手動で一度確認するだけでは、次の修正で再び壊れる可能性があります。

E2Eテストとして残しておけば、同じ操作を繰り返し確認できます。

11. Previewでテストしてから本番へ反映する

公開フローは、次のようにしました。

修正ブランチを作成
    ↓
GitHubへPush
    ↓
Cloudflare PagesがPreview環境を作成
    ↓
Preview URLに対してE2Eテスト
    ↓
動画読み込み、書き出し、再生を確認
    ↓
問題がなければmasterへマージ
    ↓
本番環境へ反映

ローカルでテストしてから本番へ反映するだけでは、Cloudflare Pages固有のCSPや配信設定の問題を見逃す可能性があります。

そのため、本番に近いPreview環境をテスト対象にしたことは大きかったです。

今後は、Pull Request作成時にPreview URLを取得し、自動でE2Eテストを実行するところまでつなげたいと考えています。

12. AIが全部やってくれたのか

ここまで読むと、AIに指示を出せば、設計から公開まで全部自動で終わったように見えるかもしれません。

ですが、そんなに簡単ではありませんでした。

コードを書く作業の多くはAIに任せましたが、次の作業は自分で判断する必要がありました。

  • 何を作るか決める
  • 必要な機能を整理する
  • AIへ渡す条件を決める
  • 実際に動かして不具合を見つける
  • エラーの発生条件を整理する
  • AIの修正内容が正しいか確認する
  • 既存機能が壊れていないか確認する
  • どこまで確認できたら完了とするか決める
  • 本番へ反映してよいか判断する

また、AIが生成したコードには、次のような問題もありました。

  • 存在しない関数を呼び出す
  • 異なるバージョンのAPIを混ぜる
  • 修正対象ではない機能まで変更する
  • ローカル環境だけで動く構成を提案する
  • 「対応しました」と回答するが、実際には動かない

AIは非常に便利ですが、出力されたコードをそのまま信用することはできません。

むしろAIで実装速度が上がるほど、レビューとテストの重要性も上がると感じました。

AIに実装を任せることと、AIに判断を任せることは別物でした。

実装速度はAIで上げられますが、仕様、品質、完了条件の判断は開発者側で担保する必要がありました。

13. 2年目エンジニアとして感じたこと

今回の個人開発では、普段のAndroid開発だけでは触れる機会が少ない分野も経験できました。

  • Webフロントエンド
  • 動画、音声処理
  • WebAssembly
  • Web Worker
  • Content Security Policy
  • MIME Type
  • GitHubによるソース管理
  • Cloudflare Pagesへのデプロイ
  • Preview環境での検証
  • PlaywrightによるE2Eテスト

最初からこれらをすべて勉強してから作ろうとしていたら、途中で止まっていたと思います。

わからないことが出たタイミングでAIへ質問し、必要な部分を調べながら進められたことで、完成まで持っていくことができました。

一方で、AIを活用することで、エンジニアとして考えなくてよくなるわけではありませんでした。

むしろ、次の力がより重要になったと感じます。

  • 要件を具体化する力
  • 問題を切り分ける力
  • 変更の影響範囲を考える力
  • 生成されたコードをレビューする力
  • テスト観点を洗い出す力
  • 完了条件を定義する力

特に今回、最初は「ユニットテストをして」とだけ書いていたものが、最終的には「公開環境で動画を読み込み、書き出したMP4を再生できるところまで確認する」という条件に変わりました。

テストの種類を知っているだけでなく、何を確認しなければ品質を担保できないか考えることが重要でした。

14. 現在地と今後やりたいこと

Web版はCloudflare Pagesへ公開しました。

ただし、公開しただけでは誰にも見つけてもらえません。

今後は、開発だけでなく次のような部分にも取り組む予定です。

  • Cloudflare Web Analyticsによるアクセス計測
  • Google Search Consoleへの登録
  • 使い方ページ、FAQの作成
  • 「動画をアップロードせずに編集できる」という特徴の明確化
  • QiitaやSNSでの発信
  • GitHub ActionsとE2Eテストの連携
  • 複数ブラウザでのテスト
  • FlutterによるAndroid・iOSアプリ開発

最初は、Webサイトを作ることだけを考えていました。

実際に公開してみると、テスト、保守、アクセス解析、利用者への説明、広報など、コード以外にもやることが多いと気づきました。

このあたりも含めて、個人開発の面白さだと思います。

15. まとめ

AIを活用し、ブラウザ上で動く動画編集サイトを設計、実装、テストし、Cloudflare Pagesへ公開しました。

最初はかなり雑なプロンプトから始めましたが、開発を続ける中で、AIへ伝える条件やテスト方法を少しずつ具体化していきました。

特に印象に残ったのは、AIを使えばテストが不要になるのではなく、AIを使うからこそテストが必要になるということです。

今回、Playwrightを使って次の一連の操作をE2Eテストとして自動化しました。

  • 動画の読み込み
  • FFmpeg Workerの初期化
  • MP4の書き出し
  • MP4のダウンロード
  • ダウンロードしたMP4の再生確認
  • Console、Page、Networkエラーの確認

AIは、未経験分野へ挑戦するハードルを大きく下げてくれました。

ただし、AIが作ったものを実際に使える状態へ持っていくには、人間側が仕様を決め、結果を疑い、テストし、完了を判断する必要があります。

エンジニア2年目でも、AIをうまく使うことで、普段の業務だけでは経験しづらい設計、実装、テスト、公開まで一通り経験できました。

まだ改善したい部分は多いですが、まずは実際に公開できるところまで進められたことを一つの成果として、今後も開発を続けていきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?