sskodje / ScreenRecorderLib

A .NET library for screen recording in Windows, using native Microsoft Media Foundation for realtime encoding to h264 video or PNG images.
MIT License
408 stars 93 forks source link

Unable to use DynamicOptions to turn off Desktop capture #256

Closed PikeNote closed 1 year ago

PikeNote commented 1 year ago

When trying to use the DynamicOptionsBuilder to modify if a capture source is enabled, I am unable to disable it.

I created a standard recorder with new DisplayRecordingSource(DisplayRecordingSource.MainMonitor) as the source. Later on in the code I used the following code to attempt to disable the source (black out the video for a duration) but the recorder keeps recording with the source on/visible in the final video output.

rd.GetDynamicOptionsBuilder()
     .SetVideoCaptureEnabledForRecordingSource(DisplayRecordingSource.MainMonitor.ID, false)
    .Apply();

Nothing is visible in the output logs other than the standard recorder starting.

2023-07-18 14:15:58.994 [DEBUG] [RecordingManager.cpp     |  ConfigureOutputDir: 142] >> Video output folder is ready
2023-07-18 14:15:58.999 [INFO]  [RecordingManager.cpp     |         operator (): 226] >> Starting recording task
2023-07-18 14:15:59.240 [DEBUG] [WASAPICapture.cpp        | InitializeResampler: 209] >> No resampling necessary
2023-07-18 14:15:59.240 [DEBUG] [AudioManager.cpp         | ConfigureAudioCaptu: 137] >> Created WASAPI capture on AudioOutputDevice
2023-07-18 14:15:59.249 [INFO]  [AudioManager.cpp         |  StartDeviceCapture: 114] >> Started audio capture on AudioOutputDevice: 3 - HP X27q (AMD High Definition Audio Device)
2023-07-18 14:15:59.259 [DEBUG] [WASAPICapture.cpp        |    StartCaptureLoop: 372] >> Probably spurious glitch reported on first packet on AudioOutputDevice
2023-07-18 14:16:00.121 [DEBUG] [OutputManager.cpp        |      BeginRecording: 104] >> Sink Writer initialized
2023-07-18 14:16:00.124 [DEBUG] [RecordingManager.cpp     |   StartRecorderLoop: 657] >> Changed Recording Status to Recording

Full options applied:

List<RecordingSourceBase> rdSources = new List<RecordingSourceBase>();
rdSources.Add(new DisplayRecordingSource(DisplayRecordingSource.MainMonitor));

RecorderOptions options = new RecorderOptions
            {
                SourceOptions = new SourceOptions
                {
                    RecordingSources = rdSources    
                },
                OutputOptions = new OutputOptions
                {
                    RecorderMode = RecorderMode.Video,
                    OutputFrameSize = new ScreenSize(1920, 1080),
                    Stretch = StretchMode.Uniform
                },
                AudioOptions = new AudioOptions
                {
                    Bitrate = AudioBitrate.bitrate_128kbps,
                    Channels = AudioChannels.Stereo,
                    IsAudioEnabled = true,
                },
                VideoEncoderOptions = new VideoEncoderOptions
                {
                    Quality = 50,
                    Framerate = 144,
                    IsFixedFramerate = false,
                    Encoder = new H264VideoEncoder()
                    {
                        BitrateMode = H264BitrateControlMode.Quality,
                        EncoderProfile = H264Profile.Main,

                    },
                    IsFragmentedMp4Enabled = true,
                    IsThrottlingDisabled = false,
                    IsHardwareEncodingEnabled = true,
                    IsLowLatencyEnabled = false,
                    IsMp4FastStartEnabled = false
                },
                MouseOptions = new MouseOptions
                {
                    IsMouseClicksDetected = false
                },
                LogOptions = new LogOptions
                {
                    IsLogEnabled = true,
                    LogFilePath = path,
                    LogSeverityLevel = ScreenRecorderLib.LogLevel.Debug
                }
            };

Only running a single setup display with a HP X27q

sskodje commented 1 year ago

Hello! I realize the interface is clumsy, but in order to differentiate several instances of the same display, window etc. in one recording, the ID in question is generated unique per source instance. In other words, you need to store a reference to the recording source you pass when starting a recording, then pass the ID of that recording source when changing dynamic options.

PikeNote commented 1 year ago

Thanks for the quick response! I can confirm the id from the stored DisplayRecordingSource worked. I had assumed since it was the main monitor that the ID would just stay consistent. I saw in the example ScreenRecorderTests that it used DisplayRecordingSource.MainMonitor and DisplayRecordingSource.MainMonitor.ID for the dynamic options builder and assumed it worked the same.