プロフィール

arismmn timeline blog

← ブログ一覧に戻る

つぶやきにYouTube埋め込み再生機能を実装した

機能実装AstroセキュリティUI/UX

概要

つぶやき(タイムライン上のノート)のテキストにYouTube URLが含まれていた場合、埋め込み再生プレーヤーを自動で表示する機能を追加した。管理画面(投稿画面)ではテキスト入力中にリアルタイムでプレビューが表示される。

背景と目的

これまで、つぶやきにYouTubeのURLを貼り付けても、単なるテキストとして表示されるだけだった。閲覧者がYouTubeの動画を視聴するには、URLをコピーしてブラウザで開く必要があった。

この機能により、つぶやきの中にYouTube動画を直接埋め込み、その場で再生できるようになった。

実装内容

対応するYouTube URLの形式

以下の形式のURLを自動検出する:

  • https://www.youtube.com/watch?v=VIDEO_ID
  • https://youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • https://www.youtube.com/embed/VIDEO_ID
  • https://www.youtube.com/shorts/VIDEO_ID

変更したファイル

公開ページ側(src/components/TimelineItem.astro):

  • extractYouTubeVideoIds() 関数を追加し、テキストからビデオIDを抽出する
  • ビデオIDが見つかった場合、つぶやきの枠下にiframeで埋め込みプレーヤーを表示する
  • レスポンシブ対応のため、padding-bottom: 56.25%(16:9比率)のCSSテクニックを使用する

管理画面側(src/pages/admin/timeline/index.astro):

  • テキストエリアのinputイベントでYouTube URLをリアルタイム検出する
  • 検出されたURLの埋め込みプレビューを投稿フォーム内に表示する
  • 投稿完了時にプレビューをクリアする

セキュリティ対策

  1. ビデオIDの厳密な検証: ビデオIDは英数字・ハイフン・アンダースコアのみの11文字に制限し、不正な文字列の注入を防止する
  2. プライバシー保護モード: youtube-nocookie.comを使用し、YouTubeのトラッキングCookieが設定されないようにする
  3. DOM操作の安全性: 管理画面のプレビュー生成ではinnerHTMLを使用せず、document.createElement()でDOM要素を生成する

sandbox属性に関する知見

初期実装ではiframesandbox="allow-scripts allow-same-origin allow-presentation"を設定していた。しかしYouTubeプレーヤーはこの制限下では「エラー153 動画プレーヤーの設定エラー」となり正常に動作しなかった。YouTube埋め込みはクロスオリジンであるため、ブラウザの同一オリジンポリシーにより既に隔離されている。youtube-nocookie.comによるプライバシー保護と、ビデオIDの厳密な検証の2層で安全性を確保する方針に変更した。

技術的な補足

レスポンシブな動画埋め込み

iframeを直接配置すると、画面幅が変わったときにアスペクト比が崩れる。これを防ぐため、親要素にpadding-bottom: 56.25%を指定し、iframeposition: absoluteで配置するテクニックを使用した。56.25%9 ÷ 16 × 100で算出される16:9のアスペクト比である。

重複の排除

同じ動画URLがテキスト内に複数回記述されていた場合、Setを使って重複を排除し、1つの埋め込みプレーヤーのみを表示する。

Claude Code
Powered by
Claude Code
(使用モデル Claude Opus 4.6)
← ブログ一覧に戻る