Базовые фото, видео и аудиозапись с помощью MediaCapture в приложении WinUI 3
В этой статье показан самый простой способ записи фотографий и видео с помощью класса MediaCapture. Класс MediaCapture предоставляет надежный набор API, обеспечивающий низкоуровневый контроль над конвейером захвата и включение расширенных сценариев записи, но эта статья предназначена для быстрого и простого добавления базового захвата мультимедиа в приложение. Дополнительные сведения о функциях, предоставляемых MediaCapture, см. в разделе Камеры.
Инициализация объекта MediaCapture
Все методы захвата, описанные в этой статье, требуют первого шага инициализации объекта MediaCapture. Это включает создание экземпляра объекта, выбор устройства записи, задание параметров инициализации, а затем вызов InitializeAsync. Обычно приложения камеры будут отображать предварительный просмотр камеры при записи фотографий или видео в пользовательском интерфейсе с помощью MediaPlayerElement. Пошаговое руководство по инициализации MediaCapture и отображению предварительного просмотра в пользовательском интерфейсе XAML см. в статье Показ предварительного просмотра камеры в приложении WinUI 3. В примерах кода в этой статье предполагается, что уже создан инициализированный экземпляр MediaCapture.
Запись фотографии в SoftwareBitmap
Класс SoftwareBitmap предоставляет общее представление изображений в нескольких функциях. Если вы хотите записать фотографию, а затем сразу же использовать захваченный образ в приложении, например отображение его в XAML, а не запись в файл, необходимо записать в SoftwareBitmap. Вы по-прежнему можете сохранить образ на диск позже.
Захватить фотографию в SoftwareBitmap с помощью класса LowLagPhotoCapture. Получите экземпляр этого класса, вызвав
Вы можете записывать несколько фотографий, многократно вызывая CaptureAsync. После завершения записи вызовите FinishAsync, чтобы завершить работу сеанса LowLagPhotoCapture и освободить связанные ресурсы. После вызова FinishAsync, чтобы снова начать захватывать фотографии, необходимо снова вызвать PrepareLowLagPhotoCaptureAsync для повторной инициализации сеанса захвата перед вызовом CaptureAsync.
// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));
var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;
// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();
Запись фотографии в поток памяти
Вы можете использовать MediaCapture для записи фотографии в поток в памяти, который затем можно использовать для перекодирования фотографии из потока в файл на диске.
Создайте InMemoryRandomAccessStream, а затем вызовите CapturePhotoToStreamAsync для захвата фотографии в поток, передавая поток и объект ImageEncodingProperties, указывающий формат изображения, который следует использовать. Вы можете создавать настраиваемые свойства кодирования, инициализировав объект самостоятельно, но класс предоставляет статические методы, такие как ImageEncodingProperties.CreateJpeg для распространенных форматов кодирования.
Создайте BitmapDecoder, чтобы декодировать изображение из потока памяти. Создайте BitmapEncoder для кодирования изображения в файл с вызовом CreateForTranscodingAsync.
При необходимости можно создать объект BitmapPropertySet, а затем вызвать SetPropertiesAsync в кодировщике изображений, чтобы включить метаданные о фотографии в файл изображения. Дополнительные сведения о свойствах кодирования см. в метаданных изображения.
Наконец, вызовите FlushAsync в объекте кодировщика, чтобы перекодировать фотографию из потока в памяти в файл.
// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));
var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;
// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();
Запись видео
Быстрое добавление видеозахвата в приложение с помощью класса LowLagMediaRecording.
Во-первых, LowLagMediaRecording необходимо сохранять во время записи видео, поэтому объявите переменную класса для объекта.
LowLagMediaRecording m_mediaRecording;
Вызовите PrepareLowLagRecordToStorageFileAsync для инициализации записи мультимедиа, передав в качестве параметра файл хранилища и объект MediaEncodingProfile, определяющий кодировку видео. Класс предоставляет статические методы, такие как CreateMp4для создания общих профилей кодирования видео. Вызовите StartAsync, чтобы начать запись видео.
var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("video.mp4", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), file);
m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;
await m_mediaRecording.StartAsync();
Чтобы остановить запись видео, вызовите StopAsync.
await m_mediaRecording.StopAsync();
Вы можете продолжать вызывать StartAsync и StopAsync для записи дополнительных видео. Когда вы завершите запись видео, вызовите FinishAsync, чтобы удалить сеанс захвата и очистить связанные ресурсы. После этого вызова необходимо снова вызвать PrepareLowLagRecordToStorageFileAsync, чтобы повторно инициализировать сеанс записи перед вызовом StartAsync.
await m_mediaRecording.FinishAsync();
При захвате видео следует зарегистрировать обработчик для события RecordLimitationExceeded объекта MediaCapture, которое будет вызвано операционной системой при превышении ограничения на одну запись, в настоящее время составляющее три часа. В обработчике события необходимо завершить запись, вызвав StopAsync.
private async void m_mediaCapture_RecordLimitationExceeded(MediaCapture sender)
{
await m_mediaRecording.StopAsync();
DispatcherQueue.TryEnqueue(() =>
{
tbStatus.Text = "Record limitation exceeded.";
});
}
Вы можете приостановить запись видео, а затем возобновить запись без создания отдельного выходного файла, вызвав PauseAsync, а затем вызвав ResumeAsync.
await m_mediaRecording.PauseAsync(Windows.Media.Devices.MediaCapturePauseBehavior.ReleaseHardwareResources);
await m_mediaRecording.ResumeAsync();
Вызов PauseWithResultAsync возвращает объект MediaCapturePauseResult. Свойство LastFrame — это объект VideoFrame, представляющий последний кадр. Чтобы отобразить кадр в XAML, получите представление кадра видео как SoftwareBitmap. В настоящее время поддерживаются только изображения в формате BGRA8 с премультиплицированным или пустым альфа-каналом, поэтому при необходимости вызовите для преобразования, чтобы получить правильный формат. PauseWithResultAsync также возвращает длительность видео, записанного в предыдущем сегменте, если необходимо отслеживать общее время записи.
При остановке видео можно также получить результирующий кадр, вызвав StopWithResultAsync.
Воспроизведение и изменение захваченных видеофайлов
После записи видео в файл может потребоваться загрузить файл и воспроизвести его в пользовательском интерфейсе приложения. Это можно сделать с помощью контрола MediaPlayerElement XAML и связанного MediaPlayer. Сведения о воспроизведении мультимедиа на странице XAML см. в разделе Воспроизведение звука и видео с помощью MediaPlayer.
[ТБD — поддерживается ли платформа MediaComposition / рекомендуется для WinUI?]
Вы также можете создать объект MediaClip из видеофайла, вызвав CreateFromFileAsync. MediaComposition предоставляет основные функции редактирования видео, такие как упорядочивание последовательности объектов MediaClip, обрезка длины видео, создание слоев, добавление фоновой музыки и применение эффектов видео. Дополнительные сведения о работе с композициями мультимедиа см. в разделе Композиции мультимедиа и редактирование.
Запись звука
Вы можете быстро добавить звукозапись в приложение с помощью того же метода, который показан выше для записи видео. Вызовите PrepareLowLagRecordToStorageFileAsync для инициализации сеанса захвата, передав файл и объект MediaEncodingProfile, который создается в этом примере статическим методом CreateMp3. Чтобы начать запись, вызовите StartAsync.
ТBD — этот код генерирует сообщение об ошибке: "Запрос недопустим в текущем состоянии".
m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;
var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("audio.mp3", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High), file);
await m_mediaRecording.StartAsync();
Вызовите StopAsync, чтобы остановить запись звука.
await m_mediaRecording.StopAsync();
Вы можете вызывать StartAsync и StopAsync несколько раз для записи нескольких звуковых файлов. Когда вы завершите запись звука, вызовите FinishAsync, чтобы удалить сеанс записи и очистить связанные ресурсы. После этого вызова необходимо снова вызвать PrepareLowLagRecordToStorageFileAsync, чтобы повторно инициализировать сеанс записи перед вызовом StartAsync.
Для получения информации об обнаружении момента, когда система изменяет уровень звука в потоке захвата звука, см. обнаружение и реагирование на изменения уровня звука системой.
Windows developer