ダウンロード動画でアニメーションが反映されない件(仮説メモ)
Download Video ボタン実行で生成される WebM がチカチカするだけで、チャットの出現アニメーションが再現されない- プレビューの
Play では想定どおりのフェード&スライド表示になるが、録画結果ではメッセージが静止状態のまま - 同じフレームが繰り返し記録されているように見える(メッセージが一瞬だけ写る/真っ白になる)
apps/web/content/2025-12-03/message-mockup.html を file:// で直接開き、Download Video を押下- デフォルトの初期メッセージ 2 件でも発生
- html2canvas のレンダリング遅延
- 1フレームごとに
html2canvas を実行しており、DOM 変更→描画→待ち時間 30ms のループがリアルタイムに追いついていない - canvas.captureStream(0) で 0fps に設定しているため、
requestFrame() を呼んでもレンダリング完了前の古いフレームが拾われている可能性
- フレームの時間管理ずれ
await sleep(30) で待機しているが、html2canvas の非同期処理時間(>100ms)が無視され、結果的に 1 コマを複数回 push → チカチカhold 区間で同じ canvas インスタンスを複数 push しており、後続で canvas が再利用されると同一フレームが上書きされるリスク
- DOM スナップショットが中途半端
- newElement に opacity/transform を設定した直後にキャプチャしており、レイアウトが安定する前に描画が始まっている
- scale:2 指定により描画時間がさらに増大
- MediaRecorder 設定のミスマッチ
- stream.framerate=0(デフォルト)だと動画時間の計算がズレ、再生側でのフレーム間隔が不均一になる可能性
- 手元の WebM 録画でもメッセージ出現が反映されずチカチカする症状が再現し、上記「フレーム重複/タイミングずれ」仮説と一致。
- html2canvas 1 回のみ実行し、既存 canvas のピクセルを
ctx.putImageData で複製 → フレーム配列に入れてもチカチカするか確認 canvas.captureStream(30) に固定し、各フレーム描画後に await new Promise(r => requestAnimationFrame(r)) を挟んで MediaRecorder に一定周期で渡すscale:1 に下げて計測(描画時間短縮効果が大きいか)file:// ではなく npx serve apps/web/content/2025-12-03 などローカル HTTP で開き、Worker/CORS 由来の遅延がないか比較
- html2canvas をフレーム毎に回さない
- 初回のみ DOM→canvas にレンダリングし、以降は Canvas 上でトランジションを直接描く(テキスト配置を自前実装)
- 労力は高いが最も安定した動画出力が期待できる
- フレーム生成と録画を分離
- 全フレームを ImageBitmap/Blob でプリレンダ→
VideoEncoder (WebCodecs) または gifenc で連結 - MediaRecorder 依存を外すことでフレーム間隔を完全制御
- アニメーションを CSS + requestAnimationFrame に寄せる
- DOM 側で実際にアニメーションを走らせ、
captureStream(30) でリアルタイム録画(スクリプトはプレイヤー用と録画用で共用) - タイムライン管理を CSS トランジション開始時刻ではなく rAF で司る
- 解像度とエンコーディングを下げる暫定策
scale:1・videoBitsPerSecond を 2〜3Mbps に落としてまず滑らかさを確保
html2canvas 1 回あたりの実測時間(Performance.now で計測)- 出力 WebM のフレーム数・再生時間(ffprobe 等)
- 端末/ブラウザ別の再現性(Chrome/Edge/Firefox)
apps/web/content/2025-12-03/message-mockup.htmlapps/web/content/2025-12-03/message-mockup.jsapps/web/content/2025-12-03/message-mockup.css