HLS
lambda

AWS LambdaからHLSストリームのスナップショットを撮る

More than 1 year has passed since last update.

環境

  • AWS Lambda
  • python 2.7
  • livestreamer 1.12
  • ffmpeg 2.4.2

Installation

  • Livestreamerをローカルインストール
pip install livestreamer -t .
  • Lambda用にffmpegのバイナリをダウンロード
$ wget https://github.com/imageio/imageio-binaries/raw/master/ffmpeg/ffmpeg.linux64 -O ffmpeg
$ chmod +x ffmpeg

撮り方

lambda_function.py

import livestreamer
import time
import subprocess

def lambda_handler(event, context):
  url = "hlsvariant://serverIp/application/stream/playlist.m3u8"
  streams = livestreamer.streams(url)
  stream = streams["best"]
  fd = stream.open()
  data = ''
  while len(data) < 3e5:
    data += fd.read(100000)
    time.sleep(0.1)
  fd.close()

  fname = '/tmp/stream.bin'
  open(fname, 'wb').write(data)

  cmd = "./ffmpeg -i /tmp/stream.bin -vframes 1 snapshot.png -y"
  proc = subprocess.Popen(shlex.split(cmd),
          stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  res = proc.communicate()
  print(res[0])

解説

  • HLSストリームを300KBだけ読み込み
url = "hlsvariant://serverIp/application/playlist.m3u8"
streams = livestreamer.streams(url)
stream = streams["best"]
fd = stream.open()
data = ''
while len(data) < 3e5:
 data += fd.read(100000)
 time.sleep(0.1)
fd.close()

fname = '/tmp/stream.bin'
open(fname, 'wb').write(data)
  • ストリームのバイナリからffmpegで1フレームだけ出力
cmd = "./ffmpeg -i /tmp/stream.bin -vframes 1 snapshot.jpg -y"
proc = subprocess.Popen(shlex.split(cmd),
      stderr=subprocess.PIPE, stdout=subprocess.PIPE)
res = proc.communicate()
print(res[0])

デプロイ

  • terraformでデプロイ
zip -r snapshot_livestream.zip *
resource "aws_lambda_function" "snapshot_livestream" {
    filename = "snapshot_livestream.zip"
    source_code_hash = "${base64sha256(file("snapshot_livestream.zip"))}"
    description =  "Take a snapshot of livestream"
    function_name = "snapshot_livestream"
    runtime = "python2.7"
    timeout = 20
    memory_size = 1024
    role = "your_lambda_role"
    handler = "lambda_function.lambda_handler"
}

参考