シグナリングの型定義

この章ではシグナリングの型について説明します。 シグナリングの仕様については シグナリング を参照ください。

型の表記は TypeScript で記述します。

基本的なデータ型

JSON 値

type JSON

JSON 値を表します。 仕様は RFC 8259 に従います。

デフォルト値

type Default<Type, Value> = Type

オブジェクトのプロパティの省略時のデフォルト値を表します。 例えば foo?: Default<boolean, true> であれば、 foo プロパティを省略すると、 true がデフォルト値として使われます。

長さに制限のある文字列

type LengthRestrictedString<Min, Max> = string

長さに制限のある文字列を表します。 長さの範囲は MixMax を含みます。 例えば LengthRestrictedString<1, 255> であれば、文字列の長さは 1 から 255 まで (255 を含む) です。

整数

type Int = number

整数です。 JSON に整数のみを表す値はないので、具体的な値は number の値です。

浮動小数点数

type Double = number

浮動小数点数です。

値の範囲が制限される整数

type RangedInt<Min, Max> = Int

値の範囲が制限される整数です。 値の範囲は MixMax を含みます。 例えば RangedInt<1, 5> であれば、有効な値は "1, 2, 3, 4, 5" のいずれかです。

ID

type ID = LengthRestrictedString<1, 255>

チャネル ID 、クライアント ID などに使われる値を表します。 長さが 1 から 255 の文字列です。

シグナリング

type Signaling =
    | ClientToServer
    | ServerToClient

type ClientToServer =
    | Connect
    | Answer
    | Candidate
    | UpdateToServer

type ServerToClient =
    | Offer
    | UpdateToClient
    | Push
    | Notify

シグナリングは「クライアントからサーバー (Sora) に送信される」メッセージと「サーバーからクライアントに送信される」メッセージに分かれます。

  • クライアントからサーバーに送信されるメッセージ

    • connect

    • answer

    • candidate

    • update

  • Server からクライアントに送信されるメッセージ

    • offer

    • update

    • push

    • notify

connect

type Connect = {
    type: "connect",
    role: Role,
    channel_id: ID,
    client_id?: ID,
    metadata?: JSON,
    signaling_notify_metadata?: JSON,
    multistream?: Default<boolean, false>,
    spotlight?: Default<Spotlight, false>,
    spotlight_number?: RangedInt<1, 8>,
    simulcast?: Default<Simulcast, false>,
    audio?: Default<Audio, true>,
    video?: Default<Video, true>,
    sdp?: string,
    sora_client?: string,
    environment?: string,
    libwebrtc?: string
}

ストリームの種別

type Role = "sendrecv" | "sendonly" | "recvonly" | "upstream" | "downstream"

サイマルキャスト

type Simulcast =
    | boolean
    | { quality: SimulcastQuality }

type SimulcastQuality = "low" | "middle" | "high"

スポットライト

type Spotlight =
    | boolean
    | RangeInt<1, 8>

音声

type Audio =
    | boolean
    | {
        codec_type?: AudioCodecType,
        bit_rate?: RangedInt<6, 510>,
        opus_params?: {
            channels?: Int;
            clock_rate?: Int;
            maxplaybackrate?: Int;
            minptime?: Int;
            ptime?: Int;
            stereo?: boolean;
            sprop_stereo?: boolean;
            useinbandfec?: boolean;
            usedtx?: boolean;
        }
      }

type AudioCodecType = "OPUS"

映像

type Video =
    | boolean
    | {
        codec_type?: VideoCodecType,
        bit_rate?: RangedInt<1, 50000>,
      }

type VideoCodecType = "VP9" | "VP8" | "AV1" | "H264" | "H265"

offer

type Offer = {
    type: "offer",
    sdp: string,
    client_id: ID,
    connection_id: ID,
    metadata?: JSON,
    config?: JSON,
    encodings?: Encoding[],
}

