Chrome で MOQT が動いた
MOQT (Media over QUIC Transport) は QUIC と WebTransport の二つがトランスポートでの利用が想定されており QUIC は moqt:// で WebTransport は https:// です。
Chrome は WebTransport 実装がかなり遅れており検証目的としては厳しいと判断して、後回しにしてきましたが、汎用的に Chrome で確認できるのもまぁ大事だろうと考えブラウザの WebTransport にも Python の MOQT ライブラリを対応することにしました。
ブラウザから Python のリレーサーバー経由でブラウザに配信しているデモ
現在の 2025 年 12 月現在の WebTransport は draft-14 ですが、Chrome の WebTransport は draft-02 です。ただし --enable-features=EnableWebTransportDraft07 を指定する事で draft-07 が利用できることがわかりました。draft-07 は大きく draft-14 と違うわけではありませんが、nghttp3 の WebTransport 対応側で対応する必要があります。
いったん fork で対応して、動作を確認して「これでブラウザで動いた」という差分を ngthttp3 の作者に共有したところ取り込んで貰いました。
MOQT の JavaScript ライブラリ
MOQT をブラウザから利用できるようにするため JS ライブラリを開発しました。MOQT 自信が難しくないこともあり 1 日で実装自体は終わりました。これはそのうち OSS として公開します。
その後、検証ページを作りました。これは preact + signals + tailwind + vite です。React に疲れていたので preact を採用してみましたが、自分には合っていそうなので今後は preact で頑張ろうという気持ちになりました。
moqt-devtools として MOQT JS ライブラリに含めてありますので、こちらも公開します。サイトもあるのでそちらも公開します。
MOQT の Python ライブラリ
時雨堂では MOQT は msquic と nghttp3 (nghttp2 を含む) を組み合わせて nanobind を利用して Free Threading で利用できるようにしています。
全くチューニングしていないのでリレーサーバーは性能定期には 1 Gbps でるかでないか程度ですが、検証用としては十分な性能だと思っています。スケールアップは狙っていますが、スケールアウトはしません。
Python だと pytest 経由で色々できます。Playwright を使ってブラウザでのテストもささっとできてしまいます。
こちらは色々落ち着いたら 2026 年には OSS として Apache-2.0 で公開予定です。気軽に MOQT が動かせる仕組みを提供していきます。
サーバー (Relay)
from moqt import RelayServer
relay = RelayServer(
port=4433,
cert_file="server.crt",
key_file="server.key",
)
def on_session(session):
print(f"New session: {session}")
relay.set_on_session(on_session)
relay.run()
クライアント (Publisher)
from moqt import Client
with Client(verify=False) as client:
with client.connect("moqt://127.0.0.1:4433/moqt") as session:
publisher = session.publish(
namespace=[b"live"],
track_name=b"video",
)
publisher.send_object(group_id=0, object_id=0, payload=b"Hello, MOQT!")
publisher.unpublish()
クライアント (Subscriber)
from moqt import Client
with Client(verify=False) as client:
with client.connect("moqt://127.0.0.1:4433/moqt") as session:
def on_object(group_id: int, object_id: int, payload: bytes):
print(f"Received: {payload}")
subscriber = session.subscribe(
namespace=[b"live"],
track_name=b"video",
on_object=on_object,
)
# ... データ受信待機 ...
subscriber.unsubscribe()
雑感
MOQT をとりあえず msquic と nghttp3 で実装してきましたが、msquic と nghttp3 のおかげで楽をさせて貰っています。MOQT 自体はあまり困っていません。MOQT の Python も JavaScript も両方所はまり所なく実装できました。
色々コードを整理して公開でき次第 MOQT は一段落させて、Multipath QUIC へ進められればと思います。
おまけ
今回は msquic + nghttp3 で WebTransport over HTTP/3 も実装してみました。Python の moqt ライブラリにおまけで入れるか、独立するかを悩んでいます。wt-devtools も JavaScript でざっくり作りました。
