Skip to content

Commit

Permalink
sumomo にビデオデバイスとオーディオデバイスを設定するオプションを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
melpon committed Jan 11, 2025
1 parent 5971ae5 commit 23fbfb5
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 39 deletions.
71 changes: 36 additions & 35 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -1,40 +1,5 @@
{
"configurations": [
{
"name": "ubuntu-20.04_x86_64 Release",
"includePath": [
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/boost/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/webrtc/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/webrtc/include/third_party/abseil-cpp",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/webrtc/include/third_party/boringssl/src/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/webrtc/include/third_party/libyuv/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/webrtc/include/third_party/zlib",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/llvm/libcxx/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/openh264/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/vpl/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/blend2d/include",
"${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/catch2/include",
"${workspaceFolder}/_build/ubuntu-20.04_x86_64/release/sora",
"${workspaceFolder}/third_party/NvCodec/include",
"${workspaceFolder}/third_party/NvCodec/NvCodec",
"${workspaceFolder}/include",
"/usr/local/cuda/include"
],
"defines": [
"WEBRTC_POSIX",
"_LIBCPP_ABI_UNSTABLE",
"_LIBCPP_DISABLE_AVAILABILITY",
"OPENSSL_IS_BORINGSSL",
"SORA_CPP_SDK_UBUNTU_2004",
"USE_NVCODEC_ENCODER",
"RTC_ENABLE_H265"
],
"compilerPath": "${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/llvm/clang/bin/clang++",
"compilerArgs": ["-nostdinc++"],
"cStandard": "gnu17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-clang-x64"
},
{
"name": "ubuntu-20.04_armv8_jetson Release",
"includePath": [
Expand Down Expand Up @@ -104,6 +69,42 @@
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-clang-x64"
},
{
"name": "ubuntu-24.04_x86_64 Release",
"includePath": [
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/boost/include",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/webrtc/include",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/webrtc/include/third_party/abseil-cpp",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/webrtc/include/third_party/boringssl/src/include",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/webrtc/include/third_party/libyuv/include",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/webrtc/include/third_party/zlib",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/llvm/libcxx/include",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/openh264/include",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/vpl/include",
"${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/blend2d/include",
"${workspaceFolder}/_build/ubuntu-24.04_x86_64/release/sora",
"${workspaceFolder}/third_party/NvCodec/include",
"${workspaceFolder}/third_party/NvCodec/NvCodec",
"${workspaceFolder}/include",
"/usr/local/cuda/include"
],
"defines": [
"WEBRTC_POSIX",
"_LIBCPP_ABI_UNSTABLE",
"_LIBCPP_DISABLE_AVAILABILITY",
"OPENSSL_IS_BORINGSSL",
"SORA_CPP_SDK_UBUNTU_2204",
"USE_NVCODEC_ENCODER",
"USE_VPL_ENCODER",
"RTC_ENABLE_H265"
],
// "compilerPath": "${workspaceFolder}/_install/ubuntu-24.04_x86_64/release/llvm/clang/bin/clang++",
"compilerPath": "/usr/bin/clang++-18",
"compilerArgs": ["-nostdinc++"],
"cStandard": "gnu17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-clang-x64"
},
{
"name": "android Release",
"includePath": [
Expand Down
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@
- @melpon
- [ADD] scaleResolutionDownTo に対応する
- @melpon
- [ADD] SoraClientContext にオーディオデバイスの設定するオプションを追加
- @melpon
- [ADD] sumomo にビデオデバイスとオーディオデバイスを設定するオプションを追加
- @melpon
- [FIX] HTTP Proxy 利用時の Websocket 初期化で insecure_ メンバ変数が初期化されていなかったのを修正
- @melpon
- [FIX] SoraSignalingConfig の client_cert と client_key に渡す必要がある値を、ファイルパスからファイルの内容に修正
Expand Down
24 changes: 21 additions & 3 deletions examples/sumomo/src/sumomo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct SumomoConfig {
std::string client_id;
bool video = true;
bool audio = true;
std::string video_device;
std::string video_codec_type;
std::string audio_codec_type;
std::string resolution = "VGA";
Expand Down Expand Up @@ -108,6 +109,7 @@ class Sumomo : public std::enable_shared_from_this<Sumomo>,
cam_config.height = size.height;
cam_config.fps = 30;
cam_config.use_native = config_.hw_mjpeg_decoder;
cam_config.device_name = config_.video_device;
auto video_source = sora::CreateCameraDeviceCapturer(cam_config);
if (video_source == nullptr) {
RTC_LOG(LS_ERROR) << "Failed to create video source.";
Expand Down Expand Up @@ -381,6 +383,7 @@ int main(int argc, char* argv[]) {
app.add_option("--client-id", config.client_id, "Client ID");
app.add_option("--video", config.video, "Send video to sora (default: true)");
app.add_option("--audio", config.audio, "Send audio to sora (default: true)");
app.add_option("--video-device", config.video_device, "Video device name");
app.add_option("--video-codec-type", config.video_codec_type,
"Video codec for send")
->check(CLI::IsMember({"", "VP8", "VP9", "AV1", "H264", "H265"}));
Expand Down Expand Up @@ -436,11 +439,20 @@ int main(int argc, char* argv[]) {

// 証明書に関するオプション
app.add_flag("--insecure", config.insecure, "Allow insecure connection");
app.add_option("--client-cert", config.client_cert, "Client certificate file")->check(CLI::ExistingFile);
app.add_option("--client-key", config.client_key, "Client key file")->check(CLI::ExistingFile);
app.add_option("--ca-cert", config.ca_cert, "CA certificate file")->check(CLI::ExistingFile);
app.add_option("--client-cert", config.client_cert, "Client certificate file")
->check(CLI::ExistingFile);
app.add_option("--client-key", config.client_key, "Client key file")
->check(CLI::ExistingFile);
app.add_option("--ca-cert", config.ca_cert, "CA certificate file")
->check(CLI::ExistingFile);

// SoraClientContextConfig に関するオプション
std::string audio_recording_device;
app.add_option("--audio-recording-device", audio_recording_device,
"Recording device name");
std::string audio_playout_device;
app.add_option("--audio-playout-device", audio_playout_device,
"Playout device name");
std::optional<bool> use_hardware_encoder;
add_optional_bool(app, "--use-hardware-encoder", use_hardware_encoder,
"Use hardware encoder");
Expand Down Expand Up @@ -473,6 +485,12 @@ int main(int argc, char* argv[]) {
}

auto context_config = sora::SoraClientContextConfig();
if (!audio_recording_device.empty()) {
context_config.audio_recording_device = audio_recording_device;
}
if (!audio_playout_device.empty()) {
context_config.audio_playout_device = audio_playout_device;
}
if (use_hardware_encoder != std::nullopt) {
context_config.use_hardware_encoder = *use_hardware_encoder;
}
Expand Down
4 changes: 4 additions & 0 deletions include/sora/sora_client_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ struct SoraClientContextConfig {
// オーディオデバイスを利用するかどうか
// false にすると一切オーディオデバイスを掴まなくなる
bool use_audio_device = true;
// 録音デバイス名
std::optional<std::string> audio_recording_device;
// 再生デバイス名
std::optional<std::string> audio_playout_device;
// ハードウェアエンコーダ/デコーダを利用するかどうか
// false にするとソフトウェアエンコーダ/デコーダのみになる(H.264 は利用できない)
bool use_hardware_encoder = true;
Expand Down
123 changes: 122 additions & 1 deletion src/sora_client_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ std::shared_ptr<SoraClientContext> SoraClientContext::Create(

void* env = sora::GetJNIEnv();

dependencies.adm = c->worker_thread_->BlockingCall([&] {
auto adm = c->worker_thread_->BlockingCall([&] {
sora::AudioDeviceModuleConfig config;
if (!c->config_.use_audio_device) {
config.audio_layer = webrtc::AudioDeviceModule::kDummyAudio;
Expand All @@ -78,6 +78,7 @@ std::shared_ptr<SoraClientContext> SoraClientContext::Create(
}
return sora::CreateAudioDeviceModule(config);
});
dependencies.adm = adm;

dependencies.audio_encoder_factory =
webrtc::CreateBuiltinAudioEncoderFactory();
Expand Down Expand Up @@ -133,6 +134,126 @@ std::shared_ptr<SoraClientContext> SoraClientContext::Create(
factory_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
c->factory_->SetOptions(factory_options);

// オーディオデバイス名を列挙して名前を覚える
std::vector<std::tuple<std::string, std::string>> recording_devices;
std::vector<std::tuple<std::string, std::string>> playout_devices;
{
int recording_device_count = adm->RecordingDevices();
recording_devices.resize(recording_device_count);
for (int i = 0; i < recording_device_count; i++) {
char name[webrtc::kAdmMaxDeviceNameSize];
char guid[webrtc::kAdmMaxGuidSize];
if (adm->SetRecordingDevice(i) != 0) {
RTC_LOG(LS_WARNING) << "Failed to SetRecordingDevice: index=" << i;
continue;
}
bool available = false;
if (adm->RecordingIsAvailable(&available) != 0) {
RTC_LOG(LS_WARNING) << "Failed to RecordingIsAvailable: index=" << i;
continue;
}

if (!available) {
continue;
}
if (adm->RecordingDeviceName(i, name, guid) != 0) {
RTC_LOG(LS_WARNING) << "Failed to RecordingDeviceName: index=" << i;
continue;
}
RTC_LOG(LS_INFO) << "RecordingDevice: index=" << i << " name=" << name
<< " guid=" << guid;
std::get<0>(recording_devices[i]) = name;
std::get<1>(recording_devices[i]) = guid;
}
adm->SetRecordingDevice(0);

int playout_device_count = adm->PlayoutDevices();
playout_devices.resize(playout_device_count);
for (int i = 0; i < playout_device_count; i++) {
char name[webrtc::kAdmMaxDeviceNameSize];
char guid[webrtc::kAdmMaxGuidSize];
if (adm->SetPlayoutDevice(i) != 0) {
RTC_LOG(LS_WARNING) << "Failed to SetPlayoutDevice: index=" << i;
continue;
}
bool available = false;
if (adm->PlayoutIsAvailable(&available) != 0) {
RTC_LOG(LS_WARNING) << "Failed to PlayoutIsAvailable: index=" << i;
continue;
}

if (!available) {
continue;
}
if (adm->PlayoutDeviceName(i, name, guid) != 0) {
RTC_LOG(LS_WARNING) << "Failed to PlayoutDeviceName: index=" << i;
continue;
}
RTC_LOG(LS_INFO) << "PlayoutDevice: index=" << i << " name=" << name
<< " guid=" << guid;
std::get<0>(playout_devices[i]) = name;
std::get<1>(playout_devices[i]) = guid;
}
adm->SetPlayoutDevice(0);
}

// オーディオデバイスを設定する
if (c->config_.audio_recording_device) {
int index = -1;
for (int i = 0; i < recording_devices.size(); i++) {
const auto& name = std::get<0>(recording_devices[i]);
const auto& guid = std::get<1>(recording_devices[i]);
if (*c->config_.audio_recording_device == name ||
*c->config_.audio_recording_device == guid) {
index = i;
break;
}
}
if (index == -1) {
RTC_LOG(LS_ERROR) << "No recording device found: name="
<< *c->config_.audio_recording_device;
return nullptr;
}

const auto& name = std::get<0>(recording_devices[index]);
const auto& guid = std::get<1>(recording_devices[index]);
if (adm->SetRecordingDevice(index) == 0) {
RTC_LOG(LS_INFO) << "Succeeded SetRecordingDevice: index=" << index
<< " name=" << name << " name=" << guid;
} else {
RTC_LOG(LS_ERROR) << "Failed to SetRecordingDevice: index=" << index
<< " name=" << name << " guid=" << guid;
}
}

if (c->config_.audio_playout_device) {
int index = -1;
for (int i = 0; i < playout_devices.size(); i++) {
const auto& name = std::get<0>(playout_devices[i]);
const auto& guid = std::get<1>(playout_devices[i]);
if (*c->config_.audio_playout_device == name ||
*c->config_.audio_playout_device == guid) {
index = i;
break;
}
}
if (index == -1) {
RTC_LOG(LS_ERROR) << "No playout device found: name="
<< *c->config_.audio_playout_device;
return nullptr;
}

const auto& name = std::get<0>(playout_devices[index]);
const auto& guid = std::get<1>(playout_devices[index]);
if (adm->SetPlayoutDevice(index) == 0) {
RTC_LOG(LS_INFO) << "Succeeded SetPlayoutDevice: index=" << index
<< " name=" << name << " guid=" << guid;
} else {
RTC_LOG(LS_ERROR) << "Failed to SetPlayoutDevice: index=" << index
<< " name=" << name << " guid=" << guid;
}
}

return c;
}

Expand Down

0 comments on commit 23fbfb5

Please sign in to comment.