type Encoding = {
    rid?: string,
    maxBitrate?: Int,
    maxFramerate?: Double,
    scaleResolutionDownBy?: Double
}

answer

type Answer = {
    type: "answer",
    sdp: string
}

candidate

type Candidate = {
    type: "candidate",
    candidate: string
}

update (サーバー -> クライアント)

type UpdateToClient = {
    type: "update",
    sdp: string,
    encodings?: Encoding[]
}

update (クライアント -> サーバー)

type UpdateToServer = {
    type: "update",
    sdp: string,
    encodings?: Encoding[]
}

push

type Push = {
    type: "push",
    data: object
}

notify

type ClientMetadata = { [key: string]: JSON; }

type Notify =
    | ConnectionCreated
    | ConnectionUpdated
    | ConnectionDestroyed
    | SpotlightChanged
    | NetworkStatus

接続中のクライアントの情報

type ClientMetadata = { [key: string]: JSON; }

キーの文字列は Base32-UUIDv4 です。

connection.created

type ConnectionCreated = {
    type: "notify",
    event_type: "connection.created",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: JSON,
    metadata_list?: ClientMetadata[],
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int,
    turn_transport_type: "udp" | "tcp"
}

connection.updated

type ConnectionUpdated = {
    type: "notify",
    event_type: "connection.updated",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int,
    turn_transport_type: "udp" | "tcp"
}

connection.destroyed

type ConnectionDestroyed = {
    type: "notify",
    event_type: "connection.destroyed",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int,
    turn_transport_type: "udp" | "tcp"
}

spotlight.changed

type SpotlightChanged = {
    type: "notify",
    event_type: "spotlight.changed",
    client_id: ID | null,
    connection_id: ID | null,
    spotlight_id: ID,
    fixed?: boolean,
    audio: boolean,
    video: boolean
}

spotlight.focused

type SpotlightFocused = {
    type: "notify",
    event_type: "spotlight.focused"
    client_id: ID | null,
    connection_id: ID,
    audio: boolean,
    video: boolean,
    fixed: boolean
}

spotlight.unfocused

type SpotlightUnfocused = {
    type: "notify",
    event_type: "spotlight.unfocused",
    client_id: ID | null,
    connection_id: ID,
    audio: boolean,
    video: boolean,
    fixed: boolean
}

network.status

type NetworkStatus = {
    type: "notify",
    event_type: "network.status",
    unstable_level: RangedInt<0, 3>
}

disconnect

type Disconnect = {
    type: "disconnect"
}

完全な型定義

// デフォルト値のある型
type Default<Type, Value> = Type

// 長さに制限のある文字列
type LengthRestrictedString<Min, Max> = string

// 整数
type Int = number

// 浮動小数点数
type Double = number

// 値の範囲が制限される整数
type RangedInt<Min, Max> = Int

// 長さ 1..255 の文字列
type ID = LengthRestrictedString<1, 255>

// シグナリング
type Signaling =
    | ClientToServer
    | ServerToClient

// クライアントからサーバーに送信されるメッセージ
type ClientToServer =
    | Connect
    | Answer
    | Candidate
    | UpdateToServer
    | Disconnect

// サーバーからクライアントに送信されるメッセージ
type ServerToClient =
    | Offer
    | UpdateToClient
    | Push
    | Notify

// type: "connect"
type Connect = {
    type: "connect",
    role: Role,
    channel_id: ID,
    client_id?: ID,
    metadata?: JSON,
    signaling_notify_metadata?: JSON,
    multistream?: Default<boolean, false>,
    spotlight?: Default<Spotlight, false>,
    spotlight_number?: RangedInt<1, 8>,
    simulcast?: Default<Simulcast, false>,
    audio?: Default<Audio, true>,
    video?: Default<Video, true>,
    sdp?: string,
    sora_client?: string,
    environment?: string,
    libwebrtc?: string
}

