Posted at

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"
}


参考