Средство выбора мультимедиа Maui при ошибке платформы Windows

Я создал очень простое приложение MauiApp, потому что хотел попробовать MediaPicker на платформе Windows.

Поэтому я скопировал код из официальной документации и попытался запустить свое приложение .

Однако, если я добавлю к Package.appxmanifestфайл, как предложено в документации, и запустите приложение, оно дает мне следующую ошибку:

      Error       DEP0700: Registration of the app failed. [0x80080204] error 0xC00CE169: App 
manifest validation error: The app manifest must be valid as per schema: Line 39, Column 
21, Reason: 'webcam' violates enumeration constraint of 'documentsLibrary 
picturesLibrary videosLibrary musicLibrary enterpriseAuthentication 
sharedUserCertificates userAccountInformation removableStorage appointments contacts 
phoneCall blockedChatMessages objects3D voipCall chat'.
The attribute 'Name' with value 'webcam' failed to parse.   MauiApp3            
        

Поэтому, чтобы решить эту проблему, я попытался изменить возможность с <uap:Capability Name="webcam"/>к <DeviceCapability Name="webcam"/>.

Таким образом, я могу запустить приложение без ошибок, но photoвсегда равно нулю:

      public async void TakePhoto(object sender, EventArgs e)
{
    if (MediaPicker.Default.IsCaptureSupported)
    {
        FileResult photo = await MediaPicker.Default.CapturePhotoAsync();
        
        if (photo != null)
        {
            // save the file into local storage
            string localFilePath = Path.Combine(FileSystem.CacheDirectory, photo.FileName);

            using Stream sourceStream = await photo.OpenReadAsync();
            using FileStream localFileStream = File.OpenWrite(localFilePath);

            await sourceStream.CopyToAsync(localFileStream);
        }
        else
        {
            // *** IT ALWAYS ENTERS IN THE ELSE CLAUSE ***
            // *** BECAUSE photo IS ALWAYS NULL ***
            CounterBtn.Text = $"Capture is supported but {photo} is null";
        }
    }
}

Примечание. Вышеупомянутая функция вызывается, когда я нажимаю эту кнопку, которую я определил в MainPage.xamlфайл:

              <Button 
            x:Name="ImageBtn"
            Text="Take Photo"
            SemanticProperties.Hint="Take Image"
            Clicked="TakePhoto"
            HorizontalOptions="Center" />

1 ответ

К сожалению, это старая и известная ошибка для WinUI3.Майкрософт/WindowsAppSDK#1034

В качестве обходного пути вы можете создать собственный медиапикер, который наследует все от MAUI для Android, iOS и Catalyst.

Затем реализуйте собственный медиапикер для Windows, наследующий всеCapture...методы и повторная реализацияCapturePhotoAsyncиспользуя пользовательский класс для захвата камеры:

      public async Task<FileResult> CaptureAsync(MediaPickerOptions options, bool photo)
{
    var captureUi = new CameraCaptureUI(options);

    var file = await captureUi.CaptureFileAsync(photo ? CameraCaptureUIMode.Photo : CameraCaptureUIMode.Video);

    if (file != null)
        return new FileResult(file.Path,file.ContentType);

    return null;
}

это новыйCameraCaptureUIсорт:

      public async Task<StorageFile> CaptureFileAsync(CameraCaptureUIMode mode)
{
    var extension = mode == CameraCaptureUIMode.Photo ? ".jpg" : ".mp4";

    var currentAppData = ApplicationData.Current;
    var tempLocation = currentAppData.LocalCacheFolder;
    var tempFileName = $"CCapture{extension}";
    var tempFile = await tempLocation.CreateFileAsync(tempFileName, CreationCollisionOption.GenerateUniqueName);
    var token = Windows.ApplicationModel.DataTransfer.SharedStorageAccessManager.AddFile(tempFile);

    var set = new ValueSet();
    if (mode == CameraCaptureUIMode.Photo)
    {
        set.Add("MediaType", "photo");
        set.Add("PhotoFileToken", token);
    }
    else
    {
        set.Add("MediaType", "video");
        set.Add("VideoFileToken", token);
    }

    var uri = new Uri("microsoft.windows.camera.picker:");
    var result = await Windows.System.Launcher.LaunchUriForResultsAsync(uri, _launcherOptions, set);
    if (result.Status == LaunchUriStatus.Success && result.Result != null)
    {
        return tempFile;
    }

    return null;
}

Также в Package.appxmanifest добавьте следующие возможности:

      <DeviceCapability Name="microphone"/>
<DeviceCapability Name="webcam"/>

Кредиты для класса CameraCapture

Изменить: изменен код, чтобы разрешить захват видео, кредиты здесь

Другие вопросы по тегам