LoginSignup
22
14

More than 3 years have passed since last update.

AWS+hls.jsでストリーミング再生(その2)

Posted at

hls.jsを使ってストリーミング再生を試みます。

mp4からHLSに変換するところは前回の記事をご覧ください。
この記事ではHLS形式の動画をブラウザからhls.jsを使って再生する部分を書きます。

条件

・AWS S3のバケット上にhls形式の動画がある。
・ブラウザはChromeを使用。
・ビデオを再生するフロント部分はfirebaseでデプロイ。

さっそく

hls.jsのread.meに書いてある通りなのですが(本当にすっごく親切に書いてあります)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
   <video id="video" style="display: none;"></video>
   <button id="button">play video</button>
   <script>
   if (Hls.isSupported()) {
       let video = document.getElementById('video');
       let hls = new Hls();
       // bind them together
       hls.attachMedia(video);
       hls.on(Hls.Events.MEDIA_ATTACHED, function () {
         console.log("video and hls.js are now bound together !");
         hls.loadSource("動画が保存されているS3バケット/hls_sample/hls_400k_.m3u8");
         hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
             console.log(data)
           console.log("manifest loaded, found " + data.levels.length + " quality level");
           let fragments = data.levels[0].details.fragments
           let play_time = 0
           for(let i in fragments) {
               console.log(fragments[i]);
               play_time += fragments[i].duration
            }
            console.log("play_time : ",play_time)  
            play_time = Math.floor((play_time*1000)+1000)
            console.log(play_time)        
           button.addEventListener('click', function() {
               video.style.display="block"
               video.muted = false;
               video.play();
               setTimeout(function(){console.log("end")}, play_time);
            });
        })
    })
    }
   </script>   
</body>
</html>

こんな感じです。
これをfirebaseにあげました。

<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>

今回はcdnでhls.jsを読み込みました。

<video id="video" style="display: none;"></video>
<button id="button">play video</button>

videoタグで動画を再生する場所を確保し、
ボタンが押されたら動画を再生するようにしました。
(理由は後述します)


hls.loadSource("動画が保存されているS3バケット/hls_sample/hls_400k_.m3u8");

ここでHLSのプレイリストファイル(.m3u8)を読み込み、

 button.addEventListener('click', function() {
               video.style.display="block"
               video.muted = false;
               video.play();
               setTimeout(function(){console.log("end")}, play_time);
            });

ボタンが押された時にvideo.play()で再生しています。
play_timeの時間でタイムアウトを設定しているのは、ちょっと事情があって、動画の再生が終了したことを知りたかったからです・・・

はまったところ

Chromeブラウザでautoplayができない・・・?

はじめ、動画は再生されるのに音声が全く再生されず、なんでや・・・?と悩みました。
調べてみたところ、Chromeのバージョン66以上では、音声付き動画について、videoタグのautoplay属性が無効になるとのこと・・・
確かに、video.mutedをtrueにして、videoタグにautoplayを指定していると、音声なしで再生されます。
FirefoxやIEではこのような問題は起こっていないようなので、Chromeブラウザを使う場合は注意が必要です。

今回はページを読み込んだタイミングでビデオを再生するのではなく、任意のタイミング(ボタンを押した時)に再生したかったので、ボタンを押したタイミングで再生されるようにしました。

CORSで引っかかる・・・?

(もはやHLSの話ではないので手短に・・・)
S3とfirebaseの両方でCORSの設定が必要でした。
当たり前すぎてこんなことに躓いた自分が恥ずかしい・・・

S3のCORSの設定

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>

AllowedOriginはワイルドカード(*)ではなく、許可したいものだけ(今回の場合はfirebaseのエンドポイント)にすると良いと思います・・・

firebaseは

firebase.json
      "headers": [ {
        "source" : "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
        "headers" : [ {
          "key" : "Access-Control-Allow-Origin",
          "value" : "*"
        } ]
      }],

これを追記します。
headerにCORSの設定を追加します。

感想

hls.jsは本当に分かりやすくて使い勝手がいいと思いました。
ドキュメントがとても丁寧:relaxed:
Chromeでautoplayが使えないのは知らなかったので、勉強になりました・・・

22
14
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
14