繁体   English   中英

在 UWP C# 中不使用 MediaComposition 从 SoftwareBitmap 或 Direct3DSurface 创建视频文件

[英]Creating a video file from SoftwareBitmap or Direct3DSurface without MediaComposition in UWP C#

我正在尝试在使用 MediaFrameReader 时录制相机的视频。 对于我的应用程序,我需要 MediaFrameReader 实例来单独处理每个帧。 我曾尝试另外应用 LowLagMediaRecording 来简单地将相机流保存到文件中,但似乎您不能同时使用这两种方法。 这意味着我只能使用 MediaFrameReader 来访问 Frame_Arrived 方法中的每一帧。

我尝试了几种方法,并找到了两个使用 MediaComposition 类创建 MediaClip 对象的有效解决方案。 您可以将每一帧保存为 JPEG 文件,最后将所有图像渲染为视频文件。 此过程非常缓慢,因为您经常需要访问硬盘驱动器。 或者,您可以从帧的 Direct3DSurface 创建 MediaStreamSample 对象。 通过这种方式,您可以将数据保存在 RAM 中(首先在 GPU RAM 中,如果已满则在 RAM 中)而不是理论上更快的硬盘驱动器。 问题是调用 MediaComposition 类的 RenderToFileAsync 方法要求所有 MediaClip 都已添加到内部列表中。 这会导致在已经很短的录制时间后超出 RAM。 在收集了大约 5 分钟的数据后,windows 已经创建了一个 70GB 的交换文件,这首先违背了选择此路径的原因。

我还尝试了第三方库 OpenCvSharp 将处理后的帧保存为视频。 我以前在 python 中做过,没有任何问题。 但是,在 UWP 中,我无法在没有 StorageFile 对象的情况下与文件系统进行交互。 因此,当我尝试将渲染的视频保存到文件系统时,我从 OpenCvSharp 得到的只是 UnauthorizedAccessException。

所以,总结一下:我需要的是一种在数据仍在输入时将我的相机帧的数据渲染到视频的方法,这样我就可以在处理后处理每一帧,就像 python OpenCV 实现一样. 我非常感谢每一个提示。 以下是我的代码的一部分,以更好地理解上下文:

private void ColorFrameArrived(MediaFrameReader sender, MediaFrameArrivedEventArgs args)
        {
            MediaFrameReference colorFrame = sender.TryAcquireLatestFrame();
            if (colorFrame != null)
            {
                if (currentMode == StreamingMode)
                {
                    colorRenderer.Draw(colorFrame, true);

                }

                if (currentMode == RecordingMode)
                {


                    MediaStreamSample sample = MediaStreamSample.CreateFromDirect3D11Surface(colorFrame.VideoMediaFrame.Direct3DSurface, new TimeSpan(0, 0, 0, 0, 33));
                    ColorComposition.Clips.Add(MediaClip.CreateFromSurface(sample.Direct3D11Surface, new TimeSpan(0, 0, 0, 0, 33)));
                }
            }

        }

private async Task CreateVideo(MediaComposition composition, string outputFileName)
        {
            try
            {
                await mediaFrameReaderColor.StopAsync();
                mediaFrameReaderColor.FrameArrived -= ColorFrameArrived;
                mediaFrameReaderColor.Dispose();

                StorageFolder folder = await documentsFolder.GetFolderAsync(directory);
                StorageFile vid = await folder.CreateFileAsync(outputFileName + ".mp4", CreationCollisionOption.GenerateUniqueName);

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                await composition.RenderToFileAsync(vid, MediaTrimmingPreference.Precise);
                stopwatch.Stop();
                Debug.WriteLine("Video rendered: " + stopwatch.ElapsedMilliseconds);

                composition.Clips.Clear();
                composition = null;
            }
            catch (Exception ex)
            {

                Debug.WriteLine(ex.Message);
            }

        }

我正在尝试在使用 MediaFrameReader 时录制相机的视频。 对于我的应用程序,我需要 MediaFrameReader 实例来单独处理每个帧。

请创建自定义视频效果并将其添加到 MediaCapture 对象以实现您的要求。 使用自定义视频效果将允许我们在不使用 MediaFrameReader 的情况下处理 MediaCapture 对象上下文中的帧,这样您提到的 MediaFrameReader 的所有限制都会消失。

此外,它还具有许多内置效果,可以让我们分析相机帧,有关更多信息,请查看以下文章:

#MediaCapture.AddVideoEffectAsync

https://docs.microsoft.com/en-us/uwp/api/windows.media.capture.mediacapture.addvideoeffectasync

#自定义视频效果

https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/custom-video-effects

#Effects 用于分析相机帧

https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/scene-analysis-for-media-capture

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM