オンライン会議で消えれるようにしてみた
こんにちは!noteでフロントエンドエンジニアやってます。iemongです。
個人的に、今年はNext.jsのApp Routerの開発を結構やってきて、そろそろ手に馴染んできたかなぁという一年でした。
さて、そんな話は置いておいて、例年通りアドベントカレンダードリブン開発で作ったものを発表したいと思います。
※この記事はnote株式会社 Advent Calendar 2023の18日目の記事です。
今回は、オンライン会議で使える石ころぼうしを作ることにしました。
石ころぼうしとはドラえもんのひみつ道具の1つで、被ると誰にも気づかれなくなる機能を持った道具です。
今回は「気づかれなくなる」 = 「画面から消える」と仮定して、「石ころぼうしを被ってる間は、被った人がZoomから消える」ようにしてみたいと思います。
作る
まず、帽子を調達しました。Amazonで石ころぼうしに近いものを探して購入しました。
次に、Webアプリを作ります。以下の4つの機能を作ることにしました。
カメラ入力機能
バーチャル背景機能
スクリーンショット機能
帽子を被ってるか判定する機能
手に馴染んだNext.jsのApp Routerを使って作ります。
カメラ入力はMediaDevicesのgetUserMediaからアクセスできます。ChatGPTに適当にサンプルコードを生成してもらって手直しして完了しました。
バーチャル背景機能は、真面目にやるとクロマキー合成や機械学習のモデルを使う方法があると思うのですが、今回はskywayが提供している skyway-video-processors というライブラリを使用してみました。バーチャル背景の精度はmeetやzoomより流石に劣りますが、5行くらいで実装できるのでプロトタイピングには非常にいいライブラリだと思いました。
スクリーンショットを撮る機能も、ChatGPTに適当に生成してもらってちょっと手直ししました。カメラの映像を映してるvideo要素を、canvasに書き込んで画像にしています。帽子を被ってるか判定する機能のために512pxの正方形でクロップするようにしました。
最後に、帽子を被ってるか判定する機能を作ります。これが機能のコアかつ1番難しいところでした。初めは帽子にセンサー縫い付けようと思ってたんですが、被らなくてもできてしまうハックに気づき断念しました。
代わりに、Open AIのVisionを使うことにしました。
VisionとはGPT-4を使って画像を理解できるAPIです。リクエストにbase64化した画像とプロンプトを渡すことで、プロンプトに対する回答がレスポンス
として帰ってきます。
https://platform.openai.com/docs/guides/vision
今回は帽子を被ってるかどうかだけを知りたかったので、「If you see someone wearing a gray hat in the picture, return it as true. Otherwise, return false.」というプロンプトにしました。レスポンスの結果が「True.」「True」など表記がブレることがあったので、文字列にtrueを含んでいるかどうかで判定しました。
コードは以下になります。
# TypeScript
"use server";
import OpenAI from "openai";
import { env } from "@/env/server.mjs";
export async function analyzeImageIfWearRockCap(base64String: string) {
const openai = new OpenAI({
apiKey: env.OPENAI_API_KEY,
});
const res = await openai.chat.completions.create({
model: "gpt-4-vision-preview",
messages: [
{
role: "user",
content: [
{
type: "text",
text: "If you see someone wearing a gray hat in the picture, return it as true. Otherwise, return false.",
},
{
type: "image_url",
image_url: {
url: base64String,
detail: "low",
},
},
],
},
],
});
const result = res.choices[0];
const message = result.message.content?.toLowerCase() ?? "false";
return message.includes("true");
}
この判定機能を適当なインターバルで動かして、カメラに写ってる人物が帽子を被ってるかどうかを判定するようにし、被ってる場合はバーチャル背景の画像で画面を覆い、被ってない場合はそのまま表示されるようにしました。機能をまとめると以下のようになります。
このWebアプリをOBSで表示して、仮想カメラとして起動すれば、Zoomなどのオンライン会議ツールで使えるようになります。
使う
ぼうしを被っているの検出すると、消えているのが分かると思います。
まとめ
以上、アドベントカレンダードリブン開発でバーチャル石ころぼうしを作ってみた話でした。チームが変わってオンラインミーティングの頻度が減ったしまいましたが、「このミーティングから消えたい。。」ってなった時には積極的に使っていこうと思います。
注) 今のところ出くわしたことは無いです。
また、がっつりChatGPTと会話しながらゼロから作ったんですが、半日くらいで完成したのでこれは今後の開発体験が変わるなぁ〜と思いました。
最後まで読んでいただきありがとうございました。
▼noteエンジニアアドベントカレンダーはこちら
▼さらにnoteの技術記事が読みたい方はこちら
付録
コードの全容が見たい方はこちらをご確認ください。