1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

画面録画のCPU使用率が492%に、Electron配信の負荷を下げる

1
Posted at

📝 この記事は forge.workstyle.tech に掲載した記事の転載です。

Electron製アプリをMacで配信中、利用者がリモートデスクトップから端末を操作できなくなりました。psでは配信用ウィンドウが492%、ffmpegは28%で、録画側が重い状態でした。録画サイズが指定されずRetinaの実解像度で録画していたことと、MediaRecorderとffmpegで二重に符号化していたことが原因でした。

原因は録画サイズと二重符号化

原因は二つありました。

一つ目は、画面録画のサイズを指定していなかったことです。コードはgetDisplayMedia({ video: true })でした。設定画面には1280×720、30fpsと表示していましたが、その値は録画に反映されていませんでした。

指定がないまま、Retinaの実解像度で録画していました。画面は3456×2234などの大きさです。設定値を見て配信負荷を見積もっていた私には、ここが盲点でした。録画は小さなウィンドウのつもりでも、実際には大きな画面を取り込んでいたのです。

二つ目は、映像を二度符号化していたことです。MediaRecorderがVP8をCPUで符号化し、その映像をffmpegがH.264に変換していました。端末の符号化器VideoToolboxが使われるのはffmpeg側だけです。録画側のVP8符号化はCPUに残ったままでした。

配信の前段である録画にも、符号化の仕事があります。プロセスを分けて測ったことで、負荷の場所が分かりました。

録画形式を先に決める

修正では、まずgetDisplayMediaにmaxつきで大きさとフレームレートを渡しました。これで録画側に上限を伝えます。

次に、MediaRecorderではH.264を先に試すようにしました。端末の符号化器が使える形式で録れれば、ffmpegに映像を作り直させずに済みます。実際に録れた形式はvideo/mp4;codecs=avc1,mp4a.40.2でした。

その場合、ffmpegは-c:v copyで詰め替えるだけにします。ここで-b:vや-rを指定すると、映像を結局作り直すことになります。コピーするなら、余計な指定は足しません。

ただし、MediaRecorderがどの形式で録れるかはウィンドウ側でないと分かりません。そこで、ウィンドウから形式の知らせを受けてからffmpegを立ち上げるようにしました。

順番を変えるときは、先に止められる理由を調べます。ffmpegが無い、鍵が無い、といった状態なら、ウィンドウを開く前に利用者へ伝えられます。ウィンドウを先に開いてから「送れません」と表示すると、利用者からは配信中に見えてしまいます。

録画側は約30分の1に

修正後、同じMacで20秒ごとに4回測りました。録画側のCPU使用率は14.8%、16.3%、19.6%、19.2%。ffmpegは0.1%でした。load averageは3.28、3.48、3.27、4.16です。

録画側の負荷は約30分の1になりました。load averageの3〜4には、LLMや埋め込みなどアプリ本体の負荷も含まれています。配信そのものの負荷は、ほぼ無視できる程度です。

ひとつ断っておきます。修正後の回は、受け皿の配信枠を終えた後だったため、YouTubeへの到達を再確認していません。到達を確認できたのは修正前の回です。そのときは9分半配信し、画質は「非常に良い」、ビットレートは3064 kbpsでした。修正後の負荷が下がったことと、修正後の配信到達を確認したことは別です。

負荷が高すぎたら、アプリが自動で配信を止める

負荷を下げても、運用上の不安は残ります。今回いちばん重かったのは、利用者が配信を止められなくなったことです。私は別の経路から止められましたが、利用者には同じ手段がありません。

そこで、負荷が高いときはアプリ自身が配信をやめる仕組みを入れました。配信中は1分平均の負荷を10秒ごとに見ます。負荷がCPUの数 × 2.5を超えた状態が3回(約30秒)続いたら、アプリが自動で配信を止めます。

一瞬だけ跳ね上がったときには止めません。一度でも落ち着いたら、回数を数え直します。やめるときは理由と直し方も画面に出します。たとえば、録画する大きさを下げるよう案内します。

利用者が操作できないほど重くなってから、利用者に停止を求めても遅いのです。異常を検知して止まるところまでを、配信機能の設計に含める必要があります。

まとめ

  • getDisplayMediaにサイズとフレームレートをmaxつきで指定する
  • MediaRecorderが実際に出力した形式を確認してからffmpegを起動する
  • コピーできる形式ならffmpegは-c:v copyで詰め替え、映像を作り直す指定を足さない
  • 配信中は負荷を監視し、高負荷が続いたらアプリが自動で配信を止める

関連記事


元記事: https://forge.workstyle.tech/blog/screen-recording-cpu-492-percent/?utm_source=qiita&utm_medium=crosspost&utm_campaign=screen-recording-cpu-492-percent

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?