迫真の氷結晶

初投稿です。

  • HOME
  • 自己紹介
  • 作品集
  • ポエム系

SPA(Gatsby)にニコニコ動画外部プレーヤーを埋め込む

2019-12-16
  • #技術系
  • #Web系

こんにちは、いの@iciclizeです。

このブログは静的サイトジェネレータGatsbyを使って生成していますが、ニコニコ動画の外部プレーヤーを埋め込もうと思ったときにある問題が発生して困ったので、その解決方法を書き留めておきたいと思います。

結論

<div style="position: relative; padding-bottom: 60%; margin-bottom: 1.5rem;">
  <iframe allowfullscreen="allowfullscreen" allow="autoplay" src="https://embed.nicovideo.jp/watch/sm34594493?oldScript=1&referer=&from=0&allowProgrammaticFullScreen=1" style="position: absolute; width: 100%; height: 100%; border: none;"></iframe>
</div>

これをコピペしてよしなに書き換えると良いと思います。

問題

ニコニコ動画のプレーヤー埋め込みコードは以下のように <script> タグとして提供されています。

<script type="application/javascript" src="https://embed.nicovideo.jp/watch/sm36080909/script?w=640&h=360"></script><noscript><a href="https://www.nicovideo.jp/watch/sm36080909">ドバミアン・ラクソディ</a></noscript>

埋め込みプレーヤーは、埋め込みプレーヤー用の <script> が実行された瞬間に表示されるのですが、Gatsbyを利用して作ったこのサイトにおいては画面遷移時にリロードされず、再び <script> が実行されることがないため、再読み込みをした場合にしか埋め込みプレーヤーが表示されません。

すぐできておおむね問題ない解決策

scriptによって埋め込まれるiframeを自分で埋め込む

埋め込みコードの src 属性の参照先 https://embed.nicovideo.jp/watch/sm36080909/script?w=640&h=360 にアクセスして javascript のコードを読んでみると、頑張って iframe を生成しようとするコードであることが分かります。

ではその埋め込まれる予定の iframe を記事に自分で埋め込んでしまえば <script> の実行不実行にかかわらず埋め込みプレーヤーが表示されるはずです。

コード中に

https://embed.nicovideo.jp/watch/sm36080909?oldScript=1&referer=&from=0&allowProgrammaticFullScreen=1

という記述があって、このURLが <iframe>src 属性になって、プレーヤーがサイトに埋め込まれます。

したがって、公式に提供される <script> タグではなく、それが埋め込む予定の <iframe src="https://embed.nicovideo.jp/watch/sm36080909?oldScript=1&referer=&from=0&allowProgrammaticFullScreen=1"></iframe> を記事に埋め込めばうまくプレーヤーが表示されます。

ただし、そのままでは <iframe> にサイズが指定されておらずデフォルトのサイズでの表示となるので、サイズを自分で指定する必要があります。

このサイトではレイアウト用の <div> タグを含めて以下のようにレイアウトを指定してレスポンシブ対応しています。

<div style="position: relative; padding-bottom: 60%; margin-bottom: 1.5rem;">
  <iframe allowfullscreen="allowfullscreen" allow="autoplay" src="https://embed.nicovideo.jp/watch/sm34594493?oldScript=1&referer=&from=0&allowProgrammaticFullScreen=1" style="position: absolute; width: 100%; height: 100%; border: none;"></iframe>
</div>

なんかプレーヤー内のボタンのサイズがおかしい…?

より本質的な解決策

マークダウンで書いた記事のレンダリングにReactMarkdownというコンポーネントを使っているのですが、ページが遷移したときに再レンダリングしてほしいですね。

GatsbyとReact Appの内部を理解してないんでよく分かんないです…

また今度調査します