假设您正在使用 Microsoft 的屏幕捕获示例。以下是您需要做的:
此处提供完整的源代码(代码确实需要重构,但它可以工作?♂️):https://gitlab.com/colinkiama/screenrecordertest/-/tree/master/screenRecorderTest
代码是使用屏幕截图示例和 SimpleRecorder 源代码的一部分:https://github.com/robmikh/SimpleRecorder/tree/master/SimpleRecorder
- 使用有关输入的详细信息创建 MediaStreamSource
private void CreateMediaObjects()
{
// Describe our input: uncompressed BGRA8 buffers
var videoProperties = VideoEncodingProperties.CreateUncompressed(MediaEncodingSubtypes.Bgra8, _sourceWidth, _sourceHeight);
_videoDescriptor = new VideoStreamDescriptor(videoProperties);
// Create our MediaStreamSource
_mediaStreamSource = new MediaStreamSource(_videoDescriptor);
_mediaStreamSource.BufferTime = TimeSpan.FromSeconds(0);
_mediaStreamSource.Starting += OnMediaStreamSourceStarting;
_mediaStreamSource.SampleRequested += OnMediaStreamSourceSampleRequested;
// Create our transcoder
_transcoder = new MediaTranscoder();
_transcoder.HardwareAccelerationEnabled = true;
}
- 设置编码,开始抓屏,开始转码(注:流是指从StorageFile对象打开的流)
private async Task EncodeInternalAsync(IRandomAccessStream stream, uint width, uint height, uint bitrateInBps, uint frameRate)
{
if (!_isRecording)
{
_isRecording = true;
var encodingProfile = new MediaEncodingProfile();
encodingProfile.Container.Subtype = "MPEG4";
encodingProfile.Video.Subtype = "H264";
encodingProfile.Video.Width = width;
encodingProfile.Video.Height = height;
encodingProfile.Video.Bitrate = bitrateInBps;
encodingProfile.Video.FrameRate.Numerator = frameRate;
encodingProfile.Video.FrameRate.Denominator = 1;
encodingProfile.Video.PixelAspectRatio.Numerator = 1;
encodingProfile.Video.PixelAspectRatio.Denominator = 1;
StartFrameCapture();
var transcode = await _transcoder.PrepareMediaStreamSourceTranscodeAsync(_mediaStreamSource, stream, encodingProfile);
await transcode.TranscodeAsync();
}
}
- 对于从屏幕捕获到达的每一帧,创建一个 MediaStream 示例
using (var frame = _framePool.TryGetNextFrame())
{
MediaStreamSample sampleToUseLater = MediaStreamSample.CreateFromDirect3D11Surface(frame.Surface, frame.SystemRelativeTime);
lock (doubleBufferingPool)
{
while (doubleBufferingPool.Count >= 2)
{
// Stops too many samples from being saved
doubleBufferingPool.Dequeue();
}
doubleBufferingPool.Enqueue(sampleToUseLater);
}
}
- 设置流的实际开始时间:
private void OnMediaStreamSourceStarting(MediaStreamSource sender, MediaStreamSourceStartingEventArgs args)
{
while (doubleBufferingPool.Count == 0)
{
}
var sample = doubleBufferingPool.Dequeue();
TimeSpan timeStamp = sample.Timestamp;
args.Request.SetActualStartPosition(timeStamp);
}
- 向 MediaStreamSource 提供样本
private void OnMediaStreamSourceSampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args)
{
if (_isRecording && !_closed)
{
while (doubleBufferingPool.Count == 0)
{
}
lock (doubleBufferingPool)
{
args.Request.Sample = doubleBufferingPool.Dequeue();
}
}
else
{
args.Request.Sample = null;
StopCapture();
}
}
如果您向 MediaStreamSource 提供空样本,它将停止要求更多样本。
然后可以从您打开流的文件中查看视频。