控制台模板应用程序MediaCapture无法录制视频 - c#

我试图在基于C#UWP控制台模板的最小应用程序上使用MediaCapture来捕获视频。使用InitializeAsync()初始化MediaCapture可以,但是实际上开始录制失败,错误代码为0xc00d3e82 / MF_E_INVALID_STATE_TRANSITION。

我已在Visual Studio 2017中安装了C#UWP控制台应用程序模板,以在可以使用MediaCapture捕获视频的最小应用程序(在这种情况下不需要GUI,因此是控制台应用程序)上工作。最低目标是Windows build 1803,因为这是C#UWP控制台应用程序所需的最低要求。

我尝试用ConfigureAwait(false)运行需要等待的方法,但这似乎没有任何区别。

关于功能,由于UWP控制台应用程序将不会显示获取对摄像机,麦克风等的访问权限的权限提示,因此在运行之前,我会通过应用程序的设置手动授予它们。我相信所有必要的功能都已包含在清单中,因为该应用程序在某些情况下确实可以工作(请参见代码块后面的段落)。

最小的可复制示例,应使用C#UWP控制台应用程序模板构建并运行:

using System;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using Windows.Storage;

namespace MinimalMediaCaptureConsoleTest
{
    class Program
    {
        private static void MediaCapture_Failed(MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs)
        {
            Console.WriteLine("Media capture failed: error message: '" + errorEventArgs.Message + "', code: " + errorEventArgs.Code.ToString("X"));
        }
        static void Main(string[] args)
        {
            Task t = MainAsync(args);
            t.Wait();
            Task.Delay(2000).Wait(); // give time to see result before exiting
        }
        static async Task MainAsync(string[] args)
        {
            var videoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
            var cameraDevice = videoDevices[0];
            if (cameraDevice == null)
            {
                Console.WriteLine("No camera device found!");
                return;
            }

            MediaCapture mc = new MediaCapture();
            MediaCaptureInitializationSettings mcSettings = new MediaCaptureInitializationSettings
            {
                AudioDeviceId = "",
                VideoDeviceId = cameraDevice.Id,
                StreamingCaptureMode = StreamingCaptureMode.Video,
                PhotoCaptureSource = PhotoCaptureSource.VideoPreview
            };
            mc.Failed += MediaCapture_Failed;
            try
            {
                await mc.InitializeAsync(mcSettings);

            } catch (UnauthorizedAccessException e)
            {
                Console.WriteLine("No access to the camera: " + e);
            }

            LowLagMediaRecording mediaRecording = null;
            var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
            StorageFile file = await myVideos.SaveFolder.CreateFileAsync("mytestvid.mp4", CreationCollisionOption.GenerateUniqueName);
            mediaRecording = await mc.PrepareLowLagRecordToStorageFileAsync(
                      MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), file);

            await mediaRecording.StartAsync();
            Console.WriteLine("Started recording, press enter to stop");
            Console.ReadLine();
            await mediaRecording.StopAsync();
        }
    }
}

该代码在从控制台应用程序的Main()启动的单独的异步任务中运行,但是我也尝试过使Main本身成为一个异步任务,并直接从那里运行MediaCapture代码,而在性能上没有差异。

有趣的是,如果我在尝试录制视频之前使用Visual Studio的调试器运行该应用程序,或者将该调试器附加到进程中,则视频捕获就可以正常工作。但是,如果从命令提示符/ Powershell或开始菜单运行,则调用LowLagMediaRecording实例的StartAsync()方法将导致上述错误代码0xc00d3e82 / MF_E_INVALID_STATE_TRANSITION,并且不会录制任何视频。

非常感谢在没有调试器的情况下运行时出现什么问题以及如何解决它的任何想法。

参考方案

成为UWP应用程序有什么特殊原因吗? (UWP控制台应用程序和后台录制可能存在某些问题/并发症)
如果UWP不重要,那么您也可以在Win32控制台应用程序中使用MediaCapture,在这种情况下,它似乎更适合(也是更简单的解决方案),
对于C#,请参考-
https://github.com/microsoft/WindowsVisionSkillsPreview/blob/master/samples/SentimentAnalyzerCustomSkill/cs/Apps/FaceSentimentAnalysisApp_.NETCore3.0/FaceSentimentAnalysisApp_.NETCore3.0.csproj

注意:此C#示例不仅仅具有Windows MediaCapture的功能。但是,您可以忽略其他内容,而仅引用示例中的项目配置,并使用与当前相同的C#代码。
您需要使用.Net Core 3.0和Visual Studio 2019预览版。
上面的.csproj文件中的以下几行至关重要:

C:\ Program Files(x86)\ Reference Assemblys \ Microsoft \ Framework.NETCore \ v4.5 \ System.Runtime.WindowsRuntime.dll

<Reference Include="Windows">
  <HintPath>C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Facade\Windows.WinMD</HintPath>
  <IsWinMDFile>true</IsWinMDFile>
</Reference>

<Reference Include="Windows.Foundation.FoundationContract">
  <HintPath>C:\Program Files (x86)\Windows Kits\10\References\10.0.17763.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd</HintPath>
  <IsWinMDFile>true</IsWinMDFile>
</Reference>

<Reference Include="Windows.Foundation.UniversalApiContract">
  <HintPath>C:\Program Files (x86)\Windows Kits\10\References\10.0.17763.0\Windows.Foundation.UniversalApiContract\7.0.0.0\Windows.Foundation.UniversalApiContract.winmd</HintPath>
  <IsWinMDFile>true</IsWinMDFile>
</Reference>

另外,对于C ++,请参考-https://github.com/microsoft/Windows-Camera/tree/master/Samples/WMCConsole_winrtcpp

jQuery不起作用 - php

我正在使用带有ajax的jquery。有时,给出错误$未定义。这是我的代码:<script language="javascript" type="text/javascript"> var base_path="<? echo $this->baseUrl().'/…

无法解析Json响应 - php

我正在尝试解析一个包含产品类别的JSON文件,然后解析这些类别中的产品,并在div中显示它们。我的问题:虽然我可以获取类别,但我不知道如何索取产品(并将它们显示在类别下)。我的剧本:<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> …

<T>如何在这里处理String和Integer - java

我不明白T如何使用Integer和String。如此处显示功能中所示,T同时处理整数和字符串。该代码如何工作?class firstBase { <T> void display(T give_num, T give_String) { System.out.println("The given number is = " +…

Div单击与单选按钮相同吗? - php

有没有一种方法可以使div上的click事件与表单环境中的单选按钮相同?我只希望下面的div提交值,单选按钮很丑代码输出如下:<input id="radio-2011-06-08" value="2011-06-08" type="radio" name="radio_date&#…

使用javascript在客户端的列表视图中选择所有复选框 - javascript

我有一个列表视图,在标题中有一个复选框。如果标题复选框已选中/未选中,我想选择行中的所有复选框。如何在客户端实现此目标?这是ListView设计代码。<asp:ListView ID="lvTypes" runat="server" GroupPlaceholderID="groupPlaceHolde…