Pausing / Resuming Screen recording with Windows Graphics Capture API
See the question and my original answer on StackOverflowOne solution is to get a deferral. Doc says:
The MediaStreamSource will then wait for you to supply the MediaStreamSample until you mark the deferral as complete.
So for example, add two private members to the Encoder
class and two methods:
private MediaStreamSourceSampleRequestedEventArgs _args;
private MediaStreamSourceSampleRequestDeferral _def;
public bool IsPaused { get; private set; }
public void Pause()
{
IsPaused = true;
}
public void Resume()
{
IsPaused = false;
// complete the request we saved earlier
OnMediaStreamSourceSampleRequested(_mediaStreamSource, _args);
}
And modify OnMediaStreamSourceSampleRequested
methods like this (where I've put comments):
private void OnMediaStreamSourceSampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args)
{
if (_isRecording && !_closed)
{
// if paused get a deferral and save the current arguments.
// OnMediaStreamSourceSampleRequested will not be called again until we complete the deferral
if (IsPaused)
{
_def = args.Request.GetDeferral();
_args = args;
return;
}
try
{
using (var frame = _frameGenerator.WaitForNewFrame())
{
if (frame == null)
{
args.Request.Sample = null;
DisposeInternal();
return;
}
var timeStamp = frame.SystemRelativeTime;
var sample = MediaStreamSample.CreateFromDirect3D11Surface(frame.Surface, timeStamp);
args.Request.Sample = sample;
// when called again (manually by us) complete the work
// and reset members
if (_def != null)
{
_def.Complete();
_def = null;
_args = null;
}
}
}
catch (Exception e)
{
...
}
}
else
{
...
}
}
Another solution is to simply freeze the frames timestamp, so add these members:
private TimeSpan _pausedTimestamp;
public bool IsPaused { get; private set; }
public void Pause()
{
IsPaused = true;
}
public void Resume()
{
IsPaused = false;
}
And modify OnMediaStreamSourceSampleRequested
methods like this (where I've put comments):
private void OnMediaStreamSourceSampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args)
{
if (_isRecording && !_closed)
{
try
{
using (var frame = _frameGenerator.WaitForNewFrame())
{
if (frame == null)
{
args.Request.Sample = null;
DisposeInternal();
return;
}
// if paused, "freeze" the timestamp
TimeSpan timeStamp;
if (IsPaused)
{
timeStamp = _pausedTimestamp;
}
else
{
timeStamp = frame.SystemRelativeTime;
_pausedTimestamp = timeStamp;
}
var sample = MediaStreamSample.CreateFromDirect3D11Surface(frame.Surface, timeStamp);
args.Request.Sample = sample;
}
}
catch (Exception e)
{
...
}
}
else
{
...
}
}