シグナリングの型定義¶
この章ではシグナリングの型について説明します。 シグナリングの仕様については シグナリング を参照ください。
型の表記は TypeScript で記述します。
基本的なデータ型¶
// JSON 値を表します。
// 仕様は RFC 8259 に従います。
type JSONValue =
| null
| boolean
| number
| string
| JSONValue[]
| { [key: string]: JSONValue | undefined };
// UnixTime
// 例: 1704067199
type UnixTime = number;
// RFC3339 UTC (マイクロ秒)
// 例: 2023-12-31T23:59:59.999999Z
type Timestamp = string;
// ストリームの種別
type Role = "sendrecv" | "sendonly" | "recvonly";
// サイマルキャストで視聴する映像の種類
type SimulcastRid = "r0" | "r1" | "r2";
// 音声の設定
type Audio =
| boolean
| {
codec_type?: AudioCodecType;
bit_rate?: number;
opus_params?: OpusParams;
};
type OpusParams = {
channels?: number;
maxplaybackrate?: number;
minptime?: number;
ptime?: number;
stereo?: boolean;
sprop_stereo?: boolean;
useinbandfec?: boolean;
usedtx?: boolean;
};
// 映像の設定
type Video =
| boolean
| {
codec_type?: VideoCodecType;
bit_rate?: number;
// 利用するには sora.conf で signaling_vp9_params = true を設定する必要があります
vp9_params?: VP9Params;
// 利用するには sora.conf で signaling_av1_params = true を設定する必要があります
av1_params?: AV1Params;
// 利用するには sora.conf で signaling_h264_params = true を設定する必要があります
h264_params?: H264Params;
// 利用するには sora.conf で signaling_h265_params = true を設定する必要があります
h265_params?: H265Params;
};
type VP9Params = {
// 0..3
profile_id?: number;
};
type AV1Params = {
// 0..2
profile?: number;
};
type H264Params = {
profile_level_id?: string;
// sora.conf で h264_b_frame = true を設定する必要があります
b_frame?: boolean;
};
type H265Params = {
level_id?: number;
// sora.conf で h265_b_frame = true を設定する必要があります
b_frame?: boolean;
};
// 音声コーデックの種類
type AudioCodecType = "OPUS";
// 映像コーデックの種類
type VideoCodecType = "VP9" | "VP8" | "AV1" | "H264" | "H265";
// DataChannel の方向
type Direction = "sendrecv" | "sendonly" | "recvonly";
type DataChannelMessagingHeaderFieldType = "sender_connection_id";
type DataChannelMessagingHeaderField = {
type: DataChannelMessagingHeaderFieldType;
// * length は "type": "offer" 時の data_channels にのみ含まれる
// * length は"type": "connect" 時には指定できない
// * length は認証成功時の払い出し時には指定できない
length?: number;
};
// DataChannels
type DataChannel = {
label: string;
direction: Direction;
ordered?: boolean;
max_packet_life_time?: number;
max_retransmits?: number;
protocol?: string;
compress?: boolean;
header?: DataChannelMessagingHeaderField[];
};
type ForwardingFilterRuleField = "connection_id" | "client_id" | "kind";
type ForwardingFilterRuleOperator = "is_in" | "is_not_in";
type ForwardingFilterRuleKindValue = "audio" | "video";
type ForwardingFilterRule = {
field: ForwardingFilterRuleField;
operator: ForwardingFilterRuleOperator;
values: [string];
};
type ForwardingFilterAction = "block" | "allow";
type ForwardingFilter = {
version?: string;
metadata?: JSONValue;
name?: string;
priority?: number;
action?: ForwardingFilterAction;
rules: [[ForwardingFilterRule]];
};
type SoraClientType =
| "Sora JavaScript SDK"
| "Sora iOS SDK"
| "Sora Android SDK"
| "Sora Unity SDK"
| "Sora C++ SDK"
| "Sora Python SDK"
| "Sora C SDK"
| "OBS-Studio-WHIP"
| "OBS-Studio-WHEP";
// SoraClient
type SoraClient = {
environment?: string;
raw?: string;
type?: SoraClientType;
version?: string;
commit_short?: string;
libwebrtc?: string;
};
// RTCRtpCodecParameters
// https://www.w3.org/TR/webrtc/#dom-rtcrtpcodecparameters
type SimulcastCodec = {
// payloadType や channels は省略
mimeType: string;
clockRate: number;
sdpFmtpLine?: string;
};
// RTCRtpEncodingParameters
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpencodingparameters
type SimulcastEncoding = {
// https://www.w3.org/TR/webrtc/#dom-rtcrtpcodingparameters-rid
rid: SimulcastRid;
// https://www.w3.org/TR/webrtc/#dom-rtcrtpencodingparameters-active
active?: boolean;
// https://www.w3.org/TR/webrtc/#dom-rtcrtpencodingparameters-maxframerate
maxFramerate?: number;
// https://www.w3.org/TR/webrtc/#dom-rtcrtpencodingparameters-maxbitrate
maxBitrate?: number;
// https://www.w3.org/TR/webrtc/#dom-rtcrtpencodingparameters-scaleresolutiondownby
scaleResolutionDownBy?: number;
// https://www.w3.org/TR/webrtc/#dom-rtcrtpcodec
codec?: SimulcastCodec;
// https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-scaleresolutiondownto
scaleResolutionDownTo?: number;
// https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime
adaptivePtime?: boolean;
// https://www.w3.org/TR/webrtc-svc/#dom-rtcrtpencodingparameters-scalabilitymode
scalabilityMode?: string;
};
シグナリング¶
シグナリングは「クライアントからサーバー (Sora) に送信される」メッセージと「サーバー (Sora) からクライアントに送信される」メッセージに分かれます。
クライアントからサーバーに送信されるメッセージ¶
connect
answer
candidate
re-answer
pong
WebSocket 経路利用時のみ
disconnect
stats
DataChannel 経路利用時のみ
Server からクライアントに送信されるメッセージ¶
offer
re-offer
ping
WebSocket 経路利用時のみ
push
notify
req-stats
DataChannel 経路利用時のみ
完全な型定義¶
// シグナリング
type Signaling = ClientToServer | ServerToClient;
// クライアントからサーバーに送信されるメッセージ
type ClientToServer =
| SignalingConnectMessage
| SignalingAnswerMessage
| SignalingCandidateMessage
| SignalingReAnswerToServerMessage
| SignalingPongMessage
| SignalingDisconnectMessage;
// サーバーからクライアントに送信されるメッセージ
type ServerToClient =
| SignalingRedirectMessage
| SignalingOfferMessage
| SignalingReOfferToClientMessage
| SignalingPingMessage
| SignalingPushMessage
| SignalingNotifyMessage
| SignalingSwitchedMessage
| SignalingCloseMessage;
// type: "connect"
type SignalingConnectMessage = {
type: "connect";
role: Role;
channel_id: string;
client_id?: string;
bundle_id?: string;
audio?: Audio;
video?: Video;
// 未指定の場合は false として扱われます
multistream?: boolean;
simulcast?: boolean;
simulcast_rid?: SimulcastRid;
// sora.conf にて simulcast_multicodec = true を有効にする必要があります
simulcast_multicodec?: boolean;
spotlight?: boolean;
// 非推奨です
// session.created の戻り値をご利用ください
spotlight_number?: number;
spotlight_focus_rid?: SimulcastRid | "none";
spotlight_unfocus_rid?: SimulcastRid | "none";
metadata?: JSONValue;
signaling_notify_metadata?: JSONValue;
data_channel_signaling?: boolean;
data_channels?: DataChannel[];
ignore_disconnect_websocket?: boolean;
forwarding_filters?: ForwardingFilter;
// 2025 年 12 月リリースの Sora にて廃止します
forwarding_filter?: ForwardingFilter;
// type: redirect で戻されて再度 type: connect で接続するときに有効にする必要があります
redirect?: boolean;
audio_streaming_language_code?: string;
sdp?: string;
sora_client?: string;
environment?: string;
libwebrtc?: string;
};
type Mid = {
audio?: string;
video?: string;
};
// type: "redirect"
type SignalingRedirectMessage = {
type: "redirect";
location: string;
};
// type: "offer"
type SignalingOfferMessage = {
type: "offer";
sdp: string;
mid: Mid;
version: string;
multistream: boolean;
simulcast: boolean;
simulcast_multicodec: boolean;
spotlight: boolean;
channel_id: string;
session_id: string;
client_id: string;
bundle_id: string;
connection_id: string;
audio: boolean;
audio_codec_type?: AudioCodecType;
audio_bit_rate?: number;
video: boolean;
video_codec_type?: VideoCodecType;
video_bit_rate?: number;
metadata?: JSONValue;
config?: JSONValue;
encodings?: SimulcastEncoding[];
data_channels?: DataChannel[];
};
// type: "answer"
type SignalingAnswerMessage = {
type: "answer";
sdp: string;
};
// type: "candidate"
type SignalingCandidateMessage = {
type: "candidate";
candidate: string;
};
// type: "re-offer"
// サーバーからクライアントに送信される
type SignalingReOfferToClientMessage = {
type: "re-offer";
sdp: string;
};
// type: "re-answer"
// クライアントからサーバーに送信される
type SignalingReAnswerToServerMessage = {
type: "re-answer";
sdp: string;
};
// type: "close"
// サーバーからクライアントに送信されるメッセージ
// サーバー側からの切断を通知するためのメッセージ
// data_channel_signaling = true かつ ignore_disconnect_websocket = true の場合のみ
// sora.conf にて data_channel_signaling_close_message = true を有効にする必要がある
type SignalingCloseMessage = {
type: "close";
reason: string;
code: number;
};
// type: "ping"
type SignalingPingMessage = {
type: "ping";
stats?: boolean;
};
// type: "pong"
type SignalingPongMessage = {
type: "pong";
stats?: RTCStatsReport[];
};
// type: "push"
type SignalingPushMessage = {
type: "push";
data: Record<string, unknown>;
};
// type: "notify"
type SignalingNotifyMessage =
| SignalingNotifyConnectionCreated
| SignalingNotifyConnectionUpdated
| SignalingNotifyConnectionDestroyed
| SignalingNotifySpotlightFocused
| SignalingNotifySpotlightUnfocused
| SignalingNotifyRecordingStarted
| SignalingNotifyRecordingStopped
| SignalingNotifyForwardingBlocked
| SignalingNotifyForwardingAllowed
| SignalingNotifyNetworkStatus
| SignalingNotifyRtpStreamPause
| SignalingNotifyRtpStreamResume;
// 接続中のクライアントの情報
type SignalingNotifyMetadata = {
client_id?: string;
bundle_id?: string;
connection_id?: string;
authn_metadata?: JSONValue;
authz_metadata?: JSONValue;
metadata?: JSONValue;
};
// "connection.created",
type SignalingNotifyConnectionCreated = {
type: "notify";
event_type: "connection.created";
role: Role;
session_id?: string;
client_id?: string;
bundle_id?: string;
connection_id?: string;
audio?: boolean;
video?: boolean;
authn_metadata?: JSONValue;
authz_metadata?: JSONValue;
metadata?: JSONValue;
data?: SignalingNotifyMetadata[];
minutes: number;
channel_connections: number;
channel_sendrecv_connections: number;
channel_sendonly_connections: number;
channel_recvonly_connections: number;
turn_transport_type: "udp" | "tcp";
};
// "connection.updated"
type SignalingNotifyConnectionUpdated = {
type: "notify";
event_type: "connection.updated";
role: Role;
session_id?: string;
client_id?: string;
bundle_id?: string;
connection_id?: string;
audio?: boolean;
video?: boolean;
authn_metadata?: JSONValue;
authz_metadata?: JSONValue;
metadata?: JSONValue;
minutes: number;
channel_connections: number;
channel_sendrecv_connections: number;
channel_sendonly_connections: number;
channel_recvonly_connections: number;
turn_transport_type: "udp" | "tcp";
};
// "connection.destroyed"
type SignalingNotifyConnectionDestroyed = {
type: "notify";
event_type: "connection.destroyed";
role: Role;
session_id?: string;
client_id?: string;
bundle_id?: string;
connection_id?: string;
audio?: boolean;
video?: boolean;
minutes: number;
authn_metadata?: JSONValue;
authz_metadata?: JSONValue;
metadata?: JSONValue;
channel_connections: number;
channel_sendrecv_connections: number;
channel_sendonly_connections: number;
channel_recvonly_connections: number;
turn_transport_type: "udp" | "tcp";
};
// "spotlight.focused"
type SignalingNotifySpotlightFocused = {
type: "notify";
event_type: "spotlight.focused";
client_id: string | null;
bundle_id: string | null;
connection_id: string;
audio: boolean;
video: boolean;
fixed: boolean;
};
// "spotlight.unfocused"
type SignalingNotifySpotlightUnfocused = {
type: "notify";
event_type: "spotlight.unfocused";
client_id: string | null;
bundle_id: string | null;
connection_id: string;
audio: boolean;
video: boolean;
fixed: boolean;
};
// "recording.started"
type SignalingNotifyRecordingStarted = {
type: "notify";
event_type: "recording.started";
client_id: string | null;
bundle_id: string | null;
connection_id: string;
};
// "recording.stopped"
type SignalingNotifyRecordingStopped = {
type: "notify";
event_type: "recording.stopped";
client_id: string | null;
bundle_id: string | null;
connection_id: string;
};
// "forwarding.blocked"
type SignalingNotifyForwardingBlocked = {
type: "notify";
event_type: "forwarding.blocked";
kind: ForwardingFilterRuleKindValue;
destination_connection_id: string;
source_connection_id: string;
};
// "forwarding.allowed"
type SignalingNotifyForwardingAllowed = {
type: "notify";
event_type: "forwarding.allowed";
kind: ForwardingFilterRuleKindValue;
destination_connection_id: string;
source_connection_id: string;
};
// "network.status"
type SignalingNotifyNetworkStatus = {
type: "notify";
event_type: "network.status";
unstable_level: 0 | 1 | 2 | 3;
};
// "rtp_stream.pause"
type SignalingNotifyRtpStreamPause = {
type: "notify";
event_type: "rtp_stream.pause";
recv_connection_id: string;
send_connection_id: string;
};
// "rtp_stream.pause"
type SignalingNotifyRtpStreamResume = {
type: "notify";
event_type: "rtp_stream.resume";
stream_id: string;
};
// type: "disconnect"
type SignalingDisconnectMessage = {
type: "disconnect";
reason: string;
};
// type: "stats"
// サーバーからクライアントに送信される
type DataChannelStatsToClientMessage = {
type: "stats";
};
// type: "stats"
// クライアントからサーバーに送信される
type DataChannelStatsToServerMessage = {
type: "stats";
reports: RTCStatsReport[];
};
// type: "switched"
type SignalingSwitchedMessage = {
type: "switched";
ignore_disconnect_websocket: boolean;
};