Skip to content

Commit 40d10bb

Browse files
authored
Merge pull request #2 from shanebweaver/fix/keep-audio-route-mutable
Keep video audio mutable with independent volume
2 parents b9e019d + 6f88a68 commit 40d10bb

20 files changed

Lines changed: 209 additions & 58 deletions

‎Directory.Version.props‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<CaptureKitVersion>1.0.3</CaptureKitVersion>
3+
<CaptureKitVersion>1.0.5</CaptureKitVersion>
44
<Version>$(CaptureKitVersion)</Version>
55
</PropertyGroup>
66
</Project>

‎src/CaptureKit.Abstractions/IVideoCaptureService.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public interface IVideoCaptureSession : IDisposable
2121
void Pause();
2222
void Resume();
2323
void SetAudioCaptureEnabled(bool enabled);
24+
void SetSystemAudioVolume(int volumePercentage);
2425
void SetAudioInputSource(string? sourceId);
2526
void SetAudioInputVolume(int volumePercentage);
2627
}

‎src/CaptureKit.Abstractions/VideoCaptureOptions.cs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ public sealed record VideoCaptureOptions(
88
uint VideoBitrate = 5_000_000,
99
uint AudioBitrate = 128_000,
1010
string? AudioInputSourceId = null,
11-
int AudioInputVolumePercentage = 100);
11+
int AudioInputVolumePercentage = 100,
12+
int SystemAudioVolumePercentage = 100);

‎src/CaptureKit.Windows.Native.Core/CaptureSessionConfig.h‎

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ struct CaptureSessionConfig
106106
/// </summary>
107107
uint32_t audioInputVolumePercentage;
108108

109+
/// <summary>
110+
/// System/desktop audio volume as a percentage. 100 preserves the captured signal.
111+
/// </summary>
112+
uint32_t systemAudioVolumePercentage;
113+
109114
/// <summary>
110115
/// Target video frame rate (FPS). Default is 30.
111116
/// </summary>
@@ -132,7 +137,8 @@ struct CaptureSessionConfig
132137
uint32_t vidBitrate = 5'000'000,
133138
uint32_t audBitrate = 128'000,
134139
std::wstring audioSourceId = L"",
135-
uint32_t audioVolumePercentage = 100)
140+
uint32_t audioVolumePercentage = 100,
141+
uint32_t systemVolumePercentage = 100)
136142
: targetType(CaptureTargetType::Monitor)
137143
, hMonitor(monitor)
138144
, hwnd(nullptr)
@@ -147,6 +153,7 @@ struct CaptureSessionConfig
147153
, audioBitrate(audBitrate)
148154
, audioInputSourceId(std::move(audioSourceId))
149155
, audioInputVolumePercentage(audioVolumePercentage)
156+
, systemAudioVolumePercentage(systemVolumePercentage)
150157
{
151158
}
152159

@@ -161,7 +168,8 @@ struct CaptureSessionConfig
161168
uint32_t vidBitrate = 5'000'000,
162169
uint32_t audBitrate = 128'000,
163170
std::wstring audioSourceId = L"",
164-
uint32_t audioVolumePercentage = 100)
171+
uint32_t audioVolumePercentage = 100,
172+
uint32_t systemVolumePercentage = 100)
165173
: targetType(CaptureTargetType::Monitor)
166174
, hMonitor(monitor)
167175
, hwnd(nullptr)
@@ -176,6 +184,7 @@ struct CaptureSessionConfig
176184
, audioBitrate(audBitrate)
177185
, audioInputSourceId(std::move(audioSourceId))
178186
, audioInputVolumePercentage(audioVolumePercentage)
187+
, systemAudioVolumePercentage(systemVolumePercentage)
179188
{
180189
}
181190

