この記事は、NetBSD Advent Calendar 2019の2日目の記事です。
はじめに
いつだったか忘れてしまいましたが安売りをしていた時に、Google Chromecastを購入していました。 ですが、スマートフォンやPCのGoogle Chromeから投影しないといけないので、 自立しているAmazon Fire TV Stickに比べて活躍の機会があまりありませんでした。
NetBSDラップトップから画面を投影できるのであれば、HDMIケーブルで接続しなくて良いかもしれません。 今回は、NetBSD環境の画面を投影してみました。
ライブラリーを選定する
ウェブを検索してみると、以下の4つの方法が有望そうです。
- VideoLANのVLCの
screen://
を利用する。 - pyChromecastを利用する。
- castv2-clientを利用する。
- node-castv2を利用する。
後ろから2つはnode.js
のモジュールです。
これはpkgsrc
ではパッケージングしにくいので、上から2つを試してみました。
VLCのscreen://
を試す
結果から言うと、依存しているlibmicrodns
がNetBSDに対応しておらず、ビルドできませんでした。
MCAST_JOIN_GROUP
がヘッダーファイルで定義されていない場合のコードが、正しくないようです。
RFC3678を良く読まないといけないようなので、今回は断念しました。
pyChromecast
を試す
pyChromecast
は、pkgsrc/net/py-pychromecast
に用意しました。
以下のようにインストールできます。
$ cd /usr/pkgsrc/net/py=pychromecast $ make installただし、
pyChromecast
自体はライブラリーだけなので、サンプルプログラム等が付属する訳ではありません。
pyChromecast
はzeroconfというPythonのみで書かれたライブラリーのあかげで、無事に使うことができました。
pyChromecastのREADME.rstを参考に以下のようなファイルを作って実行してみました。
30秒のビデオが再生できました。
import time import pychromecast chromecasts = pychromecast.get_chromecasts() cast = next(cc for cc in chromecasts if cc.device.friendly_name == "Living Room TV") cast.wait() print(cast.status) mc = cast.media_controller mc.play_media('https://www.ryoon.net/~ryoon/BigBuckBunny.mp4', 'video/mp4') mc.block_until_active() mc.play() time.sleep(30) mc.stop()Chromecastへ映像を送る方法は分かりました。
次に画面をChromecastに送る方法を考えてみます。
自分のChromecastから見える場所にビデオストリームを置いてやれば良いはずです。
画面をキャプチャーするのは、ffmpeg
のx11grab
ソースが一番手軽なように思います。
そして、ffmpegと組み合わせるとなると、一番簡単に使えるのはffserver
です。
ffserver
は、pkgsrc/multimediaffmpeg3
を最後に削除されてしまいました。
そこで、今回はffmpeg4
パッケージではなくffmpeg3
を使うことにします。
さて、そもそも、Chromcastが再生できるビデオストリームとはのような仕様でしょうか? Supported Media for Google Castのページによると、 WebMコンテナーのVP8ビデオであれば再生できそうです。 解像度は、1980×1080も可能なようですが、1280×720で進めてみます。
このようなビデオを配信するffserver3
の設定ファイルは以下のようになります。
サウンドは今回は配信しません。
Port 8090 BindAddress 0.0.0.0 MaxHTTPConnections 1000 MaxClients 200 MaxBandwidth 10000 CustomLog - <:Feed screen.ffm> File /tmp/screen.ffm FileMaxSize 20M <:/Feed> <:Stream screen.webm> Feed screen.ffm Format webm VideoCodec libvpx VideoFrameRate 30 VideoSize 1280x720 VideoBitRate 512 VideoBufferSize 80 VideoGopSize 30 NoAudio <:/Stream>実行は以下のようにします。。
$ ffserver3 -f ffserver3-vp8.confこれで、
http://localhost:8090/screen.ffm
にffmpeg3
コマンドでビデオを送信してやると、
http://10.81.0.117:8090/screen.webm
(ここで、10.81.0.117はNetBSDラップトップのIPアドレス)でストリーミング配信されます。
これに画面の左上1280×720ピクセル分を流し込むには、以下のように実行します。
ffmpeg3 -f x11grab -r 30 -s 1280x720 -i :0.0 -vcodec vp8 -c:v libvpx -b:v 2M -threads 2 -s 1280x720 http://localhost:8090/screen.ffm
このストリーミング配信を再生するようにChromecastに指示するのは以下のようなファイルを用意します。
import time import pychromecast chromecasts = pychromecast.get_chromecasts() cast = next(cc for cc in chromecasts if cc.device.friendly_name == "Living Room TV") cast.wait() print(cast.status) mc = cast.media_controller mc.play_media('http://10.81.0.117:8090/screen.webm', 'video/webm; codecs="vp8, vorbis"') mc.block_until_active() mc.play() time.sleep(120) mc.stop()ファイル名を
screencast.py
とすると、以下のように実行します。2分間再生します。
$ python3.8 screencast.py
私の環境では、約5秒から15秒で遅れで配信することができました。
ffmpeg3
コマンドのオプションを工夫することで、遅延は短くできるかもしれません。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。