# チュートリアル

このチュートリアルでは Python Sora SDK を利用して映像を配信する方法を説明します。

## 接続先の用意

接続先は時雨堂が開発、販売している WebRTC SFU Sora を利用します。

検証目的であれば [Sora Labo](https://sora-labo.shiguredo.jp/) を利用することで、 Sora を無料で試すことが可能です。

GitHub アカウントを用意して [Sora Labo のドキュメント](https://github.com/shiguredo/sora-labo-doc) を読んだ後、
 にサインアップしてください。

必要なのは以下の 3 つです。

- シグナリング URL
- チャネル ID
- Sora Labo や Sora Cloud の場合はアクセストークン

## uv のインストール

Sora Python SDK の例では uv を利用しています。

[Installation | uv](https://docs.astral.sh/uv/getting-started/installation/) を参考に uv をインストールしてください。

## プロジェクトの作成

uv init でプロジェクトを作成します。

```console
$ uv init tutorial
$ cd tutorial
```

## Python Sora SDK セットアップ

uv add して sora-sdk をインストールします。

```console
$ uv add sora-sdk
```

また、映像を配信するためにはカメラデバイスを利用する必要があります。
ここでは OpenCV を利用します。

```console
$ uv add opencv-python opencv-python-headless
```

## main.py を作成

デバイスキャプチャをして、 映像を配信する main.py を作成します。今回は音声は送りません。

signaling_url や channel_id や access_token は適切なものを指定してください。

```python
import platform

import cv2  # type: ignore
from sora_sdk import (
    Sora,
)


def get_video_capture(fps=30) -> cv2.VideoCapture:
    """
    ここは Python SDK 関係なくカメラデバイスをキャプチャする部分です。
    """
    video_capture = None

    # ここからカメラの設定
    if platform.system() == "Windows":
        # CAP_DSHOW を設定しないと、カメラの起動が遅くなる
        video_capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    else:
        video_capture = cv2.VideoCapture(0)

    video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
    video_capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))
    video_capture.set(cv2.CAP_PROP_FPS, fps)

    # Ubuntu → FOURCC を設定すると FPS が初期化される
    # Windows → FPS を設定すると FOURCC が初期化される
    # ので、両方に対応するため２回設定する
    fourcc = cv2.VideoWriter_fourcc(*"MJPG")
    target_fourcc = video_capture.get(cv2.CAP_PROP_FOURCC)
    if fourcc != target_fourcc:
        video_capture.set(cv2.CAP_PROP_FOURCC, fourcc)
    if fps != int(video_capture.get(cv2.CAP_PROP_FPS)):
        video_capture.set(cv2.CAP_PROP_FPS, fps)

    return video_capture


def main() -> None:
    signaling_url = "ws://192.0.2.1:5000/signaling"
    channel_id = "sora"
    access_token = "access_token"

    sora: Sora = Sora()
    video_source = sora.create_video_source()

    connection = sora.create_connection(
        signaling_urls=[
            signaling_url,
        ],
        role="sendonly",
        channel_id=channel_id,
        metadata={"access_token": access_token},
        video_source=video_source,
    )

    # カメラデバイス確保
    video_capture = get_video_capture()

    # 接続
    connection.connect()

    try:
        while True:
            # カメラデバイスからの映像を取得
            success, frame = video_capture.read()
            if not success:
                continue
            # カメラデバイスからの映像を Python SDK に渡す
            video_source.on_captured(frame)
    except KeyboardInterrupt:
        pass
    finally:
        # 切断
        connection.disconnect()
        # カメラデバイスを解放
        video_capture.release()


if __name__ == "__main__":
    main()
```

## main.py 起動

```console
$ uv run main.py
```

止めるときは Ctrl+C です。

## main.py からの映像を確認

[Sora-DevTools](https://github.com/shiguredo/sora-devtools) を利用して Python SDK から送られてきている映像を確認してみてください。
