Allow to choose camera device in Settings.
This commit is contained in:
parent
e782e065a0
commit
aa87d627c9
|
@ -370,6 +370,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_adaptive_wide" = "Adaptive layout for wide screens";
|
"lng_settings_adaptive_wide" = "Adaptive layout for wide screens";
|
||||||
|
|
||||||
"lng_settings_section_call_settings" = "Calls Settings";
|
"lng_settings_section_call_settings" = "Calls Settings";
|
||||||
|
"lng_settings_call_camera" = "Camera";
|
||||||
"lng_settings_call_section_output" = "Speakers and headphones";
|
"lng_settings_call_section_output" = "Speakers and headphones";
|
||||||
"lng_settings_call_section_input" = "Microphone";
|
"lng_settings_call_section_input" = "Microphone";
|
||||||
"lng_settings_call_input_device" = "Input device";
|
"lng_settings_call_input_device" = "Input device";
|
||||||
|
@ -380,7 +381,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_call_stop_mic_test" = "Stop test";
|
"lng_settings_call_stop_mic_test" = "Stop test";
|
||||||
"lng_settings_call_section_other" = "Other settings";
|
"lng_settings_call_section_other" = "Other settings";
|
||||||
"lng_settings_call_open_system_prefs" = "Open system sound preferences";
|
"lng_settings_call_open_system_prefs" = "Open system sound preferences";
|
||||||
"lng_settings_call_device_default" = "Default";
|
"lng_settings_call_device_default" = "Same as the System";
|
||||||
"lng_settings_call_audio_ducking" = "Mute other sounds during calls";
|
"lng_settings_call_audio_ducking" = "Mute other sounds during calls";
|
||||||
|
|
||||||
"lng_settings_language" = "Language";
|
"lng_settings_language" = "Language";
|
||||||
|
|
|
@ -346,22 +346,35 @@ void Call::setMuted(bool mute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call::setupOutgoingVideo() {
|
void Call::setupOutgoingVideo() {
|
||||||
|
static const auto hasDevices = [] {
|
||||||
|
return !Webrtc::GetVideoInputList().empty();
|
||||||
|
};
|
||||||
const auto started = _videoOutgoing->state();
|
const auto started = _videoOutgoing->state();
|
||||||
|
if (!hasDevices()) {
|
||||||
|
_videoOutgoing->setState(Webrtc::VideoState::Inactive);
|
||||||
|
}
|
||||||
_videoOutgoing->stateValue(
|
_videoOutgoing->stateValue(
|
||||||
) | rpl::start_with_next([=](Webrtc::VideoState state) {
|
) | rpl::start_with_next([=](Webrtc::VideoState state) {
|
||||||
if (state != Webrtc::VideoState::Inactive
|
if (state != Webrtc::VideoState::Inactive && !hasDevices()) {
|
||||||
&& Webrtc::GetVideoInputList().empty()) {
|
_errors.fire({ ErrorType::NoCamera });
|
||||||
_videoOutgoing->setState(Webrtc::VideoState::Inactive);
|
_videoOutgoing->setState(Webrtc::VideoState::Inactive);
|
||||||
} else if (_state.current() != State::Established
|
} else if (_state.current() != State::Established
|
||||||
&& state != started
|
&& state != started
|
||||||
&& !_videoCapture) {
|
&& !_videoCapture) {
|
||||||
|
_errors.fire({ ErrorType::NotStartedCall });
|
||||||
_videoOutgoing->setState(started);
|
_videoOutgoing->setState(started);
|
||||||
|
} else if (state != Webrtc::VideoState::Inactive
|
||||||
|
&& _instance
|
||||||
|
&& !_instance->supportsVideo()) {
|
||||||
|
_errors.fire({ ErrorType::NotVideoCall });
|
||||||
|
_videoOutgoing->setState(Webrtc::VideoState::Inactive);
|
||||||
} else if (state != Webrtc::VideoState::Inactive) {
|
} else if (state != Webrtc::VideoState::Inactive) {
|
||||||
// Paused not supported right now.
|
// Paused not supported right now.
|
||||||
#ifndef DESKTOP_APP_DISABLE_WEBRTC_INTEGRATION
|
#ifndef DESKTOP_APP_DISABLE_WEBRTC_INTEGRATION
|
||||||
Assert(state == Webrtc::VideoState::Active);
|
Assert(state == Webrtc::VideoState::Active);
|
||||||
if (!_videoCapture) {
|
if (!_videoCapture) {
|
||||||
_videoCapture = tgcalls::VideoCaptureInterface::Create();
|
_videoCapture = tgcalls::VideoCaptureInterface::Create(
|
||||||
|
Core::App().settings().callVideoInputDeviceId().toStdString());
|
||||||
_videoCapture->setOutput(_videoOutgoing->sink());
|
_videoCapture->setOutput(_videoOutgoing->sink());
|
||||||
}
|
}
|
||||||
if (_instance) {
|
if (_instance) {
|
||||||
|
@ -729,8 +742,8 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
|
||||||
std::move(encryptionKeyValue),
|
std::move(encryptionKeyValue),
|
||||||
(_type == Type::Outgoing)),
|
(_type == Type::Outgoing)),
|
||||||
.mediaDevicesConfig = tgcalls::MediaDevicesConfig{
|
.mediaDevicesConfig = tgcalls::MediaDevicesConfig{
|
||||||
.audioInputId = settings.callInputDeviceID().toStdString(),
|
.audioInputId = settings.callInputDeviceId().toStdString(),
|
||||||
.audioOutputId = settings.callOutputDeviceID().toStdString(),
|
.audioOutputId = settings.callOutputDeviceId().toStdString(),
|
||||||
.inputVolume = settings.callInputVolume() / 100.f,
|
.inputVolume = settings.callInputVolume() / 100.f,
|
||||||
.outputVolume = settings.callOutputVolume() / 100.f,
|
.outputVolume = settings.callOutputVolume() / 100.f,
|
||||||
},
|
},
|
||||||
|
@ -949,16 +962,22 @@ void Call::setState(State state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call::setCurrentAudioDevice(bool input, std::string deviceID) {
|
void Call::setCurrentAudioDevice(bool input, std::string deviceId) {
|
||||||
if (_instance) {
|
if (_instance) {
|
||||||
if (input) {
|
if (input) {
|
||||||
_instance->setAudioInputDevice(deviceID);
|
_instance->setAudioInputDevice(deviceId);
|
||||||
} else {
|
} else {
|
||||||
_instance->setAudioOutputDevice(deviceID);
|
_instance->setAudioOutputDevice(deviceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Call::setCurrentVideoDevice(std::string deviceId) {
|
||||||
|
if (_videoCapture) {
|
||||||
|
_videoCapture->switchToDevice(deviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Call::setAudioVolume(bool input, float level) {
|
void Call::setAudioVolume(bool input, float level) {
|
||||||
if (_instance) {
|
if (_instance) {
|
||||||
if (input) {
|
if (input) {
|
||||||
|
|
|
@ -40,6 +40,19 @@ struct DhConfig {
|
||||||
bytes::vector p;
|
bytes::vector p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ErrorType {
|
||||||
|
NoCamera,
|
||||||
|
NoMicrophone,
|
||||||
|
NotStartedCall,
|
||||||
|
NotVideoCall,
|
||||||
|
Unknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Error {
|
||||||
|
ErrorType type = ErrorType::Unknown;
|
||||||
|
QString details;
|
||||||
|
};
|
||||||
|
|
||||||
class Call : public base::has_weak_ptr {
|
class Call : public base::has_weak_ptr {
|
||||||
public:
|
public:
|
||||||
class Delegate {
|
class Delegate {
|
||||||
|
@ -105,6 +118,10 @@ public:
|
||||||
return _state.value();
|
return _state.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<Error> errors() const {
|
||||||
|
return _errors.events();
|
||||||
|
}
|
||||||
|
|
||||||
enum class RemoteAudioState {
|
enum class RemoteAudioState {
|
||||||
Muted,
|
Muted,
|
||||||
Active,
|
Active,
|
||||||
|
@ -155,7 +172,8 @@ public:
|
||||||
|
|
||||||
QString getDebugLog() const;
|
QString getDebugLog() const;
|
||||||
|
|
||||||
void setCurrentAudioDevice(bool input, std::string deviceID);
|
void setCurrentAudioDevice(bool input, std::string deviceId);
|
||||||
|
void setCurrentVideoDevice(std::string deviceId);
|
||||||
void setAudioVolume(bool input, float level);
|
void setAudioVolume(bool input, float level);
|
||||||
void setAudioDuckingEnabled(bool enabled);
|
void setAudioDuckingEnabled(bool enabled);
|
||||||
|
|
||||||
|
@ -213,6 +231,7 @@ private:
|
||||||
rpl::variable<State> _state = State::Starting;
|
rpl::variable<State> _state = State::Starting;
|
||||||
rpl::variable<RemoteAudioState> _remoteAudioState = RemoteAudioState::Active;
|
rpl::variable<RemoteAudioState> _remoteAudioState = RemoteAudioState::Active;
|
||||||
rpl::variable<Webrtc::VideoState> _remoteVideoState;
|
rpl::variable<Webrtc::VideoState> _remoteVideoState;
|
||||||
|
rpl::event_stream<Error> _errors;
|
||||||
FinishType _finishAfterRequestingCall = FinishType::None;
|
FinishType _finishAfterRequestingCall = FinishType::None;
|
||||||
bool _answerAfterDhConfigReceived = false;
|
bool _answerAfterDhConfigReceived = false;
|
||||||
rpl::variable<int> _signalBarCount = kSignalBarStarting;
|
rpl::variable<int> _signalBarCount = kSignalBarStarting;
|
||||||
|
|
|
@ -32,8 +32,9 @@ QByteArray Settings::serialize() const {
|
||||||
+ Serialize::stringSize(_downloadPath.current())
|
+ Serialize::stringSize(_downloadPath.current())
|
||||||
+ Serialize::bytearraySize(_downloadPathBookmark)
|
+ Serialize::bytearraySize(_downloadPathBookmark)
|
||||||
+ sizeof(qint32) * 12
|
+ sizeof(qint32) * 12
|
||||||
+ Serialize::stringSize(_callOutputDeviceID)
|
+ Serialize::stringSize(_callOutputDeviceId)
|
||||||
+ Serialize::stringSize(_callInputDeviceID)
|
+ Serialize::stringSize(_callInputDeviceId)
|
||||||
|
+ Serialize::stringSize(_callVideoInputDeviceId)
|
||||||
+ sizeof(qint32) * 3;
|
+ sizeof(qint32) * 3;
|
||||||
for (const auto &[key, value] : _soundOverrides) {
|
for (const auto &[key, value] : _soundOverrides) {
|
||||||
size += Serialize::stringSize(key) + Serialize::stringSize(value);
|
size += Serialize::stringSize(key) + Serialize::stringSize(value);
|
||||||
|
@ -63,8 +64,8 @@ QByteArray Settings::serialize() const {
|
||||||
<< qint32(_notificationsCount)
|
<< qint32(_notificationsCount)
|
||||||
<< static_cast<qint32>(_notificationsCorner)
|
<< static_cast<qint32>(_notificationsCorner)
|
||||||
<< qint32(_autoLock)
|
<< qint32(_autoLock)
|
||||||
<< _callOutputDeviceID
|
<< _callOutputDeviceId
|
||||||
<< _callInputDeviceID
|
<< _callInputDeviceId
|
||||||
<< qint32(_callOutputVolume)
|
<< qint32(_callOutputVolume)
|
||||||
<< qint32(_callInputVolume)
|
<< qint32(_callInputVolume)
|
||||||
<< qint32(_callAudioDuckingEnabled ? 1 : 0)
|
<< qint32(_callAudioDuckingEnabled ? 1 : 0)
|
||||||
|
@ -107,7 +108,8 @@ QByteArray Settings::serialize() const {
|
||||||
<< qint32(_thirdSectionExtendedBy)
|
<< qint32(_thirdSectionExtendedBy)
|
||||||
<< qint32(_notifyFromAll ? 1 : 0)
|
<< qint32(_notifyFromAll ? 1 : 0)
|
||||||
<< qint32(_nativeWindowFrame.current() ? 1 : 0)
|
<< qint32(_nativeWindowFrame.current() ? 1 : 0)
|
||||||
<< qint32(_systemDarkModeEnabled.current() ? 1 : 0);
|
<< qint32(_systemDarkModeEnabled.current() ? 1 : 0)
|
||||||
|
<< _callVideoInputDeviceId;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -137,8 +139,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
qint32 notificationsCount = _notificationsCount;
|
qint32 notificationsCount = _notificationsCount;
|
||||||
qint32 notificationsCorner = static_cast<qint32>(_notificationsCorner);
|
qint32 notificationsCorner = static_cast<qint32>(_notificationsCorner);
|
||||||
qint32 autoLock = _autoLock;
|
qint32 autoLock = _autoLock;
|
||||||
QString callOutputDeviceID = _callOutputDeviceID;
|
QString callOutputDeviceId = _callOutputDeviceId;
|
||||||
QString callInputDeviceID = _callInputDeviceID;
|
QString callInputDeviceId = _callInputDeviceId;
|
||||||
|
QString callVideoInputDeviceId = _callVideoInputDeviceId;
|
||||||
qint32 callOutputVolume = _callOutputVolume;
|
qint32 callOutputVolume = _callOutputVolume;
|
||||||
qint32 callInputVolume = _callInputVolume;
|
qint32 callInputVolume = _callInputVolume;
|
||||||
qint32 callAudioDuckingEnabled = _callAudioDuckingEnabled ? 1 : 0;
|
qint32 callAudioDuckingEnabled = _callAudioDuckingEnabled ? 1 : 0;
|
||||||
|
@ -193,8 +196,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
>> notificationsCount
|
>> notificationsCount
|
||||||
>> notificationsCorner
|
>> notificationsCorner
|
||||||
>> autoLock
|
>> autoLock
|
||||||
>> callOutputDeviceID
|
>> callOutputDeviceId
|
||||||
>> callInputDeviceID
|
>> callInputDeviceId
|
||||||
>> callOutputVolume
|
>> callOutputVolume
|
||||||
>> callInputVolume
|
>> callInputVolume
|
||||||
>> callAudioDuckingEnabled
|
>> callAudioDuckingEnabled
|
||||||
|
@ -253,6 +256,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
if (!stream.atEnd()) {
|
if (!stream.atEnd()) {
|
||||||
stream >> systemDarkModeEnabled;
|
stream >> systemDarkModeEnabled;
|
||||||
}
|
}
|
||||||
|
if (!stream.atEnd()) {
|
||||||
|
stream >> callVideoInputDeviceId;
|
||||||
|
}
|
||||||
if (stream.status() != QDataStream::Ok) {
|
if (stream.status() != QDataStream::Ok) {
|
||||||
LOG(("App Error: "
|
LOG(("App Error: "
|
||||||
"Bad data for Core::Settings::constructFromSerialized()"));
|
"Bad data for Core::Settings::constructFromSerialized()"));
|
||||||
|
@ -290,8 +296,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
_countUnreadMessages = (countUnreadMessages == 1);
|
_countUnreadMessages = (countUnreadMessages == 1);
|
||||||
_notifyAboutPinned = (notifyAboutPinned == 1);
|
_notifyAboutPinned = (notifyAboutPinned == 1);
|
||||||
_autoLock = autoLock;
|
_autoLock = autoLock;
|
||||||
_callOutputDeviceID = callOutputDeviceID;
|
_callOutputDeviceId = callOutputDeviceId;
|
||||||
_callInputDeviceID = callInputDeviceID;
|
_callInputDeviceId = callInputDeviceId;
|
||||||
|
_callVideoInputDeviceId = callVideoInputDeviceId;
|
||||||
_callOutputVolume = callOutputVolume;
|
_callOutputVolume = callOutputVolume;
|
||||||
_callInputVolume = callInputVolume;
|
_callInputVolume = callInputVolume;
|
||||||
_callAudioDuckingEnabled = (callAudioDuckingEnabled == 1);
|
_callAudioDuckingEnabled = (callAudioDuckingEnabled == 1);
|
||||||
|
@ -446,8 +453,9 @@ void Settings::resetOnLastLogout() {
|
||||||
_notifyAboutPinned = true;
|
_notifyAboutPinned = true;
|
||||||
//_autoLock = 3600;
|
//_autoLock = 3600;
|
||||||
|
|
||||||
//_callOutputDeviceID = u"default"_q;
|
//_callOutputDeviceId = u"default"_q;
|
||||||
//_callInputDeviceID = u"default"_q;
|
//_callInputDeviceId = u"default"_q;
|
||||||
|
//_callVideoInputDeviceId = u"default"_q;
|
||||||
//_callOutputVolume = 100;
|
//_callOutputVolume = 100;
|
||||||
//_callInputVolume = 100;
|
//_callInputVolume = 100;
|
||||||
//_callAudioDuckingEnabled = true;
|
//_callAudioDuckingEnabled = true;
|
||||||
|
|
|
@ -175,21 +175,29 @@ public:
|
||||||
void setAutoLock(int value) {
|
void setAutoLock(int value) {
|
||||||
_autoLock = value;
|
_autoLock = value;
|
||||||
}
|
}
|
||||||
[[nodiscard]] QString callOutputDeviceID() const {
|
[[nodiscard]] QString callOutputDeviceId() const {
|
||||||
return _callOutputDeviceID.isEmpty()
|
return _callOutputDeviceId.isEmpty()
|
||||||
? u"default"_q
|
? u"default"_q
|
||||||
: _callOutputDeviceID;
|
: _callOutputDeviceId;
|
||||||
}
|
}
|
||||||
void setCallOutputDeviceID(const QString &value) {
|
void setCallOutputDeviceId(const QString &value) {
|
||||||
_callOutputDeviceID = value;
|
_callOutputDeviceId = value;
|
||||||
}
|
}
|
||||||
[[nodiscard]] QString callInputDeviceID() const {
|
[[nodiscard]] QString callInputDeviceId() const {
|
||||||
return _callInputDeviceID.isEmpty()
|
return _callInputDeviceId.isEmpty()
|
||||||
? u"default"_q
|
? u"default"_q
|
||||||
: _callInputDeviceID;
|
: _callInputDeviceId;
|
||||||
}
|
}
|
||||||
void setCallInputDeviceID(const QString &value) {
|
void setCallInputDeviceId(const QString &value) {
|
||||||
_callInputDeviceID = value;
|
_callInputDeviceId = value;
|
||||||
|
}
|
||||||
|
[[nodiscard]] QString callVideoInputDeviceId() const {
|
||||||
|
return _callVideoInputDeviceId.isEmpty()
|
||||||
|
? u"default"_q
|
||||||
|
: _callVideoInputDeviceId;
|
||||||
|
}
|
||||||
|
void setCallVideoInputDeviceId(const QString &value) {
|
||||||
|
_callVideoInputDeviceId = value;
|
||||||
}
|
}
|
||||||
[[nodiscard]] int callOutputVolume() const {
|
[[nodiscard]] int callOutputVolume() const {
|
||||||
return _callOutputVolume;
|
return _callOutputVolume;
|
||||||
|
@ -493,8 +501,9 @@ private:
|
||||||
bool _countUnreadMessages = true;
|
bool _countUnreadMessages = true;
|
||||||
rpl::variable<bool> _notifyAboutPinned = true;
|
rpl::variable<bool> _notifyAboutPinned = true;
|
||||||
int _autoLock = 3600;
|
int _autoLock = 3600;
|
||||||
QString _callOutputDeviceID = u"default"_q;
|
QString _callOutputDeviceId = u"default"_q;
|
||||||
QString _callInputDeviceID = u"default"_q;
|
QString _callInputDeviceId = u"default"_q;
|
||||||
|
QString _callVideoInputDeviceId = u"default"_q;
|
||||||
int _callOutputVolume = 100;
|
int _callOutputVolume = 100;
|
||||||
int _callInputVolume = 100;
|
int _callInputVolume = 100;
|
||||||
bool _callAudioDuckingEnabled = true;
|
bool _callAudioDuckingEnabled = true;
|
||||||
|
|
|
@ -76,34 +76,86 @@ void Calls::setupContent() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto &settings = Core::App().settings();
|
const auto &settings = Core::App().settings();
|
||||||
|
|
||||||
const auto currentOutputName = [&] {
|
const auto currentOutputName = [&] {
|
||||||
if (settings.callOutputDeviceID() == qsl("default")) {
|
|
||||||
return tr::lng_settings_call_device_default(tr::now);
|
|
||||||
}
|
|
||||||
const auto list = Webrtc::GetAudioOutputList();
|
const auto list = Webrtc::GetAudioOutputList();
|
||||||
const auto i = ranges::find(
|
const auto i = ranges::find(
|
||||||
list,
|
list,
|
||||||
settings.callOutputDeviceID(),
|
settings.callOutputDeviceId(),
|
||||||
getId);
|
getId);
|
||||||
return (i != end(list))
|
return (i != end(list))
|
||||||
? getName(*i)
|
? getName(*i)
|
||||||
: settings.callOutputDeviceID();
|
: tr::lng_settings_call_device_default(tr::now);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
const auto currentInputName = [&] {
|
const auto currentInputName = [&] {
|
||||||
if (settings.callInputDeviceID() == qsl("default")) {
|
|
||||||
return tr::lng_settings_call_device_default(tr::now);
|
|
||||||
}
|
|
||||||
const auto list = Webrtc::GetAudioInputList();
|
const auto list = Webrtc::GetAudioInputList();
|
||||||
const auto i = ranges::find(
|
const auto i = ranges::find(
|
||||||
list,
|
list,
|
||||||
settings.callInputDeviceID(),
|
settings.callInputDeviceId(),
|
||||||
getId);
|
getId);
|
||||||
return (i != end(list))
|
return (i != end(list))
|
||||||
? getName(*i)
|
? getName(*i)
|
||||||
: settings.callInputDeviceID();
|
: tr::lng_settings_call_device_default(tr::now);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
const auto cameras = Webrtc::GetVideoInputList();
|
||||||
|
if (!cameras.empty()) {
|
||||||
|
const auto currentCameraName = [&] {
|
||||||
|
const auto i = ranges::find(
|
||||||
|
cameras,
|
||||||
|
settings.callVideoInputDeviceId(),
|
||||||
|
getId);
|
||||||
|
return (i != end(cameras))
|
||||||
|
? getName(*i)
|
||||||
|
: tr::lng_settings_call_device_default(tr::now);
|
||||||
|
}();
|
||||||
|
|
||||||
|
AddSkip(content);
|
||||||
|
AddSubsectionTitle(content, tr::lng_settings_call_camera());
|
||||||
|
AddButtonWithLabel(
|
||||||
|
content,
|
||||||
|
tr::lng_settings_call_input_device(),
|
||||||
|
rpl::single(
|
||||||
|
currentCameraName
|
||||||
|
) | rpl::then(
|
||||||
|
_cameraNameStream.events()
|
||||||
|
),
|
||||||
|
st::settingsButton
|
||||||
|
)->addClickHandler([=] {
|
||||||
|
const auto &devices = Webrtc::GetVideoInputList();
|
||||||
|
const auto options = ranges::view::concat(
|
||||||
|
ranges::view::single(tr::lng_settings_call_device_default(tr::now)),
|
||||||
|
devices | ranges::view::transform(getName)
|
||||||
|
) | ranges::to_vector;
|
||||||
|
const auto i = ranges::find(
|
||||||
|
devices,
|
||||||
|
Core::App().settings().callVideoInputDeviceId(),
|
||||||
|
getId);
|
||||||
|
const auto currentOption = (i != end(devices))
|
||||||
|
? int(i - begin(devices) + 1)
|
||||||
|
: 0;
|
||||||
|
const auto save = crl::guard(this, [=](int option) {
|
||||||
|
_cameraNameStream.fire_copy(options[option]);
|
||||||
|
const auto deviceId = option
|
||||||
|
? devices[option - 1].id
|
||||||
|
: "default";
|
||||||
|
Core::App().settings().setCallVideoInputDeviceId(deviceId);
|
||||||
|
Core::App().saveSettingsDelayed();
|
||||||
|
if (const auto call = Core::App().calls().currentCall()) {
|
||||||
|
call->setCurrentVideoDevice(deviceId.toStdString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ui::show(Box<SingleChoiceBox>(
|
||||||
|
tr::lng_settings_call_camera(),
|
||||||
|
options,
|
||||||
|
currentOption,
|
||||||
|
save));
|
||||||
|
});
|
||||||
|
|
||||||
|
AddSkip(content);
|
||||||
|
AddDivider(content);
|
||||||
|
}
|
||||||
AddSkip(content);
|
AddSkip(content);
|
||||||
AddSubsectionTitle(content, tr::lng_settings_call_section_output());
|
AddSubsectionTitle(content, tr::lng_settings_call_section_output());
|
||||||
AddButtonWithLabel(
|
AddButtonWithLabel(
|
||||||
|
@ -123,7 +175,7 @@ void Calls::setupContent() {
|
||||||
) | ranges::to_vector;
|
) | ranges::to_vector;
|
||||||
const auto i = ranges::find(
|
const auto i = ranges::find(
|
||||||
devices,
|
devices,
|
||||||
Core::App().settings().callOutputDeviceID(),
|
Core::App().settings().callOutputDeviceId(),
|
||||||
getId);
|
getId);
|
||||||
const auto currentOption = (i != end(devices))
|
const auto currentOption = (i != end(devices))
|
||||||
? int(i - begin(devices) + 1)
|
? int(i - begin(devices) + 1)
|
||||||
|
@ -133,7 +185,7 @@ void Calls::setupContent() {
|
||||||
const auto deviceId = option
|
const auto deviceId = option
|
||||||
? devices[option - 1].id
|
? devices[option - 1].id
|
||||||
: "default";
|
: "default";
|
||||||
Core::App().settings().setCallOutputDeviceID(deviceId);
|
Core::App().settings().setCallOutputDeviceId(deviceId);
|
||||||
Core::App().saveSettingsDelayed();
|
Core::App().saveSettingsDelayed();
|
||||||
if (const auto call = Core::App().calls().currentCall()) {
|
if (const auto call = Core::App().calls().currentCall()) {
|
||||||
call->setCurrentAudioDevice(false, deviceId.toStdString());
|
call->setCurrentAudioDevice(false, deviceId.toStdString());
|
||||||
|
@ -198,7 +250,7 @@ void Calls::setupContent() {
|
||||||
) | ranges::to_vector;
|
) | ranges::to_vector;
|
||||||
const auto i = ranges::find(
|
const auto i = ranges::find(
|
||||||
devices,
|
devices,
|
||||||
Core::App().settings().callInputDeviceID(),
|
Core::App().settings().callInputDeviceId(),
|
||||||
getId);
|
getId);
|
||||||
const auto currentOption = (i != end(devices))
|
const auto currentOption = (i != end(devices))
|
||||||
? int(i - begin(devices) + 1)
|
? int(i - begin(devices) + 1)
|
||||||
|
@ -208,7 +260,7 @@ void Calls::setupContent() {
|
||||||
const auto deviceId = option
|
const auto deviceId = option
|
||||||
? devices[option - 1].id
|
? devices[option - 1].id
|
||||||
: "default";
|
: "default";
|
||||||
Core::App().settings().setCallInputDeviceID(deviceId);
|
Core::App().settings().setCallInputDeviceId(deviceId);
|
||||||
Core::App().saveSettingsDelayed();
|
Core::App().saveSettingsDelayed();
|
||||||
if (_micTester) {
|
if (_micTester) {
|
||||||
stopTestingMicrophone();
|
stopTestingMicrophone();
|
||||||
|
@ -354,7 +406,7 @@ void Calls::startTestingMicrophone() {
|
||||||
_micTestTextStream.fire(tr::lng_settings_call_stop_mic_test(tr::now));
|
_micTestTextStream.fire(tr::lng_settings_call_stop_mic_test(tr::now));
|
||||||
_levelUpdateTimer.callEach(50);
|
_levelUpdateTimer.callEach(50);
|
||||||
_micTester = std::make_unique<tgvoip::AudioInputTester>(
|
_micTester = std::make_unique<tgvoip::AudioInputTester>(
|
||||||
Core::App().settings().callInputDeviceID().toStdString());
|
Core::App().settings().callInputDeviceId().toStdString());
|
||||||
if (_micTester->Failed()) {
|
if (_micTester->Failed()) {
|
||||||
stopTestingMicrophone();
|
stopTestingMicrophone();
|
||||||
Ui::show(Box<InformBox>(tr::lng_call_error_audio_io(tr::now)));
|
Ui::show(Box<InformBox>(tr::lng_call_error_audio_io(tr::now)));
|
||||||
|
|
|
@ -38,6 +38,7 @@ private:
|
||||||
void stopTestingMicrophone();
|
void stopTestingMicrophone();
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
|
rpl::event_stream<QString> _cameraNameStream;
|
||||||
rpl::event_stream<QString> _outputNameStream;
|
rpl::event_stream<QString> _outputNameStream;
|
||||||
rpl::event_stream<QString> _inputNameStream;
|
rpl::event_stream<QString> _inputNameStream;
|
||||||
rpl::event_stream<QString> _micTestTextStream;
|
rpl::event_stream<QString> _micTestTextStream;
|
||||||
|
|
|
@ -1093,9 +1093,9 @@ bool ReadSetting(
|
||||||
settingsStream >> duckingEnabled;
|
settingsStream >> duckingEnabled;
|
||||||
if (CheckStreamStatus(settingsStream)) {
|
if (CheckStreamStatus(settingsStream)) {
|
||||||
auto &app = Core::App().settings();
|
auto &app = Core::App().settings();
|
||||||
app.setCallOutputDeviceID(outputDeviceID);
|
app.setCallOutputDeviceId(outputDeviceID);
|
||||||
app.setCallOutputVolume(outputVolume);
|
app.setCallOutputVolume(outputVolume);
|
||||||
app.setCallInputDeviceID(inputDeviceID);
|
app.setCallInputDeviceId(inputDeviceID);
|
||||||
app.setCallInputVolume(inputVolume);
|
app.setCallInputVolume(inputVolume);
|
||||||
app.setCallAudioDuckingEnabled(duckingEnabled);
|
app.setCallAudioDuckingEnabled(duckingEnabled);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c6c78d68729ce16cff2bee868939780788443963
|
Subproject commit 481f7fa9bbcbc07ebbbdb6432bdeebc1e0ca3982
|
|
@ -1 +1 @@
|
||||||
Subproject commit 32957e855993b20c95fa714518ba4bc55ebcdd32
|
Subproject commit 0b6130704442a1fb8cd91407ec46d3ae5a66389e
|
Loading…
Reference in New Issue