👻

【Rails】 YouTube の URL を 埋め込み用に変換するクラス

2021/02/21に公開

YouTube の URL は複数種類存在します。

  1. 視聴用 URL
    • https://www.youtube.com/watch?v=動画ID
    • https://www.youtube.com/watch?v=動画ID&t=120 (時間指定付き)
  2. 共有用 URL
    • https://youtu.be/動画ID
  3. 埋め込み用 URL
    • https://www.youtube.com/embed/動画ID

Webサイトで動画を表示するための iframe タグの src 属性に埋め込む際は, 「埋め込み用のURL」を使用しなければならない。

そこで,「視聴用URL」「共有用URL」,そして「埋め込み用の iframe タグ」のどれであっても「埋め込み用のURL」に変換するクラスを作成してみました。

lib/autoloads/youtube_url_formatter.rb
class YoutubeUrlFormatter
  # iframe タグの src 属性のURLを取得するための正規表現
  SRC_REGEX = /src\s*=\s*"([^"]*)"/
  # URL から 動画ID を取得するための正規表現(時刻指定は除去)
  YOUTUBE_ID_REGEX = %r{\A(?:http(?:s)?://)?(?:www\.)?(?:m\.)?(?:youtu\.be/|youtube\.com/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)/))([^?&"'>]+)(&t=.*)?\z}

  def self.format(url)
    # YouTube の埋め込み用 iframe である場合は src 属性のURLに置き換える
    src_match = SRC_REGEX.match(url)
    url = src_match[1] if src_match
    # YouTube の動画である場合は 埋め込み用URL を戻り値とする
    # そうでない場合は nil を返す
    youtube_id_match = YOUTUBE_ID_REGEX.match(url)
    if youtube_id_match
      "https://www.youtube.com/embed/#{youtube_id_match[1]}"
    end
  end
end

例えば,モデル側で次のようなものを用意すれば自動で変換して保存できます。

  before_save do
    format_url = YoutubeUrlFormatter.format(url)
    if format_url.present?
      self.url = format_url
    else
      self.errors.add(:url, "YouTubeのURL以外は無効です")
    end
  end

Discussion