🔖
S3に保存されている動画の尺をLambdaで確認する
きっかけ
特にこれといった目的があった訳じゃないんですが、動画の尺を取得できると便利かなとふと思った。個人的な案件でS3にファイルが保存されていることが多かったのでS3を対象としてるけど、他のストレージにも流用できそうな形にできたらいいなと感じ、メモ代わりに方法を残しておく。
方法
Layerの追加
Layerに追加するためのzipファイルをローカル環境で作成
wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
tar xvf ffmpeg-git-amd64-static.tar.xz
mkdir -p ffprobe/bin
cp ffmpeg-4.3.1-amd64-static/ffprobe ffprobe/bin/
cd ffprobe
zip -r ../ffprobe.zip
作成したZipファイルをLayerに追加します。
AWS CLIで設定やS3にアップロードしてから設定する方法がありますが、今回はコンソールからLayerを登録しました。
コンソール上でLayerレイヤーを登録
Lambdaコード
Layerを追加して、ffprobeコマンドを実行して動画尺情報を取り出すことができます。
/opt/bin/ffprobe -i "url" -hide_banner -show_entries format=duration
指定するURLはpresigned urlで一時的にダウンロード可能にします
サンプルコードはこちら(IAMロールを適切に設定してください)
import subprocess
import shlex
import boto3
s3_client = boto3.client('s3')
SIGNED_URL_TIMEOUT = 10
def lambda_handler(event, context):
s3_source_bucket = xxxxxxxxxxxxxxxx
s3_source_key = yyyyyyyyyyyyyyyy
signed_url = s3_client.generate_presigned_url(
'get_object',
Params={'Bucket': s3_source_bucket, 'Key': s3_source_key},
ExpiresIn=SIGNED_URL_TIMEOUT
)
ffprobe_cmd = "/opt/bin/ffprobe -i \"%s\" -hide_banner -show_entries format=duration" % signed_url
command = shlex.split(ffprobe_cmd)
p1 = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
duration = p1.stdout.decode().split("\n")[1].replace("duration=", '')
return {
'duration': duration
}
レスポンスに以下のように尺情報(秒)が出力されます。
{
"duration": "596.568000"
}
おわりに
ffprobeをLmabdaで使えるようにして、URLで動画ファイルをGetできるようにする方法はいろんなケースで利用できるでしょう。
あまり需要はないと思うけど、誰かの参考になるときがくれば
Discussion