概要
- ffmpeg でマニフェストファイル、セグメントファイルを生成する
- Python で CORS 対応の HLS サーバをサクッと書く
- hls.js の demo ページで動画を再生する
はじめに
HLS (HTTP Live Streaming) は、動画配信を行う上で広く使われている技術です。
モイが運営するツイキャスでも利用されています。
開発を進める上ではデバッグやモックなど、サービスと切り離してHLS配信を利用したくなることがあります。
そのため、Python でミニマムなHLSサーバを実装して動作させてみます。
作業ディレクトリを作成します。
$ mkdir qiita-hls; cd qiita-hls
ffmpeg でマニフェストファイル、セグメントファイルを生成する
動画素材から ffmpeg を利用して、HLS 配信に必要なマニフェストファイル、セグメントファイルを生成します。
配置ディレクトリを作成します。
$ mkdir resource; cd resource
動画素材には Big Buck Bunny を利用させていただきます。
Big Buck Bunny is licensed under the Creative Commons Attribution 3.0 license.
(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org
以下の ffmpeg を実行します。
$ ffmpeg -i ~/Downloads/big_buck_bunny_720p_h264.mov \
-c:v copy -c:a copy \
-f hls \
-hls_time 9 \
-hls_playlist_type vod \
-hls_segment_type fmp4 \
-hls_fmp4_init_filename "init.mp4" \
-hls_segment_filename "seg.%3d.mp4" \
media.m3u8
-f hls
を指定して HLS 形式の出力を行います。また -hls_segment_type fmp4
を指定して FMP4 形式でセグメントファイルを生成します。 この -hls_segment_type fmp4
がないと初期化セグメントが生成されないので注意です。
HLS サーバ
resource
からでて qiita-hls
ディレクトリに戻ります。
$ cd ..
以下を srv.py
として保存します。
srv.py
#!/usr/bin/env python3
import os
from http.server import HTTPServer, SimpleHTTPRequestHandler
class MyRequestHandler(SimpleHTTPRequestHandler):
def send_acao(self):
origin = self.headers["Origin"]
self.send_header("Access-Control-Allow-Origin", origin)
self.send_header("Access-Control-Allow-Headers", "*")
self.send_header("Access-Control-Allow-Methods", "*")
self.send_header("Access-Control-Allow-Credentials", "true")
def send_content_type(self):
content_type = ""
if self.path.endswith(".m3u8"):
content_type = "application/vnd.apple.mpegurl"
elif self.path.endswith(".mp4"):
content_type = "video/mp4"
if content_type != "":
self.send_header("Content-type", content_type)
def do_GET(self):
data, ok = read_resource(os.path.basename(self.path))
if not ok:
self.send_response(404)
self.end_headers()
return
self.send_response(200)
self.send_acao()
self.send_content_type()
self.end_headers()
self.wfile.write(data)
return
def do_OPTIONS(self):
self.send_response(200)
self.send_acao()
self.end_headers()
return
def read_resource(basename):
filepath = "resource/" + basename
if not os.path.exists(filepath):
return b"", False
with open(filepath, "rb") as f:
return f.read(), True
httpd = HTTPServer(("0.0.0.0", 8003), MyRequestHandler)
httpd.serve_forever()
CORS でのリクエストを受け入れるよう、リクエストのはじめに CORS を許可するヘッダー群を返しています。
デバッグやモックなど、開発補助を目的にしているためきちんとした検証は行っていません。
ディレクトリレイアウトはこんな感じになってるはずです。
qiita-hls
├── resource
│ ├── init.mp4
│ ├── media.m3u8
│ ├── seg.000.mp4
│ ├── seg.001.mp4
│ ├── seg.002.mp4
... 省略 ...
└── srv.py
HLSサーバを起動します。
$ python3 srv.py
hls.js の demo ページで動画を再生する
以下のリンクを開き、 http://localhost:8003/media.m3u8
を入力してエンターを押して再生が開始されればOK