Skip to content

Commit

Permalink
Merge pull request #81 from shiguredo/feature/add-on-signaling
Browse files Browse the repository at this point in the history
on_signaling_message を追加します
  • Loading branch information
voluntas authored Sep 14, 2024
2 parents 2909823 + 09ae8c4 commit 5c75415
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

## develop

- [ADD] on_signaling_message コールバックを追加する
- @tnoho
- [UPDATE] Sora C++ SDK のバージョンを `2024.8.0` に上げる
- @torikizi
- [UPDATE] libwebrtc のバージョンを `m128.6613.2.0` に上げる
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SORA_CPP_SDK_VERSION=2024.8.0-canary.0
SORA_CPP_SDK_VERSION=2024.8.0-canary.1
WEBRTC_BUILD_VERSION=m128.6613.2.0
BOOST_VERSION=1.85.0
CMAKE_VERSION=3.29.6
Expand Down
74 changes: 74 additions & 0 deletions examples/src/media/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
SoraAudioSink,
SoraConnection,
SoraMediaTrack,
SoraSignalingDirection,
SoraSignalingErrorCode,
SoraSignalingType,
SoraVideoFrame,
SoraVideoSink,
)
Expand Down Expand Up @@ -95,6 +97,16 @@ def __init__(
self._closed: Event = Event()
self._default_connection_timeout_s: float = 10.0

# メッセージ
self._connect_message: Optional[dict[str, Any]] = None
self._redirect_message: Optional[dict[str, Any]] = None
self._offer_message: Optional[dict[str, Any]] = None
self._answer_message: Optional[dict[str, Any]] = None
self._candidate_messages: list[dict[str, Any]] = []
self._re_offer_messages: list[dict[str, Any]] = []
self._re_answer_messages: list[dict[str, Any]] = []

self._connection.on_signaling_message = self._on_signaling_message
self._connection.on_set_offer = self._on_set_offer
self._connection.on_switched = self._on_switched
self._connection.on_notify = self._on_notify
Expand Down Expand Up @@ -131,6 +143,34 @@ def get_stats(self):
raw_stats = self._connection.get_stats()
return json.loads(raw_stats)

@property
def connect_message(self) -> Optional[dict[str, Any]]:
return self._connect_message

@property
def redirect_message(self) -> Optional[dict[str, Any]]:
return self._redirect_message

@property
def offer_message(self) -> Optional[dict[str, Any]]:
return self._offer_message

@property
def answer_message(self) -> Optional[dict[str, Any]]:
return self._answer_message

@property
def candidate_messages(self) -> list[dict[str, Any]]:
return self._candidate_messages

@property
def re_offer_messages(self) -> list[dict[str, Any]]:
return self._re_offer_messages

@property
def re_answer_messages(self) -> list[dict[str, Any]]:
return self._re_answer_messages

@property
def connected(self) -> bool:
return self._connected.is_set()
Expand All @@ -149,6 +189,40 @@ def _fake_video_loop(self):
time.sleep(1.0 / 30)
self._video_source.on_captured(numpy.zeros((480, 640, 3), dtype=numpy.uint8))

def _on_signaling_message(
self,
signaling_type: SoraSignalingType,
signaling_direction: SoraSignalingDirection,
raw_message: str,
):
print(raw_message)
message: dict[str, Any] = json.loads(raw_message)
match message["type"]:
case "connect":
assert signaling_type == SoraSignalingType.WEBSOCKET
assert signaling_direction == SoraSignalingDirection.SENT
self._connect_message = message
case "redirect":
assert signaling_type == SoraSignalingType.WEBSOCKET
assert signaling_direction == SoraSignalingDirection.RECEIVED
self._redirect_message = message
case "offer":
assert signaling_type == SoraSignalingType.WEBSOCKET
assert signaling_direction == SoraSignalingDirection.RECEIVED
self._offer_message = message
case "answer":
assert signaling_type == SoraSignalingType.WEBSOCKET
assert signaling_direction == SoraSignalingDirection.SENT
self._answer_message = message
case "candidate":
self._candidate_messages.append(message)
case "re-offer":
self._re_offer_messages.append(message)
case "re-answer":
self._re_answer_messages.append(message)
case _:
NotImplementedError(f"Unknown signaling message type: {message['type']}")

def _on_set_offer(self, raw_message: str) -> None:
"""
オファー設定イベントを処理します。
Expand Down
30 changes: 30 additions & 0 deletions examples/tests/test_signaling_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import sys
import time
import uuid

from media import Sendonly


def test_signaling_message(setup):
signaling_urls = setup.get("signaling_urls")
channel_id_prefix = setup.get("channel_id_prefix")
metadata = setup.get("metadata")

channel_id = f"{channel_id_prefix}_{__name__}_{sys._getframe().f_code.co_name}_{uuid.uuid4()}"

sendonly = Sendonly(
signaling_urls,
channel_id,
audio=False,
video=True,
metadata=metadata,
)
sendonly.connect(fake_audio=True)

time.sleep(5)

assert sendonly.connect_message is not None
assert sendonly.offer_message is not None
assert sendonly.answer_message is not None

sendonly.disconnect()
11 changes: 11 additions & 0 deletions src/sora_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <chrono>
#include <stdexcept>

// WebRTC
#include <rtc_base/crypto_random.h>

// Sora C++ SDK
#include <sora/rtc_stats.h>

Expand Down Expand Up @@ -186,6 +189,14 @@ void SoraConnection::OnSwitched(std::string text) {
}
}

void SoraConnection::OnSignalingMessage(sora::SoraSignalingType type,
sora::SoraSignalingDirection direction,
std::string message) {
if (on_signaling_message_) {
on_signaling_message_(type, direction, message);
}
}

void SoraConnection::OnTrack(
rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver) {
if (on_track_) {
Expand Down
6 changes: 6 additions & 0 deletions src/sora_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,19 @@ class SoraConnection : public sora::SoraSignalingObserver,
void OnPush(std::string text) override;
void OnMessage(std::string label, std::string data) override;
void OnSwitched(std::string text) override;
void OnSignalingMessage(sora::SoraSignalingType type,
sora::SoraSignalingDirection direction,
std::string message) override;
void OnTrack(
rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver) override;
void OnRemoveTrack(
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override;
void OnDataChannel(std::string label) override;

// sora::SoraSignalingObserver のコールバック関数が呼び出された時に対応して呼び出す Python の関数を保持する
std::function<
void(sora::SoraSignalingType, sora::SoraSignalingDirection, std::string)>
on_signaling_message_;
std::function<void(std::string)> on_set_offer_;
std::function<void(sora::SoraSignalingErrorCode, std::string)> on_disconnect_;
std::function<void(std::string)> on_notify_;
Expand Down
17 changes: 17 additions & 0 deletions src/sora_sdk_ext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ int connection_tp_traverse(PyObject* self, visitproc visit, void* arg) {
Py_VISIT(on_disconnect.ptr());
}

if (conn->on_signaling_message_) {
nb::object on_disconnect =
nb::cast(conn->on_signaling_message_, nb::rv_policy::none);
Py_VISIT(on_disconnect.ptr());
}

if (conn->on_notify_) {
nb::object on_notify = nb::cast(conn->on_notify_, nb::rv_policy::none);
Py_VISIT(on_notify.ptr());
Expand Down Expand Up @@ -162,6 +168,16 @@ NB_MODULE(sora_sdk_ext, m) {
sora::SoraSignalingErrorCode::PEER_CONNECTION_STATE_FAILED)
.value("ICE_FAILED", sora::SoraSignalingErrorCode::ICE_FAILED);

nb::enum_<sora::SoraSignalingType>(m, "SoraSignalingType",
nb::is_arithmetic())
.value("WEBSOCKET", sora::SoraSignalingType::WEBSOCKET)
.value("DATACHANNEL", sora::SoraSignalingType::DATACHANNEL);

nb::enum_<sora::SoraSignalingDirection>(m, "SoraSignalingDirection",
nb::is_arithmetic())
.value("SENT", sora::SoraSignalingDirection::SENT)
.value("RECEIVED", sora::SoraSignalingDirection::RECEIVED);

nb::enum_<webrtc::MediaStreamTrackInterface::TrackState>(m, "SoraTrackState",
nb::is_arithmetic())
.value("LIVE", webrtc::MediaStreamTrackInterface::TrackState::kLive)
Expand Down Expand Up @@ -286,6 +302,7 @@ NB_MODULE(sora_sdk_ext, m) {
.def("get_stats", &SoraConnection::GetStats)
.def_rw("on_set_offer", &SoraConnection::on_set_offer_)
.def_rw("on_disconnect", &SoraConnection::on_disconnect_)
.def_rw("on_signaling_message", &SoraConnection::on_signaling_message_)
.def_rw("on_notify", &SoraConnection::on_notify_)
.def_rw("on_push", &SoraConnection::on_push_)
.def_rw("on_message", &SoraConnection::on_message_)
Expand Down
5 changes: 1 addition & 4 deletions src/sora_vad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <modules/audio_processing/agc2/agc2_common.h>
#include <modules/audio_processing/agc2/cpu_features.h>
#include <modules/audio_processing/agc2/rnn_vad/common.h>
#include <modules/audio_processing/include/audio_frame_view.h>

SoraVAD::SoraVAD() {
vad_ = std::make_unique<webrtc::VoiceActivityDetectorWrapper>(
Expand Down Expand Up @@ -36,7 +35,5 @@ float SoraVAD::Analyze(std::shared_ptr<SoraAudioFrame> frame) {
webrtc::StreamConfig(frame->sample_rate_hz(), frame->num_channels());
}
audio_buffer_->CopyFrom(frame->RawData(), vad_input_config_);
return vad_->Analyze(webrtc::AudioFrameView<const float>(
audio_buffer_->channels(), audio_buffer_->num_channels(),
audio_buffer_->num_frames()).view());
return vad_->Analyze(audio_buffer_->view());
}

0 comments on commit 5c75415

Please sign in to comment.