// ストリームの種別
type Role = "sendrecv" | "sendonly" | "recvonly" | "upstream" | "downstream"

// サイマルキャスト
type Simulcast =
    | boolean
    | { quality: SimulcastQuality }

type SimulcastQuality = "low" | "middle" | "high"

// スポットライト
type Spotlight =
    | boolean
    | RangeInt<1, 8>

// 音声
type Audio =
    | boolean
    | {
        codec_type?: AudioCodecType,
        bit_rate?: RangedInt<6, 510>,
        opus_params?: {
            channels?: Int;
            clock_rate?: Int;
            maxplaybackrate?: Int;
            minptime?: Int;
            ptime?: Int;
            stereo?: boolean;
            sprop_stereo?: boolean;
            useinbandfec?: boolean;
            usedtx?: boolean;
        }
      }

type AudioCodecType = "OPUS"

// 映像
type Video =
    | boolean
    | {
        codec_type?: VideoCodecType,
        bit_rate?: RangedInt<1, 50000>,
      }

type VideoCodecType = "VP9" | "VP8" | "AV1" | "H264" | "H265"

// type: "offer"
type Offer = {
    type: "offer",
    sdp: string,
    client_id: ID,
    connection_id: ID,
    metadata?: JSON,
    config?: JSON,
    encodings?: Encoding[],
}

type Encoding = {
    rid?: string,
    maxBitrate?: Int,
    maxFramerate?: Double,
    scaleResolutionDownBy?: Double
}

// type: "answer"
type Answer = {
    type: "answer",
    sdp: string
}

// type: "candidate"
type Candidate = {
    type: "candidate",
    candidate: string
}

// type: "update"
// サーバーからクライアントに送信される
type UpdateToClient = {
    type: "update",
    sdp: string,
    encodings?: Encoding[]
}

// type: "update"
// クライアントからサーバーに送信される
type UpdateToServer = {
    type: "update",
    sdp: string,
    encodings?: Encoding[]
}

// type: "push"
type Push = {
    type: "push",
    data: object
}

// type: "notify"
type Notify =
    | ConnectionCreated
    | ConnectionUpdated
    | ConnectionDestroyed
    | SpotlightChanged
    | SpotlightFocused
    | SpotlightUnfocused
    | NetworkStatus

// キーは Base32-UUIDv4
type ClientMetadata = { [key: string]: JSON }

// "connection.created",
type ConnectionCreated = {
    type: "notify",
    event_type: "connection.created",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: JSON,
    metadata_list?: ClientMetadata[],
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int,
    turn_transport_type: "udp" | "tcp"
}

// "connection.updated"
type ConnectionUpdated = {
    type: "notify",
    event_type: "connection.updated",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int,
    turn_transport_type: "udp" | "tcp"
}

// "connection.destroyed"
type ConnectionDestroyed = {
    type: "notify",
    event_type: "connection.destroyed",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int,
    turn_transport_type: "udp" | "tcp"
}

// "spotlight.changed"
type SpotlightChanged = {
    type: "notify",
    event_type: "spotlight.changed",
    client_id: ID | null,
    connection_id: ID | null,
    spotlight_id: ID,
    fixed?: boolean,
    audio: boolean,
    video: boolean
}

// "spotlight.focused"
type SpotlightFocused = {
    type: "notify",
    event_type: "spotlight.focused"
    client_id: ID | null,
    connection_id: ID,
    audio: boolean,
    video: boolean,
    fixed: boolean
}

// "spotlight.unfocused"
type SpotlightUnfocused = {
    type: "notify",
    event_type: "spotlight.unfocused",
    client_id: ID | null,
    connection_id: ID,
    audio: boolean,
    video: boolean,
    fixed: boolean
}


// "network.status"
type NetworkStatus = {
    type: "notify",
    event_type: "network.status",
    unstable_level: RangedInt<0, 3>
}

// type: "disconnect"
type Disconnect = {
    type: "disconnect"
}