Sausage Erectos X ブラウザ内動画生成——Canvas録画とSNS最適化
ブラウザ内動画生成──Canvas録画からSNS投稿までの技術
Sausage Erectosのカスタマイザーでは、ユーザーが自分のフィギュアを回転させた動画を生成し、直接SNSにシェアできる。この機能の技術的な裏側を解説する。
Canvas.captureStream() の仕組み
ブラウザのCanvas要素から動画ストリームを取得する方法として、captureStream()APIを使用している。
const canvas = document.getElementById('three-canvas');
const stream = canvas.captureStream(30); // 30fps でキャプチャ
このAPIはCanvasの描画内容をリアルタイムでMediaStreamに変換する。Three.jsのレンダリングループが回っている間、フレームが自動的にキャプチャされる。
引数のフレームレートは「最大フレームレート」であり、Canvasの描画が追いつかない場合はフレームがドロップされる。安定した動画を得るためには、レンダリングパフォーマンスの確保が前提条件になる。
MediaRecorder APIの使い方
キャプチャしたストリームを動画ファイルに変換するのがMediaRecorder APIだ。
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm;codecs=vp9',
videoBitsPerSecond: 5000000, // 5Mbps
});
const chunks = [];
recorder.ondataavailable = (e) => {
if (e.data.size > 0) chunks.push(e.data);
};
recorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
// ダウンロードリンクを生成
};
recorder.start();
setTimeout(() => recorder.stop(), 5000); // 5秒間録画
フレームレート制御──30fps vs 60fps
フレームレートの選択は、品質とファイルサイズのトレードオフだ。
30fps: ファイルサイズ小、SNS投稿に十分な品質
推定ファイルサイズ: 5秒で約3MB(5Mbps時)
60fps: 滑らかな動き、ファイルサイズ大
推定ファイルサイズ: 5秒で約5MB(5Mbps時)
SNS投稿用途では30fpsで十分だ。60fpsは、スローモーション編集を前提とする場合にのみ推奨している。
エンコード形式──WebM vs MP4
ブラウザのMediaRecorder APIが標準でサポートするのはWebM形式(VP8/VP9コーデック)だ。しかし、多くのSNSプラットフォームはMP4(H.264)を推奨している。
// ブラウザのサポートを確認
const types = [
'video/webm;codecs=vp9',
'video/webm;codecs=vp8',
'video/mp4;codecs=h264', // Safariのみサポート
];
const supported = types.filter(t => MediaRecorder.isTypeSupported(t));
Chrome/FirefoxではWebMを生成し、必要に応じてFFmpeg.wasm(ブラウザ内で動作するFFmpeg)でMP4に変換する戦略を取っている。SafariはネイティブでMP4をサポートする。
SNS別の最適動画サイズ
各SNSプラットフォームで最適な動画サイズが異なる:
Instagram投稿: 1080×1080(正方形) 最大60秒
Instagramリール: 1080×1920(9:16縦長)最大90秒
TikTok: 1080×1920(9:16縦長)最大10分
X(Twitter): 1280×720(16:9横長) 最大140秒
YouTube Shorts: 1080×1920(9:16縦長)最大60秒
カスタマイザーでは、録画開始前にプラットフォームを選択すると、自動的にCanvas のアスペクト比とリサイズが調整される仕組みにしている。
録画中のUI非表示テクニック
動画にUI要素(ボタン、スライダーなど)が映り込まないようにする必要がある。
function startRecording() {
// UIを非表示
document.querySelector('.controls').style.display = 'none';
document.querySelector('.panel').style.display = 'none';
// カメラの自動回転を開始
autoRotate = true;
// 次のフレームから録画開始(UI非表示が反映されてから)
requestAnimationFrame(() => {
recorder.start();
});
}
ポイントはrequestAnimationFrameで1フレーム待つことだ。display: noneの反映とCanvasの再描画が完了してから録画を開始しないと、最初のフレームにUIが映り込む。
録画中は、カメラを自動回転させてフィギュアの全方位を見せる「ターンテーブル」モードを提供している。回転速度は5秒で1周がデフォルトだ。
動画は静止画の100倍の情報量を持つ。ブラウザ内でその情報量を生成できることは、Web技術の驚異的な進歩の証だ。