@@ -197,6 +206,7 @@ struct CaptureSessionConfig
197206
, audioBitrate(128'000)
198207
, audioInputSourceId(L"")
199208
, audioInputVolumePercentage(100)
209+
, systemAudioVolumePercentage(100)
200210
{
201211
}
202212

@@ -208,9 +218,10 @@ struct CaptureSessionConfig
208218
uint32_t vidBitrate = 5'000'000,
209219
uint32_t audBitrate = 128'000,
210220
std::wstring audioSourceId = L"",
211-
uint32_t audioVolumePercentage = 100)
221+
uint32_t audioVolumePercentage = 100,
222+
uint32_t systemVolumePercentage = 100)
212223
{
213-
CaptureSessionConfig config(monitor, std::move(path), audio, fps, vidBitrate, audBitrate, std::move(audioSourceId), audioVolumePercentage);
224+
CaptureSessionConfig config(monitor, std::move(path), audio, fps, vidBitrate, audBitrate, std::move(audioSourceId), audioVolumePercentage, systemVolumePercentage);
214225
config.targetType = CaptureTargetType::Monitor;
215226
return config;
216227
}
@@ -223,9 +234,10 @@ struct CaptureSessionConfig
223234
uint32_t vidBitrate = 5'000'000,
224235
uint32_t audBitrate = 128'000,
225236
std::wstring audioSourceId = L"",
226-
uint32_t audioVolumePercentage = 100)
237+
uint32_t audioVolumePercentage = 100,
238+
uint32_t systemVolumePercentage = 100)
227239
{
228-
CaptureSessionConfig config(nullptr, std::move(path), audio, fps, vidBitrate, audBitrate, std::move(audioSourceId), audioVolumePercentage);
240+
CaptureSessionConfig config(nullptr, std::move(path), audio, fps, vidBitrate, audBitrate, std::move(audioSourceId), audioVolumePercentage, systemVolumePercentage);
229241
config.targetType = CaptureTargetType::Window;
230242
config.hwnd = window;
231243
return config;
@@ -243,9 +255,10 @@ struct CaptureSessionConfig
243255
uint32_t vidBitrate = 5'000'000,
244256
uint32_t audBitrate = 128'000,
245257
std::wstring audioSourceId = L"",
246-
uint32_t audioVolumePercentage = 100)
258+
uint32_t audioVolumePercentage = 100,
259+
uint32_t systemVolumePercentage = 100)
247260
{
248-
CaptureSessionConfig config(monitor, std::move(path), audio, fps, vidBitrate, audBitrate, std::move(audioSourceId), audioVolumePercentage);
261+
CaptureSessionConfig config(monitor, std::move(path), audio, fps, vidBitrate, audBitrate, std::move(audioSourceId), audioVolumePercentage, systemVolumePercentage);
249262
config.targetType = CaptureTargetType::Rectangle;
250263
config.sourceLeft = left;
251264
config.sourceTop = top;
@@ -335,21 +348,24 @@ struct CaptureSessionConfig
335348
constexpr uint32_t MIN_AUDIO_BITRATE = 32'000; // 32 kbps
336349
constexpr uint32_t MAX_AUDIO_BITRATE = 320'000; // 320 kbps
337350

338-
if (audioEnabled)
351+
if (audioBitrate < MIN_AUDIO_BITRATE || audioBitrate > MAX_AUDIO_BITRATE)
339352
{
340-
if (audioBitrate < MIN_AUDIO_BITRATE || audioBitrate > MAX_AUDIO_BITRATE)
341-
{
342-
result.AddError("audioBitrate must be between " +
343-
std::to_string(MIN_AUDIO_BITRATE) + " and " +
344-
std::to_string(MAX_AUDIO_BITRATE) + " (got " +
345-
std::to_string(audioBitrate) + ")");
346-
}
353+
result.AddError("audioBitrate must be between " +
354+
std::to_string(MIN_AUDIO_BITRATE) + " and " +
355+
std::to_string(MAX_AUDIO_BITRATE) + " (got " +
356+
std::to_string(audioBitrate) + ")");
357+
}
347358

348-
if (audioInputVolumePercentage > 100)
349-
{
350-
result.AddError("audioInputVolumePercentage must be between 0 and 100 (got " +
351-
std::to_string(audioInputVolumePercentage) + ")");
352-
}
359+
if (audioInputVolumePercentage > 100)
360+
{
361+
result.AddError("audioInputVolumePercentage must be between 0 and 100 (got " +
362+
std::to_string(audioInputVolumePercentage) + ")");
363+
}
364+
365+
if (systemAudioVolumePercentage > 100)
366+
{
367+
result.AddError("systemAudioVolumePercentage must be between 0 and 100 (got " +
368+
std::to_string(systemAudioVolumePercentage) + ")");
353369
}
354370

355371
return result;

‎src/CaptureKit.Windows.Native.Core/CompositeAudioCaptureSource.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,17 @@ void CompositeAudioCaptureSource::SetVolume(uint32_t volumePercentage)
434434
}
435435
}
436436

