Приложение-шаблон консоли MediaCapture не может записывать видео

Я пытаюсь использовать MediaCapture в минимальном приложении на основе шаблона консоли UWP C # для захвата видео. Инициализация MediaCapture с помощью InitializeAsync () работает, но при запуске записи происходит сбой с кодом ошибки 0xc00d3e82 / MF_E_INVALID_STATE_TRANSITION.

Я установил шаблоны консольных приложений C # UWP в Visual Studio 2017 для работы с минимальным приложением (графический интерфейс в данном случае не нужен, следовательно, консольное приложение), которое будет захватывать видео с помощью MediaCapture. Минимальная цель - сборка Windows 1803, поскольку это минимум, необходимый для консольных приложений C # UWP.

Я пробовал запускать методы, требующие await, с 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 или меню «Пуск» вызов метода StartAsync () экземпляра LowLagMediaRecording приведет к вышеупомянутому коду ошибки 0xc00d3e82 / MF_E_INVALID_STATE_TRANSITION, и видео не будет записано.

Мы очень ценим любые идеи, в чем проблема при запуске без отладчика и как это исправить.


person ExplodingDeveloper    schedule 31.05.2019    source источник
comment
Не могли бы мы поделиться с нами минимальным воспроизводимым примером?   -  person Nico Zhu - MSFT    schedule 05.06.2019
comment
Обновлен образец кода для лучшего минимально воспроизводимого примера.   -  person ExplodingDeveloper    schedule 06.06.2019


Ответы (1)


Есть ли какая-то особая причина для того, чтобы это было приложение UWP? (могут быть определенные проблемы / сложности с консольными приложениями UWP и фоновой записью). Если UWP не важен, вы также можете использовать MediaCapture в консольном приложении Win32, которое кажется более подходящим (и более простым решением) в этой ситуации - для 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 Assemblies \ 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>

Alternatively for C++ refer to - https://github.com/microsoft/Windows-Camera/tree/master/Samples/WMCConsole_winrtcpp

person SpeedCoder    schedule 04.06.2019
comment
К сожалению, в этом случае я не могу легко повлиять на выбор UWP. Жаль, что, похоже, не так много подробной официальной документации об ограничениях консольных приложений UWP, только отдельные фрагменты здесь и там, или, по крайней мере, мне, кажется, трудно ее найти. Тем не менее, спасибо за указатели Win32; даже если они не применяются напрямую, может быть, они дадут мне какие-то косвенно полезные идеи. - person ExplodingDeveloper; 04.06.2019
comment
Подтверждено, что это неподдерживаемый сценарий. Поскольку UWP не поддерживает «запуск» видеозаписи без видимого изображения на переднем плане. Консольное приложение не имеет представления и, следовательно, не может записывать видео. Однако вы можете создать пустое приложение UWP (с пустым окном) и запускать его с консоли по мере необходимости, это должно иметь возможность записывать видео, пока оно находится на переднем плане. - person SpeedCoder; 06.06.2019
comment
Я предполагал, что для этой цели использовались бы ограниченные возможности backgroundMediaRecording. Однако теперь, когда я перечитал его описание, оно действительно не противоречит требованию наличия видимого изображения на переднем плане. Тогда я полагаю, что это минимальный графический интерфейс. - person ExplodingDeveloper; 06.06.2019
comment
backgroundMediaRecording позволит вам продолжить запись, когда она свернута. Однако вам нужен видимый обзор только для того, чтобы начать запись. Также обратите внимание, что backgroundMediaRecording - это ограниченная возможность, что означает, что потребуются специальные разрешения / проверка, если / когда это приложение необходимо отправить в магазин Microsoft. - person SpeedCoder; 06.06.2019