Основные принципы фото-, аудио- и видеозахвата с помощью MediaCapture
В этой статье показан самый простой способ записи фотографий и видео с помощью класса медиакаптуре . Класс MediaCapture предоставляет широкий набор API, которые обеспечивают низкоуровневое управление конвейером захвата и поддерживают расширенные сценарии захвата, но цель этой статьи — помочь быстро и просто добавлять в приложение основные функции захвата мультимедиа. Дополнительные сведения о возможностях, предоставляемых медиакаптуре , см. в разделе Camera.
Если вы хотите просто захватить фотографию или видео и не планируете добавлять дополнительные возможности захвата мультимедиа или не хотите создать собственный пользовательский интерфейс камеры, можно использовать класс CameraCaptureUI, который позволяет просто запустить встроенное приложение камеры Windows и получить созданную фотографию или видео. Дополнительные сведения см. в разделе Фото- и видеосъемка с помощью встроенного пользовательского интерфейса камеры в Windows.
В этой статье используется код, адаптированный из примера Начальный набор камеры. Вы можете скачать этот пример, чтобы просмотреть код в контексте или использовать пример как отправную точку для настройки собственного приложения.
Добавление объявлений возможностей в манифест приложения
Чтобы ваше приложение получило доступ к камере устройства, необходимо объявить, что оно использует возможности устройства webcam и microphone. Если нужно сохранить захваченные фотографии и видео в библиотеке изображений или видео пользователя, следует также объявить возможности picturesLibrary и videosLibrary.
Добавление возможностей в манифест приложения
- В Microsoft Visual Studio откройте конструктор манифеста приложения, дважды щелкнув элемент package.appxmanifest в Обозревателе решений.
- Перейдите на вкладку Возможности.
- Выставьте флажок для пункта Веб-камера и поле для параметра Микрофон.
- Для доступа к библиотеке изображений и видео установите флажки Библиотека изображений и Библиотека видео.
Инициализация объекта MediaCapture
Для всех методов захвата, описанных в этой статье, сначала требуется инициализировать объект MediaCapture, вызвав конструктор и затем — InitializeAsync. Так как доступ к объекту MediaCapture будет осуществляться из различных областей приложения, объявите переменную класса для размещения объекта. Реализуйте обработчик для свойства Failed объекта MediaCapture, чтобы получить уведомление, если операция захвата завершится ошибкой.
Настройка просмотра камеры
Можно захватывать фотографии, видео и звук с помощью MediaCapture без показа изображения камеры, но обычно это необходимо, чтобы пользователь видел, что именно записывается. Кроме того, для использования некоторых функций MediaCapture, таких как автоматическая фокусировка, экспозиция и регулировка баланса белого, необходим поток предварительного просмотра. Сведения о настройке предварительного просмотра камеры см. в разделе Отображение просмотра камеры.
Захват фотографии в классе SoftwareBitmap
Класс SoftwareBitmap появился в Windows 10 и используется в качестве общего представления изображений для многих функций. Если вы хотите записать фотографию, а затем сразу использовать полученное изображение в приложение, например показать его в коде XAML, вместо записи в файл следует записать его в класс SoftwareBitmap. Вы по-прежнему сможете сохранить изображение на диск позднее.
После инициализации объекта MediaCapture вы можете записать фотографию в SoftwareBitmap с помощью класса LowLagPhotoCapture. Получите экземпляр класса, вызвав метод PrepareLowLagPhotoCaptureAsync и передав объект ImageEncodingProperties, указывающий нужный формат изображения. CreateUncompressed создает несжатую кодировку с заданным форматом пикселя. Чтобы захватить фотографию, вызовите метод CaptureAsync, который возвращает объект CapturedPhoto. Получите объект SoftwareBitmap с помощью свойств Frame и SoftwareBitmap.
При желании можно получить несколько фотографий, повторно вызывая CaptureAsync. Получив нужные данные, вызовите FinishAsync для завершения сеанса LowLagPhotoCapture и освобождения связанных ресурсов. Чтобы начать захват фотографий после вызова метода FinishAsync, потребуется снова вызвать PrepareLowLagPhotoCaptureAsync для повторной инициализации сеанса захвата перед вызовом CaptureAsync.
Начиная с Windows версии 1803, вы можете получить доступ к свойству BitmapProperties класса CapturedFrame, полученного из метода CaptureAsync для извлечения метаданных о записанной фотографии. Эти данные можно передать в BitmapEncoder, чтобы сохранения метаданные в файл. Ранее не было возможности получить доступ к этим данным для изображений в несжатых форматах. Также вы можете использовать свойство ControlValues, чтобы получить объект CapturedFrameControlValues, который описывает контрольные значения, например, экспозицию и баланс белого в записанном кадре.
Дополнительные сведения о работе с BitmapEncoder и объектом SoftwareBitmap, включая метод отображения такого объекта на XAML-странице, см. в статье Создание, редактирование и запись растровых изображений.
Дополнительные сведения о задании контрольных значений устройства захвата см. в разделе Контрольные значения устройства захвата фотографий и видео.
Начиная с Windows 10 версии 1803, вы можете получить метаданные, такие как EXIF, для фотографий, записанных в формате без сжатия, использовав свойство BitmapProperties свойство объекта CapturedFrame, возвращаемого MediaCapture. В предыдущих выпусках эти данные были доступны только в заголовке фотографий, записанных в файловых форматах со сжатием. Эти данные можно передать в BitmapEncoder при записи файла изображения вручную. Дополнительные сведения про запись растровых изображений см. в статье Создание, редактирование и запись растровых изображений. Можно также получить доступ к контрольным значениям кадра, например, параметрам экспозиции и вспышки, которые применялись при записи кадра, обратившись к свойству ControlValues. Дополнительные сведения см. в разделе Контрольные значения устройства захвата фотографий и видео.
Фотозахват в файл
Типичное фотоприложение сохраняет полученные фотографии на диск или в облачное хранилище, а также добавляет метаданные, например сведения об ориентации фотографии, в файл. В следующем примере показано, как записать фотографию в файл. Вы по-прежнему сможете создать объект SoftwareBitmap на основе изображения позже.
Способ, показанный в этом примере, позволяет получить фотографию в поток в памяти и преобразовать фотографию из потока в файл на диске. В этом примере используется метод GetLibraryAsync, чтобы получить библиотеку изображений пользователя, а затем свойство SaveFolder, чтобы получить папку для сохранения по умолчанию. Не забывайте добавить возможность Библиотека изображений в манифест приложения для доступа к этой папке. CreateFileAsync создает объект StorageFile, в котором будет сохранена фотография.
Создайте объект InMemoryRandomAccessStream и вызовите метод CapturePhotoToStreamAsync, чтобы записать фотографию в поток, передав методу поток и объект ImageEncodingProperties, указывающий формат изображения. Вы можете создавать пользовательские свойства кодирования, инициализируя объект самостоятельно, но класс предоставляет статические методы, такие как ImageEncodingProperties.CreateJpeg, для распространенных форматов кодирования. Затем создайте файловый поток для выходного файла, вызвав метод OpenAsync. Создайте объект BitmapDecoder для декодирования изображения из потока в памяти, а затем создайте BitmapEncoder для кодировки изображения в файл, вызвав метод CreateForTranscodingAsync.
Вы также можете создать объект BitmapPropertySet и затем вызвать метод SetPropertiesAsync кодировщика изображения, чтобы добавить метаданные фотографии в файл изображения. Подробнее о свойствах кодирования см. в разделе Метаданные изображения. Для большинства приложений важно правильно определять ориентацию приложения. Подробнее: Обработка ориентации устройства и экрана с помощью MediaCapture.
Наконец, вызовите метод FlushAsync объекта кодировщика, чтобы перекодировать фотографию из потока в памяти в файл.
Дополнительные сведения о работе с файлами и папками см. в разделе Файлы, папки и библиотеки.
Видеозахват
Вы можете быстро реализовать возможности видеозахвата в свое приложение с помощью класса LowLagMediaRecording. Сначала объявите переменную класса для объекта.
Затем создайте объект StorageFile, в котором будет сохранено видео. Обратите внимание, что для сохранения в видеобиблиотеке пользователя, как показано в этом примере, необходимо добавить возможность Библиотека видео в манифест приложения. Вызовите метод PrepareLowLagRecordToStorageFileAsync, чтобы инициализировать запись мультимедиа, передав файл и объект MediaEncodingProfile, определяющий кодировку видео. Этот класс содержит статические методы, такие как CreateMp4, для создания профилей кодирования популярных форматов.
Наконец, вызовите метод StartAsync, чтобы приступить к записи видео.
Чтобы остановить запись видео, вызовите метод StopAsync.
Вы можете продолжить вызывать методы StartAsync и StopAsync для записи дополнительных видео. Закончив захват видео, вызовите метод FinishAsync, чтобы закрыть сеанса захвата и освободить связанные ресурсы. Затем необходимо вызвать метод PrepareLowLagRecordToStorageFileAsync снова, чтобы повторно инициализировать сеанс захвата перед вызовом StartAsync.
При захвате видео вам нужно зарегистрировать обработчик события RecordLimitationExceeded объекта MediaCapture, которое будет вызвано операционной системой, если вы подавляете временное ограничение для одной записи (в настоящее время — это три часа). В обработчике события необходимо также завершить запись, вызвав метод StopAsync.
Воспроизведение и редактирование записанных видеофайловЗаписав видео в файл, его можно загрузить и воспроизвести в пользовательском интерфейсе вашего приложения. Это можно сделать с помощью элемента управления XAML MediaPlayerElement и связанным с ним MediaPlayer. Дополнительные сведения о воспроизведения медиа на XAML-странице см. в разделе Воспроизведение аудио и видео с помощью MediaPlayer.
Вы также можете создать объект MediaClip из видеофайла, вызвав метод CreateFromFileAsync. Объект MediaComposition предоставляет основные функции для редактирования видео, например, расстановка последовательности объектов MediaClip, уменьшение продолжительности видео, создание слоев, добавление фоновой музыки и применение видеоэффектов. Дополнительные сведения о работе с медиакомпозициями см. в разделе Медиакомпозиции и их редактирование.
Приостановка и возобновление видеозаписи
Вы можете приостановить видеозапись, а затем продолжить ее, не создавая отдельный выходной файл, вызвав метод PauseAsync, а затем — ResumeAsync.
Начиная с Windows 10 версии 1607 вы можете приостановить видеозапись и получить последний кадр, записанный до приостановки. Затем можно накладывать этот кадр в режиме предварительного просмотра камеры пользователь мог, чтобы выровнять камеру с приостановлено кадра, прежде чем возобновлять запись. Метод PauseWithResultAsync возвращает объект MediaCapturePauseResult. Свойство LastFrame — это объект VideoFrame, представляющий последний кадр. Чтобы показать кадр в XAML, получите представление кадра в форме класса SoftwareBitmap. В данный момент поддерживаются только изображения в формате BGRA8 с предварительно умноженным или пустым альфа-каналом, поэтому вызовите метод Convert при необходимости, чтобы получить правильный формат. Создайте объект SoftwareBitmapSource и вызовите метод SetBitmapAsync, чтобы инициализировать его. Наконец настройте свойство Source XAML-элемента управления Image, чтобы показать изображения. Чтобы это сработало, изображение должно быть выровнено с элементом управления CaptureElement, а значение непрозрачности должно быть меньше одного. Не забывайте, что изменить интерфейс можно только в потоке пользовательского интерфейса, поэтому этот вызов следует выполнить в пределах RunAsync.
Метод PauseWithResultAsync также возвращает длительность записанного в предыдущем сегменте видео, если вам нужно отслеживать общее время записи.
Если вы продолжаете запись, вы можете указать источник изображения как NULL и скрыть его.
Обратите внимание, что вы также можете получить стоп-кадр после остановки видео с помощью метода StopWithResultAsync.
Запись звука
Вы можете быстро добавить в приложение возможности записи звука, используя способ захвата видео, описанный выше. В примере ниже создается объект StorageFile создается в папке данных приложения. Вызовите метод PrepareLowLagRecordToStorageFileAsync, чтобы инициализировать сеанс захвата, передав файл и объект MediaEncodingProfile, который в этом примере создается статическим методом CreateMp3. Чтобы начать запись, вызовите метод StartAsync.
Вызовите метод StopAsync, чтобы остановить запись звука.
Связанные темы
Вы можете вызвать методы StartAsync и StopAsync несколько раз, чтобы записать несколько звуковых файлов. Закончив захват звука, вызовите метод FinishAsync, чтобы закрыть сеанса захвата и освободить связанные ресурсы. Затем необходимо вызвать метод PrepareLowLagRecordToStorageFileAsync снова, чтобы повторно инициализировать сеанс захвата перед вызовом StartAsync.
Обнаружение изменения громкости звука системой и реагирование на это событие
Начиная с Windows 10 версии 1803, ваше приложение может обнаружить, что система уменьшила громкость звука или отключило звук для потоков записи и обработки вашего приложения. Например, система может отключить звук в потоках вашего приложения, при переводе последнего в фоновый режим. В классе AudioStateMonitor можно зарегистрировать обработчик события, отправляемого когда система изменяет громкость звукового потока. Получите экземпляр AudioStateMonitor для отслеживания потоков записи звука, вызвав метод CreateForCaptureMonitoring. Получите экземпляр для наблюдения за потоками обработки звуковых данных, вызвав метод CreateForRenderMonitoring. Зарегистрируйте обработчик для события SoundLevelChanged каждого средства наблюдения, чтобы получать уведомления про изменение системой громкости звука для потоков соответствующей категории.
В обработчике SoundLevelChanged для потока записи вы можете проверить свойство SoundLevel отправителя AudioStateMonitor, и определить новую уровень громкости. Обратите внимание, что система никогда не должна уменьшать уровень громкости потока записи. Он должен либо отключаться совсем либо включаться обратно с полной громкостью. Если звуковой поток выключен, вы можете остановить процесс идущей записи. Если громкость звукового потока восстановлена до полного уровня, вы можете возобновить запись. В следующем примере в нескольких переменных класса Boolean отслеживается процесс записи звука приложением и была ли запись остановлена из-за изменения громкости звука. С помощью этих переменных можно определить, когда стоит программно запустить или остановить аудиозапись.
В следующем примере кода показана реализация обработчика SoundLevelChanged для вывода звука. В зависимости от вашего сценария приложения и типа воспроизводимого содержимого, возможно, потребуется приостановить воспроизведение при выключении звука. Дополнительные сведения о том, как реагировать на изменение громкости звука при воспроизведении мультимедиа см. в разделе Воспроизведение аудио и видео с помощью MediaPlayer.