🎥
入力されたURLを元に、動画を自動で埋め込む方法
背景
生配信のURLをFormに入力した際に、自動で動画が埋め込まれるようにする必要があり、実装方法を検討しました。
今回は Twitch, Youtube, niconico に対応しました。
概要
入力されたURLを正規表現でうまく切り貼りして<iframe>
に入れます。
<iframe>
についてはこちら。
各動画コンテンツの埋め込み仕様
Twitch
- 公式document: https://dev.twitch.tv/docs/embed/video-and-clips/
-
<iframe src="https://player.twitch.tv/?channel=jornojovanni&autoplay=false"></iframe>
- 備考: 動画の自動再生がデフォルトでONになっているので、URL末尾に
&autoplay=false
をつける必要がある
Youtube
- 公式document: https://developers.google.com/youtube/player_parameters?hl=ja
-
<iframe src="https://www.youtube.com/embed/ANwf8AE3_d0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
- 埋め込みに必要なURL: https://www.youtube.com/embed/ANwf8AE3_d0
- ref https://stackoverflow.com/questions/3452546/how-do-i-get-the-youtube-video-id-from-a-url
- allow属性のパラメータがたくさんあるが、今回は使わない
- 備考: 普通の動画も生配信も埋め込み用URLは一緒
niconico
- 公式document: これ?
- 詳しく記載されたページが見当たらない
<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/1453178722?w=490&h=307"></script>
公式的には↑だが、実際はiframeを表示しているので
<iframe src="http://embed.nicovideo.jp/watch/1453178722"></iframe>
とする。
- 埋め込みに必要なURL: http://embed.nicovideo.jp/watch/1453178722
- 備考: ニコニコ動画は通常の動画(https://www.nicovideo.jp/video_top にある動画)のみ対応。コミュニティや生放送のURLには対応しなかった。
- ニコニコ公式がブログパーツは提供しているが、埋め込み動画を提供していないため。
対応させるURL
http://twitch.tv/********
https://www.twitch.tv/********
https://go.twitch.tv/********
https://m.twitch.tv/********
https://youtu.be/********
https://www.youtube.com/watch?v=********
https://gaming.youtube.com/watch?v=********
https://nico.ms/sm********
https://www.nicovideo.jp/watch/sm********
「********」はID
実装方法
function embedVideo(url: string) {
const hostname = urlParser(url).hostname
const matchesTwitch = url.match(/twitch\.tv\/([^#?/]+)/)
if (/twitch\.tv$/.test(hostname) && matchesTwitch) {
return 'https://player.twitch.tv/?channel=' + matchesTwitch[1] + '&autoplay=false'
}
if (/(youtube\.com|youtu\.be)$/.test(hostname) && !/\/user\//.test(url) && !/\/channel\//.test(url)) {
const matches = url.match(/(\/watch\?v=|youtu\.be\/)([^#&?/]+)/)
if (!matches) return ''
return 'https://www.youtube.com/embed/' + matches[2]
}
if (/(nicovideo\.jp|nico\.ms)$/.test(hostname) && !/live/.test(hostname)) {
const matches = url.match(/(\/watch\/|nico\.ms\/)([^#&?/]+)/)
if (!matches) return ''
return 'https://embed.nicovideo.jp/watch/' + matches[2]
}
return ''
}
Vue.jsの場合
Vue.filtersに追加して、
filters: {
embedVideo,
},
iframeのsrcでフィルタすると良いです。
<iframe :src="url | embedVideo" allow="fullscreen"></iframe>
レスポンシブ対応
.video
position relative
padding-bottom 56.25%
& > iframe
position absolute
size 100% 100%
border none
<iframe>
はそのままだとサイズが変わらないので、position: absolute;
で浮かせて親要素に同じ高さのpaddingを取ることで、可変になります。
2021-06-02 追記
aspect-ratio: 16/9;
を使うことでも対応できるようです。ただしSafariは未対応。
Discussion