UWP:如何录制屏幕并保存为MP4文件? [英] UWP: How to record Screen and save as mp4 file?
问题描述
我已经使用下面的示例了解了如何捕获屏幕并将其输出回预览器:Microsoft Screen Capture Documentation
就目前而言,这已经很好了。
我想不出来的是,我也找不到任何文档,就是获取这些帧并将其写入视频文件。
理想情况下,我希望将它们直接流到MP4或类似的音乐中,然后我可以在以后使用MediaComposation系统进行编辑。
我找到了VideoFrame.CreateWithDirect3D11Surface,但我想不出如何将视频帧添加到现有视频文件中。文档告诉您如何创建视频帧以及属性如何工作,但它没有告诉您如何在视频文件中使用视频帧,我也找不到任何关于如何在没有摄像机或其他捕获设备的情况下创建视频文件的内容。
文档GitHub中也有一些引用,其中有人问到他们说MediaStreamSample是关键字的位置,但也没有任何代码,当然也没有允许保存文件的代码。(Here's the issue)
人们可能会认为,使用此API录制屏幕并将这些帧转储为原始视频文件会很容易,然后您可以使用MediaComposation API引入和编辑该文件。
请帮帮忙!
推荐答案
假设您使用的是微软的屏幕截图示例。以下是您需要做的事情:
这里有完整的源代码(代码确实需要重构,但它可以在🤷♂️上运行):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;
}
- 设置编码,开始截屏并开始转码(注:Stream指的是从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提供空样本,它将停止请求更多样本。
然后可以从打开流的文件中查看视频。
这篇关于UWP:如何录制屏幕并保存为MP4文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!