HLSストリーミング配信の作成と録画(pythonとffmpeg)


もうすぐ5G通信が到来し、ライブ配信を活用した案件が増えると思われます。今回はpythonとffmpegを使った、HLSの作成と録画を紹介します。

HLSについて

概要

  • HLSとは HTTP Live Streaming の略。アップルが開発しています。ブラウザではMacのSafariとWindowsのEdgeが対応しています。

特徴

  • ファイルであること。基本的にはMP4ファイルを5秒ごとに分割しただけです。なのでHttpサーバーに置くだけで使えます(5秒は変更可能)
  • アダプティブビットレート。環境によって高画質と低画質が自動的に切り替わります。自動的なのがポイント。

ファイル

  • 連番の付いた ts ファイルと、再生する m3u8 ファイルがあります。フリーソフトVLCなどでは、m3u8 ファイルをそのまま再生できます。
Video HLS
input.mp4





playlist.m3u8
001.ts
002.ts
003.ts
004.ts
005.ts

HLSの作成

ビデオMP4ファイルからHLSを作成します。input.mp4ファイルとhlsフォルダを用意して、以下のmain.pyを実行してください。

  • Macの場合、ffmpegを brew install ffmpeg でインストールしてください。
  • Windowsの場合、ffmpeg.exeを入手して、以下のffmepgをffmepg.exeに書き換えればOKです。
main.py
# -*- coding: utf-8 -*-
import sys, os
import subprocess
import codecs

def create_hls():
    # 高画質m3u8の作成 (input.mp4 -> hls/h.m3u8)
    c = 'ffmpeg'
    c += ' -i input.mp4'
    c += ' -codec copy -vbsf h264_mp4toannexb -map 0'
    c += ' -f segment -segment_format mpegts -segment_time 5'
    c += ' -segment_list hls/h.m3u8'
    c += ' hls/h_%5d.ts'
    code = subprocess.call(c.split())
    print('process=' + str(code))

    # 低画質mp4の作成 (input.mp4 -> input_low.mp4)
    c = 'ffmpeg'
    c += ' -i input.mp4'
    c += ' -f mp4 -vcodec h264 -vb 500k -s 640x360 -pix_fmt yuv420p'
    c += ' -ac 2 -ar 48000 -ab 128k -acodec aac -strict experimental'
    c += ' -movflags faststart'
    c += ' input_low.mp4'
    code = subprocess.call(c.split())
    print('process=' + str(code))

    # 低画質m3u8の作成 (input_low.mp4 -> hls/l.m3u8)
    c = 'ffmpeg'
    c += ' -i input_low.mp4'
    c += ' -codec copy -vbsf h264_mp4toannexb -map 0'
    c += ' -f segment -segment_format mpegts -segment_time 5'
    c += ' -segment_list hls/l.m3u8'
    c += ' hls/l_%5d.ts'
    code = subprocess.call(c.split())
    print('process=' + str(code))

    # 低画質高画質を含めたm3u8の作成 (->hls/playlist.m3u8)
    t = '#EXTM3U'
    t += '\n##EXT-X-VERSION:3'
    t += '\n#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=500000'
    t += '\nl.m3u8'
    t += '\n#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4000000'
    t += '\nh.m3u8'
    f = codecs.open('hls/playlist.m3u8', 'w', 'utf-8')
    f.write(t)
    f.close()

if __name__ == "__main__":
    create_hls()

実行すると、hls フォルダに m3u8 と ts が作られます。

Httpサーバーに置く

HLSは Mac の Safari と Windows の Edge が対応しています。上記でできた hls フォルダを Http サーバーに置いて、以下をブラウザでアクセスしてください。
http://localhost:8080/hls/playlist.m3u8

Httpサーバーがない場合は、pythonでも構築できます。

cd yourdirectory
(python 2)
python -m SimpleHTTPServer 8080
(python 3)
python -m http.server 8080

HLSの録画

HLSをffmepgを使い録画します。iOSフリーソフト「it's my Live」を使った例を紹介します(iOSのみです)

  1. HLSモードを選択してURLが表示されるので控えます。
  2. ブラウザでアクセスします。ブラウザはSafariかEdgeをお使いください。
  3. Wifiのローカルネットのみです(社内LANや家庭内LAN)

以下のrec.pyをアドレスを変えて実行します。

rec.py
# -*- coding: utf-8 -*-
import sys, os
import subprocess

def recode_hls():
    c = 'ffmpeg'
    c += ' -i http://10.255.114.14:8080/my/playlist.m3u8' 要変更
    c += ' -movflags faststart -c copy rec.mp4'
    code = subprocess.call(c.split())
    print('process=' + str(code))

if __name__ == "__main__":
    recode_hls()

注意点
録画 rec.mp4 はできたのだが、QickTimeで再生できない場合
以下を試してください(aacを有効)
brew uninstall ffmpeg
brew install ffmpeg --with-fdk-aac --with-libvo-aacenc
brew install ffmpeg

アプリ設定のビットレート、フレームレート、サイズを変えても録画可能でした。1分以上長めに録画してみるとか、再起動してみるなど試してください。

まとめ

RTMP や次世代の SRT はライブサーバーが必要です。遅延を気にしないならHLSが楽です。ドライブレコーダーや会議の録画なんかは大手企業がやるでしょう。私のような中小企業は隙間商法で入り込みたいところ。何かいいアイデアがないかなぁと模索しているところです。