437+
void CompositeAudioCaptureSource::SetSystemVolume(uint32_t volumePercentage)
438+
{
439+
uint32_t clampedVolume = std::min<uint32_t>(volumePercentage, 100);
440+
441+
std::lock_guard<std::mutex> lock(m_sourceMutex);
442+
if (m_loopbackSource)
443+
{
444+
m_loopbackSource->SetVolume(clampedVolume);
445+
}
446+
}
447+
437448
bool CompositeAudioCaptureSource::IsRunning() const
438449
{
439450
return m_isRunning.load();

‎src/CaptureKit.Windows.Native.Core/CompositeAudioCaptureSource.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class CompositeAudioCaptureSource final : public IAudioCaptureSource
2727
void SetEnabled(bool enabled) override;
2828
bool IsEnabled() const override;
2929
void SetVolume(uint32_t volumePercentage) override;
30+
void SetSystemVolume(uint32_t volumePercentage) override;
3031
bool IsRunning() const override;
3132
bool SetInputDeviceId(const wchar_t* sourceId, HRESULT* outHr = nullptr) override;
3233
void SetClockWriter(IMediaClockWriter* clockWriter) override;

‎src/CaptureKit.Windows.Native.Core/IAudioCaptureSource.h‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ class IAudioCaptureSource : public IMediaClockAdvancer
8484
/// </summary>
8585
virtual void SetVolume(uint32_t volumePercentage) = 0;
8686

87+
/// <summary>
88+
/// Set the system/desktop volume independently from microphone/input volume.
89+
/// Standalone sources treat this as their normal volume control.
90+
/// </summary>
91+
virtual void SetSystemVolume(uint32_t volumePercentage)
92+
{
93+
SetVolume(volumePercentage);
94+
}
95+
8796
/// <summary>
8897
/// Check if the audio input source is currently running.
8998
/// </summary>

‎src/CaptureKit.Windows.Native.Core/ICaptureSession.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ class ICaptureSession
5050
/// <param name="enabled">True to enable audio, false to mute.</param>
5151
virtual void ToggleAudioCapture(bool enabled) = 0;
5252

53+
/// <summary>
54+
/// Set the system/desktop audio volume percentage for the active recording.
55+
/// </summary>
56+
virtual void SetSystemAudioVolume(uint32_t volumePercentage) = 0;
57+
5358
/// <summary>
5459
/// Change the audio input source for the active recording.
5560
/// </summary>

‎src/CaptureKit.Windows.Native.Core/ScreenRecorderImpl.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,17 @@ bool ScreenRecorderImpl::SetAudioCaptureEnabled(bool enabled)
190190
return true;
191191
}
192192

193+
bool ScreenRecorderImpl::SetSystemAudioVolume(uint32_t volumePercentage)
194+
{
195+
if (!HasActiveSession() || !m_captureSession->IsActive())
196+
{
197+
return false;
198+
}
199+
200+
m_captureSession->SetSystemAudioVolume(volumePercentage);
201+
return true;
202+
}
203+
193204
bool ScreenRecorderImpl::SetAudioInputSource(const wchar_t* sourceId)
194205
{
195206
if (!HasActiveSession() || !m_captureSession->IsActive())

‎src/CaptureKit.Windows.Native.Core/ScreenRecorderImpl.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ class ScreenRecorderImpl
7070
/// <param name="enabled">True to enable audio, false to mute.</param>
7171
bool SetAudioCaptureEnabled(bool enabled);
7272

73+
/// <summary>
74+
/// Set system/desktop audio volume during recording.
75+
/// </summary>
76+
bool SetSystemAudioVolume(uint32_t volumePercentage);
77+
7378
/// <summary>
7479
/// Change the audio input source during recording.
7580
/// </summary>

0 commit comments

Comments
 (0)