diff --git a/webrtc-jni/src/main/cpp/include/JNI_MediaDevices.h b/webrtc-jni/src/main/cpp/include/JNI_MediaDevices.h index 60f48ea..fb7d0ed 100644 --- a/webrtc-jni/src/main/cpp/include/JNI_MediaDevices.h +++ b/webrtc-jni/src/main/cpp/include/JNI_MediaDevices.h @@ -13,7 +13,7 @@ extern "C" { * Signature: (Ldev/onvoid/webrtc/media/DeviceChangeListener;)V */ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_addDeviceChangeListener - (JNIEnv *, jclass, jobject); + (JNIEnv*, jclass, jobject); /* * Class: dev_onvoid_webrtc_media_MediaDevices @@ -21,7 +21,23 @@ extern "C" { * Signature: (Ldev/onvoid/webrtc/media/DeviceChangeListener;)V */ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_removeDeviceChangeListener - (JNIEnv *, jclass, jobject); + (JNIEnv*, jclass, jobject); + + /* + * Class: dev_onvoid_webrtc_media_MediaDevices + * Method: getDefaultAudioRenderDevice + * Signature: ()Ldev/onvoid/webrtc/media/audio/AudioDevice; + */ + JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getDefaultAudioRenderDevice + (JNIEnv*, jclass); + + /* + * Class: dev_onvoid_webrtc_media_MediaDevices + * Method: getDefaultAudioCaptureDevice + * Signature: ()Ldev/onvoid/webrtc/media/audio/AudioDevice; + */ + JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getDefaultAudioCaptureDevice + (JNIEnv*, jclass); /* * Class: dev_onvoid_webrtc_media_MediaDevices @@ -29,7 +45,7 @@ extern "C" { * Signature: ()Ljava/util/List; */ JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getAudioRenderDevices - (JNIEnv *, jclass); + (JNIEnv*, jclass); /* * Class: dev_onvoid_webrtc_media_MediaDevices @@ -37,7 +53,7 @@ extern "C" { * Signature: ()Ljava/util/List; */ JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getAudioCaptureDevices - (JNIEnv *, jclass); + (JNIEnv*, jclass); /* * Class: dev_onvoid_webrtc_media_MediaDevices @@ -45,7 +61,7 @@ extern "C" { * Signature: ()Ljava/util/List; */ JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getVideoCaptureDevices - (JNIEnv *, jclass); + (JNIEnv*, jclass); /* * Class: dev_onvoid_webrtc_media_MediaDevices @@ -53,7 +69,7 @@ extern "C" { * Signature: (Ldev/onvoid/webrtc/media/video/VideoDevice;)Ljava/util/List; */ JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getVideoCaptureCapabilities - (JNIEnv *, jclass, jobject); + (JNIEnv*, jclass, jobject); #ifdef __cplusplus } diff --git a/webrtc-jni/src/main/cpp/include/media/audio/AudioDeviceManager.h b/webrtc-jni/src/main/cpp/include/media/audio/AudioDeviceManager.h index 46983af..e2b3f5a 100644 --- a/webrtc-jni/src/main/cpp/include/media/audio/AudioDeviceManager.h +++ b/webrtc-jni/src/main/cpp/include/media/audio/AudioDeviceManager.h @@ -37,8 +37,8 @@ namespace jni AudioDeviceManager(); virtual ~AudioDeviceManager() {}; - AudioDevicePtr getDefaultAudioCaptureDevice(); - AudioDevicePtr getDefaultAudioPlaybackDevice(); + virtual AudioDevicePtr getDefaultAudioCaptureDevice(); + virtual AudioDevicePtr getDefaultAudioPlaybackDevice(); virtual std::set getAudioCaptureDevices() = 0; virtual std::set getAudioPlaybackDevices() = 0; diff --git a/webrtc-jni/src/main/cpp/include/media/audio/linux/AlsaAudioDeviceManager.h b/webrtc-jni/src/main/cpp/include/media/audio/linux/AlsaAudioDeviceManager.h deleted file mode 100644 index be56560..0000000 --- a/webrtc-jni/src/main/cpp/include/media/audio/linux/AlsaAudioDeviceManager.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2019 Alex Andres - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef JNI_WEBRTC_MEDIA_ALSA_AUDIO_DEVICE_MANAGER_H_ -#define JNI_WEBRTC_MEDIA_ALSA_AUDIO_DEVICE_MANAGER_H_ - -#include - -#include "media/audio/AudioDeviceManager.h" - -namespace jni -{ - namespace avdev - { - class AlsaAudioDeviceManager : public AudioDeviceManager - { - public: - AlsaAudioDeviceManager(); - ~AlsaAudioDeviceManager(); - - std::set getAudioCaptureDevices() override; - std::set getAudioPlaybackDevices() override; - - private: - void enumerateDevices(snd_pcm_stream_t stream); - bool insertDevice(std::shared_ptr device, snd_pcm_stream_t stream); - }; - } -} - -#endif \ No newline at end of file diff --git a/webrtc-jni/src/main/cpp/include/media/audio/linux/PulseAudioDeviceManager.h b/webrtc-jni/src/main/cpp/include/media/audio/linux/PulseAudioDeviceManager.h index 2d64d38..24ff3e1 100644 --- a/webrtc-jni/src/main/cpp/include/media/audio/linux/PulseAudioDeviceManager.h +++ b/webrtc-jni/src/main/cpp/include/media/audio/linux/PulseAudioDeviceManager.h @@ -32,8 +32,8 @@ namespace jni PulseAudioDeviceManager(); ~PulseAudioDeviceManager(); - AudioDevicePtr getDefaultAudioCaptureDevice(); - AudioDevicePtr getDefaultAudioPlaybackDevice(); + AudioDevicePtr getDefaultAudioCaptureDevice() override; + AudioDevicePtr getDefaultAudioPlaybackDevice() override; std::set getAudioCaptureDevices() override; std::set getAudioPlaybackDevices() override; @@ -47,8 +47,10 @@ namespace jni static void stateCallback(pa_context * ctx, void * userdata); static void serverInfoCallback(pa_context * ctx, const pa_server_info * info, void * userdata); static void subscribeCallback(pa_context * ctx, pa_subscription_event_type_t t, uint32_t idx, void * userdata); + static void getSourceInfoCallback(pa_context * ctx, const pa_source_info * info, int last, void * userdata); static void getSourceCallback(pa_context * ctx, const pa_source_info * info, int last, void * userdata); static void newSourceCallback(pa_context * ctx, const pa_source_info * info, int last, void * userdata); + static void getSinkInfoCallback(pa_context * ctx, const pa_sink_info * info, int last, void * userdata); static void getSinkCallback(pa_context * ctx, const pa_sink_info * info, int last, void * userdata); static void newSinkCallback(pa_context * ctx, const pa_sink_info * info, int last, void * userdata); @@ -60,7 +62,9 @@ namespace jni pa_context * context; std::string defaultCaptureName; + std::string defaultCaptureDescName; std::string defaultPlaybackName; + std::string defaultPlaybackDescName; std::unordered_map deviceMap; }; diff --git a/webrtc-jni/src/main/cpp/include/media/audio/macos/CoreAudioDeviceManager.h b/webrtc-jni/src/main/cpp/include/media/audio/macos/CoreAudioDeviceManager.h index 499fa1c..e128963 100644 --- a/webrtc-jni/src/main/cpp/include/media/audio/macos/CoreAudioDeviceManager.h +++ b/webrtc-jni/src/main/cpp/include/media/audio/macos/CoreAudioDeviceManager.h @@ -34,11 +34,15 @@ namespace jni std::set getAudioCaptureDevices() override; std::set getAudioPlaybackDevices() override; + AudioDevicePtr getDefaultAudioCaptureDevice() override; + AudioDevicePtr getDefaultAudioPlaybackDevice() override; + private: void enumerateDevices(const AudioObjectPropertyScope & scope); void onDevicesChanged(); void onDefaultDeviceChanged(const AudioObjectPropertyScope & scope, DeviceList & devices, const AudioDevicePtr & device); void checkDeviceGone(DeviceList & devices, AudioDeviceID * devIDs, const int numDevIDs, const AudioObjectPropertyScope & scope); + AudioDevicePtr createDefaultAudioDevice(const AudioObjectPropertyScope & scope); AudioDevicePtr createAudioDevice(const AudioDeviceID & deviceID, const AudioObjectPropertyScope & scope); bool insertAudioDevice(const AudioDevicePtr & device, const AudioObjectPropertyScope & scope); int getChannelCount(const AudioDeviceID & deviceID, const AudioObjectPropertyScope & scope); diff --git a/webrtc-jni/src/main/cpp/include/media/audio/windows/WindowsAudioDeviceManager.h b/webrtc-jni/src/main/cpp/include/media/audio/windows/WindowsAudioDeviceManager.h index e8da0b3..dee044d 100644 --- a/webrtc-jni/src/main/cpp/include/media/audio/windows/WindowsAudioDeviceManager.h +++ b/webrtc-jni/src/main/cpp/include/media/audio/windows/WindowsAudioDeviceManager.h @@ -36,10 +36,14 @@ namespace jni std::set getAudioCaptureDevices() override; std::set getAudioPlaybackDevices() override; + AudioDevicePtr getDefaultAudioCaptureDevice() override; + AudioDevicePtr getDefaultAudioPlaybackDevice() override; + private: void enumerateDevices(EDataFlow dataFlow); void addDevice(LPCWSTR deviceId); void removeDevice(LPCWSTR deviceId); + AudioDevicePtr createDefaultAudioDevice(const EDataFlow & dataFlow); AudioDevicePtr createAudioDevice(LPCWSTR deviceId, EDataFlow * dataFlow); bool insertAudioDevice(AudioDevicePtr device, EDataFlow dataFlow); void removeAudioDevice(DeviceList & devices, std::string id); diff --git a/webrtc-jni/src/main/cpp/src/JNI_MediaDevices.cpp b/webrtc-jni/src/main/cpp/src/JNI_MediaDevices.cpp index 5d87cae..de94de1 100644 --- a/webrtc-jni/src/main/cpp/src/JNI_MediaDevices.cpp +++ b/webrtc-jni/src/main/cpp/src/JNI_MediaDevices.cpp @@ -60,6 +60,40 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_removeDeviceCha } } +JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getDefaultAudioRenderDevice +(JNIEnv * env, jclass caller) +{ + jni::WebRTCContext * context = static_cast(javaContext); + + auto device = context->getAudioDeviceManager()->getDefaultAudioPlaybackDevice(); + + try { + return jni::AudioDevice::toJavaAudioDevice(env, device).release(); + } + catch (...) { + ThrowCxxJavaException(env); + } + + return nullptr; +} + +JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getDefaultAudioCaptureDevice +(JNIEnv * env, jclass caller) +{ + jni::WebRTCContext * context = static_cast(javaContext); + + auto device = context->getAudioDeviceManager()->getDefaultAudioCaptureDevice(); + + try { + return jni::AudioDevice::toJavaAudioDevice(env, device).release(); + } + catch (...) { + ThrowCxxJavaException(env); + } + + return nullptr; +} + JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_MediaDevices_getAudioRenderDevices (JNIEnv * env, jclass caller) { diff --git a/webrtc-jni/src/main/cpp/src/media/audio/linux/AlsaAudioDeviceManager.cpp b/webrtc-jni/src/main/cpp/src/media/audio/linux/AlsaAudioDeviceManager.cpp deleted file mode 100644 index 107782a..0000000 --- a/webrtc-jni/src/main/cpp/src/media/audio/linux/AlsaAudioDeviceManager.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2019 Alex Andres - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "media/audio/linux/AlsaAudioDeviceManager.h" - -#include "rtc_base/logging.h" - -#include -#include - -namespace jni -{ - namespace avdev - { - AlsaAudioDeviceManager::AlsaAudioDeviceManager() - { - getAudioCaptureDevices(); - getAudioPlaybackDevices(); - } - - AlsaAudioDeviceManager::~AlsaAudioDeviceManager() - { - } - - std::set AlsaAudioDeviceManager::getAudioCaptureDevices() { - if (captureDevices.empty()) { - enumerateDevices(SND_PCM_STREAM_CAPTURE); - } - - return captureDevices.devices(); - } - - std::set AlsaAudioDeviceManager::getAudioPlaybackDevices() { - if (playbackDevices.empty()) { - enumerateDevices(SND_PCM_STREAM_PLAYBACK); - } - - return playbackDevices.devices(); - } - - void AlsaAudioDeviceManager::enumerateDevices(snd_pcm_stream_t stream) - { - snd_ctl_t * handle; - snd_ctl_card_info_t * info; - snd_pcm_info_t * pcminfo; - snd_ctl_card_info_alloca(&info); - snd_pcm_info_alloca(&pcminfo); - - int dev; - int error; - int card = -1; - - while (snd_card_next(&card) == 0 && card > -1) { - char hwname[32]; - snprintf(hwname, sizeof(hwname), "hw:%d", card); - - if ((error = snd_ctl_open(&handle, hwname, 0)) < 0) { - RTC_LOG(LS_ERROR) << "ALSA: Control open failed (" << card << "): " << snd_strerror(error); - continue; - } - if ((error = snd_ctl_card_info(handle, info)) < 0) { - RTC_LOG(LS_ERROR) << "ALSA: Get card related information failed (" << card << "): " << snd_strerror(error); - snd_ctl_close(handle); - - continue; - } - - dev = -1; - - while (1) { - if ((error = snd_ctl_pcm_next_device(handle, &dev)) < 0) { - RTC_LOG(LS_ERROR) << "ALSA: Get next PCM device number failed (" << card << "): " << snd_strerror(error); - } - if (dev < 0) { - break; - } - - snd_pcm_info_set_device(pcminfo, dev); - snd_pcm_info_set_subdevice(pcminfo, 0); - snd_pcm_info_set_stream(pcminfo, stream); - - if ((error = snd_ctl_pcm_info(handle, pcminfo)) < 0) { - if (error != -ENOENT) { - RTC_LOG(LS_ERROR) << "ALSA: Get PCM device info failed (" << card << "): " << snd_strerror(error); - } - continue; - } - - std::ostringstream idStream; - idStream << "plughw:" << card << "," << dev; - - std::ostringstream nameStream; - nameStream << snd_ctl_card_info_get_name(info) << " [" << snd_pcm_info_get_name(pcminfo) << "]"; - - std::string id = idStream.str(); - std::string name = nameStream.str(); - AudioDevicePtr device = nullptr; - - if (stream == SND_PCM_STREAM_CAPTURE) { - device = std::make_shared(name, id); - } - else if (stream == SND_PCM_STREAM_PLAYBACK) { - device = std::make_shared(name, id); - } - - insertDevice(device, stream); - } - snd_ctl_close(handle); - } - } - - bool AlsaAudioDeviceManager::insertDevice(AudioDevicePtr device, snd_pcm_stream_t stream) - { - if (device == nullptr) { - return false; - } - - if (stream == SND_PCM_STREAM_CAPTURE) { - captureDevices.insertDevice(device); - return true; - } - else if (stream == SND_PCM_STREAM_PLAYBACK) { - playbackDevices.insertDevice(device); - return true; - } - - return false; - } - } -} \ No newline at end of file diff --git a/webrtc-jni/src/main/cpp/src/media/audio/linux/PulseAudioDeviceManager.cpp b/webrtc-jni/src/main/cpp/src/media/audio/linux/PulseAudioDeviceManager.cpp index 123acf5..60a0654 100644 --- a/webrtc-jni/src/main/cpp/src/media/audio/linux/PulseAudioDeviceManager.cpp +++ b/webrtc-jni/src/main/cpp/src/media/audio/linux/PulseAudioDeviceManager.cpp @@ -123,31 +123,23 @@ namespace jni AudioDevicePtr PulseAudioDeviceManager::getDefaultAudioCaptureDevice() { - if (defaultCaptureName.empty()) { - if (!pa_threaded_mainloop_in_thread(mainloop)) - pa_threaded_mainloop_lock(mainloop); + if (!pa_threaded_mainloop_in_thread(mainloop)) + pa_threaded_mainloop_lock(mainloop); - pa_operation * op = pa_context_get_server_info(context, serverInfoCallback, this); + pa_operation * op = pa_context_get_server_info(context, serverInfoCallback, this); - if (!pa_threaded_mainloop_in_thread(mainloop)) - iterate(mainloop, op); + if (!pa_threaded_mainloop_in_thread(mainloop)) + iterate(mainloop, op); - if (!pa_threaded_mainloop_in_thread(mainloop)) - pa_threaded_mainloop_unlock(mainloop); - } - - auto predicate = [this](const std::shared_ptr & dev) { - return defaultCaptureName == dev->getDescriptor(); - }; + op = pa_context_get_source_info_by_name(context, defaultCaptureName.c_str(), getSourceInfoCallback, this); - AudioDevicePtr found = captureDevices.findDevice(predicate); + if (!pa_threaded_mainloop_in_thread(mainloop)) + iterate(mainloop, op); - if (found) { - //setDefaultCaptureDevice(found); - return found; - } + if (!pa_threaded_mainloop_in_thread(mainloop)) + pa_threaded_mainloop_unlock(mainloop); - return *captureDevices.devices().begin(); + return std::make_shared(defaultCaptureDescName, defaultCaptureName); } std::set PulseAudioDeviceManager::getAudioCaptureDevices() @@ -166,31 +158,23 @@ namespace jni AudioDevicePtr PulseAudioDeviceManager::getDefaultAudioPlaybackDevice() { - if (defaultPlaybackName.empty()) { - if (!pa_threaded_mainloop_in_thread(mainloop)) - pa_threaded_mainloop_lock(mainloop); + if (!pa_threaded_mainloop_in_thread(mainloop)) + pa_threaded_mainloop_lock(mainloop); - pa_operation * op = pa_context_get_server_info(context, serverInfoCallback, this); + pa_operation * op = pa_context_get_server_info(context, serverInfoCallback, this); - if (!pa_threaded_mainloop_in_thread(mainloop)) - iterate(mainloop, op); + if (!pa_threaded_mainloop_in_thread(mainloop)) + iterate(mainloop, op); - if (!pa_threaded_mainloop_in_thread(mainloop)) - pa_threaded_mainloop_unlock(mainloop); - } + op = pa_context_get_sink_info_by_name(context, defaultPlaybackName.c_str(), getSinkInfoCallback, this); - auto predicate = [this](const std::shared_ptr & dev) { - return defaultPlaybackName == dev->getDescriptor(); - }; + if (!pa_threaded_mainloop_in_thread(mainloop)) + iterate(mainloop, op); - AudioDevicePtr found = playbackDevices.findDevice(predicate); + if (!pa_threaded_mainloop_in_thread(mainloop)) + pa_threaded_mainloop_unlock(mainloop); - if (found) { - //setDefaultCaptureDevice(found); - return found; - } - - return *playbackDevices.devices().begin(); + return std::make_shared(defaultPlaybackDescName, defaultPlaybackName); } std::set PulseAudioDeviceManager::getAudioPlaybackDevices() @@ -207,6 +191,18 @@ namespace jni return playbackDevices.devices(); } + void PulseAudioDeviceManager::getSourceInfoCallback(pa_context * ctx, const pa_source_info * info, int last, void * userdata) + { + PulseAudioDeviceManager * engine = reinterpret_cast(userdata); + + if (last > 0) { + pa_threaded_mainloop_signal(engine->mainloop, 0); + return; + } + + engine->defaultCaptureDescName = info->description; + } + void PulseAudioDeviceManager::getSourceCallback(pa_context * ctx, const pa_source_info * info, int last, void * userdata) { PulseAudioDeviceManager * engine = reinterpret_cast(userdata); @@ -216,7 +212,9 @@ namespace jni return; } - engine->insertDevice(engine->captureDevices, info->description, info->name, info->index, false); + if (info->monitor_of_sink == PA_INVALID_INDEX) { + engine->insertDevice(engine->captureDevices, info->description, info->name, info->index, false); + } } void PulseAudioDeviceManager::newSourceCallback(pa_context * ctx, const pa_source_info * info, int last, void * userdata) @@ -231,6 +229,18 @@ namespace jni engine->insertDevice(engine->captureDevices, info->description, info->name, info->index, true); } + void PulseAudioDeviceManager::getSinkInfoCallback(pa_context * ctx, const pa_sink_info * info, int last, void * userdata) + { + PulseAudioDeviceManager * engine = reinterpret_cast(userdata); + + if (last > 0) { + pa_threaded_mainloop_signal(engine->mainloop, 0); + return; + } + + engine->defaultPlaybackDescName = info->description; + } + void PulseAudioDeviceManager::getSinkCallback(pa_context * ctx, const pa_sink_info * info, int last, void * userdata) { PulseAudioDeviceManager * engine = reinterpret_cast(userdata); diff --git a/webrtc-jni/src/main/cpp/src/media/audio/macos/CoreAudioDeviceManager.cpp b/webrtc-jni/src/main/cpp/src/media/audio/macos/CoreAudioDeviceManager.cpp index 0d95253..473afeb 100644 --- a/webrtc-jni/src/main/cpp/src/media/audio/macos/CoreAudioDeviceManager.cpp +++ b/webrtc-jni/src/main/cpp/src/media/audio/macos/CoreAudioDeviceManager.cpp @@ -65,6 +65,16 @@ namespace jni return playbackDevices.devices(); } + AudioDevicePtr CoreAudioDeviceManager::getDefaultAudioCaptureDevice() + { + return createDefaultAudioDevice(kAudioObjectPropertyScopeInput); + } + + AudioDevicePtr CoreAudioDeviceManager::getDefaultAudioPlaybackDevice() + { + return createDefaultAudioDevice(kAudioObjectPropertyScopeOutput); + } + void CoreAudioDeviceManager::enumerateDevices(const AudioObjectPropertyScope & scope) { // Get all devices. AudioObjectPropertyAddress pa; @@ -256,6 +266,13 @@ namespace jni } } + AudioDevicePtr CoreAudioDeviceManager::createDefaultAudioDevice(const AudioObjectPropertyScope & scope) + { + AudioDeviceID defaultID = getDefaultDeviceID(scope); + + return createAudioDevice(defaultID, scope); + } + AudioDevicePtr CoreAudioDeviceManager::createAudioDevice(const AudioDeviceID & deviceID, const AudioObjectPropertyScope & scope) { AudioDevicePtr device = nullptr; CFStringRef devNameRef; diff --git a/webrtc-jni/src/main/cpp/src/media/audio/windows/WindowsAudioDeviceManager.cpp b/webrtc-jni/src/main/cpp/src/media/audio/windows/WindowsAudioDeviceManager.cpp index cbd8ac4..8e85fd6 100644 --- a/webrtc-jni/src/main/cpp/src/media/audio/windows/WindowsAudioDeviceManager.cpp +++ b/webrtc-jni/src/main/cpp/src/media/audio/windows/WindowsAudioDeviceManager.cpp @@ -36,8 +36,6 @@ namespace jni HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&deviceEnumerator); THROW_IF_FAILED(hr, "MMF: Create device enumerator failed"); - enumerateDevices(eAll); - deviceEnumerator->RegisterEndpointNotificationCallback(this); } @@ -48,6 +46,16 @@ namespace jni } } + AudioDevicePtr WindowsAudioDeviceManager::getDefaultAudioCaptureDevice() + { + return createDefaultAudioDevice(EDataFlow::eCapture); + } + + AudioDevicePtr WindowsAudioDeviceManager::getDefaultAudioPlaybackDevice() + { + return createDefaultAudioDevice(EDataFlow::eRender); + } + std::set WindowsAudioDeviceManager::getAudioCaptureDevices() { if (captureDevices.empty()) { @@ -147,6 +155,38 @@ namespace jni removeAudioDevice(playbackDevices, id); } + AudioDevicePtr WindowsAudioDeviceManager::createDefaultAudioDevice(const EDataFlow& dataFlow) + { + MFInitializer initializer; + ComPtr deviceCollection; + ComPtr defaultDevice; + ComPtr propertyStore; + LPWSTR defaultDeviceId = nullptr; + PROPVARIANT pv; + PropVariantInit(&pv); + + HRESULT hr = deviceEnumerator->GetDefaultAudioEndpoint(dataFlow, eMultimedia, &defaultDevice); + THROW_IF_FAILED(hr, "MMF: Get default audio endpoint failed"); + + hr = defaultDevice->GetId(&defaultDeviceId); + THROW_IF_FAILED(hr, "MMF: Get default device ID failed"); + + hr = defaultDevice->OpenPropertyStore(STGM_READ, &propertyStore); + THROW_IF_FAILED(hr, "MMF: Device open property store failed"); + + hr = propertyStore->GetValue(PKEY_Device_FriendlyName, &pv); + THROW_IF_FAILED(hr, "MMF: PropertyStore get friendly name failed"); + + std::string id = WideStrToStr(defaultDeviceId); + std::string name = WideStrToStr(pv.pwszVal); + + AudioDevicePtr device = std::make_shared(name, id); + + PropVariantClear(&pv); + + return device; + } + AudioDevicePtr WindowsAudioDeviceManager::createAudioDevice(LPCWSTR deviceId, EDataFlow * dataFlow) { MFInitializer initializer; diff --git a/webrtc/src/main/java/dev/onvoid/webrtc/media/MediaDevices.java b/webrtc/src/main/java/dev/onvoid/webrtc/media/MediaDevices.java index e23fd65..ce36177 100644 --- a/webrtc/src/main/java/dev/onvoid/webrtc/media/MediaDevices.java +++ b/webrtc/src/main/java/dev/onvoid/webrtc/media/MediaDevices.java @@ -39,6 +39,10 @@ public class MediaDevices { public static native void removeDeviceChangeListener(DeviceChangeListener listener); + public static native AudioDevice getDefaultAudioRenderDevice(); + + public static native AudioDevice getDefaultAudioCaptureDevice(); + public static native List getAudioRenderDevices(); public static native List getAudioCaptureDevices();