ffmpegを使って、Google Driveからダウンロードした画像をbgm付きでライブ配信してみました。
以下は画像をダウンロードするスクリプト(download.sh)。
#!/bin/sh
work_dir=$(cd $(dirname $0); pwd)
next_image_file="${work_dir}/next.jpg"
timed_image_file="${work_dir}/timed.jpg"
org_image_file="${work_dir}/current.jpg"
rclone copy mydrive:img/current.jpg ${work_dir}
current_date_time=`date "+%Y-%m-%d %H:%M:%S"`
convert ${org_image_file} -font "DejaVu-Sans-Bold" -fill white -pointsize 64 -gravity south -annotate 0 "$current_date_time" ${timed_image_file}
convert ${timed_image_file} -resize 1280x720x -background black -gravity center -extent 1280x720 ${next_image_file}
このスクリプトは、後述するストリーミング用のスクリプトから実行します。rcloneというツールでgoogle driveから画像をダウンロードしています。ブラウザが起動できないサーバ上で実行するため、rcloneの設定ファイル(rclone.conf)はこちらのページを参考に事前に別のPCで取得したものをコピーして使いました。そして現在時刻を取得し、画像にその時刻を描画した後、配信するのにちょうどいいサイズ(1280×720)に変換しています。ちなみにconvertはImagemagickのコマンドです。ダウンロードしている画像は縦長のため、左右は黒い領域となります。
以下はライブ配信するスクリプト。
#!/bin/sh
stream_key="${STREAM_KEY}"
work_dir=$(cd $(dirname $0); pwd)
next_image_file="${work_dir}/next.jpg"
live_image_file="${work_dir}/live.jpg"
./download.sh
cp ${next_image_file} ${live_image_file}
while true
do
for audio_file in ${work_dir}/bgm/*.mp3
do
ffmpeg -loglevel quiet -loop 1 -re -r 24 -i ${live_image_file} -i "${audio_file}" -vcodec libx264 -g 48 -acodec aac -strict experimental -ab 320k -ac 2 -ar 44100 -pix_fmt yuv420p -shortest -f flv rtmp://a.rtmp.youtube.com/live2/${stream_key}
cp ${next_image_file} ${live_image_file}
./download.sh &
done
done
forループの中身ではffmpegで静止画とBGMとするmp3を指定してyoutubeに配信しています。「エンコーダがリアルタイムより高速でデータを送信しています(複数秒の動画が毎秒送信されています)。ライブ動画のアップロードを毎秒約 1 秒の動画に制限してください。」というエラーを回避するため、”-re”というオプションをつけることでリアルタイムに配信してます。bgmの再生が終わると次に表示する画像をコピーして、download.shをバックグラウンドで実行して次の画像をダウンロードしつつ、最初からまた実行します。バックグラウンドで実行しているのは、配信が長時間途切れるのを回避するためです。ちなみに、Google Driveからダウンロードする画像を定期的に更新すれば表示される画像を変えることができます。最初はGoogle Driveの画像が更新されたら通知を受けてリアルタイムに配信する内容を変更しようとしていましたが、難しそうなので断念しました。
このスクリプトはほとんどChatGPTに作ってもらったのですが、ほぼそのままで動作しました。ただ、時々途切れる問題があったので、画像サイズを小さめにしたり、ffmpegのパラメータをいじったりしてます。
Comments