Воспроизведение видео

180

Все, что написано в предыдущей статье о классе MediaElement, применимо не только к аудио-, но и к видеофайлам.

Ключевое отличие видео от звука состоит лишь в необходимости визуализации содержимого и добавлении свойств, связанных с добавлением элемента MediaElement. Исходные размеры рамки определяются свойствами NaturalVideoHeight и NaturalVideoWidth элемента MediaElement.

С помощью свойства Stretch рамку можно масштабировать или растягивать. Доступны значения None (вывод рамки с исходными размерами; рекомендуется для обеспечения максимальной производительности), Uniform (рамка растягивается, насколько позволяют размеры контейнера; пропорции сохраняются; это значение установлено по умолчанию), Fill (рамка растягивается до размеров контейнера; пропорции не сохраняются) и UniformToFill (рамка растягивается, насколько позволяет больший размер контейнера; заполняется все пространство контейнера; пропорции сохраняются; не поместившаяся часть видеосодержимого отсекается).

Рекомендуется задать размеры элемента MediaEiement такими же, как исходные размеры, определенные в видеофайле. Например, если создать элемент MediaEiement, присвоить его свойству Stretch значение Uniform и поместить его в строку Grid, свойство Height которой имеет значение Auto, то строка Grid примет исходные размеры видеофайла. Масштабирование не понадобится.

Управление скоростью воспроизведения

В Silverlight встроен специальный режим воспроизведения, позволяющий ускорять или замедлять воспроизведение видео, не изменяя тональность звуковой дорожки (напомним, что в обычном режиме при ускорении видео звуки становятся более высокими, а при замедлении — более низкими; при большом изменении скорости звук может измениться до такой степени, что станет неразборчивым).

Специальный режим воспроизведения полезен только в определенных ситуациях. Например, он позволяет опытным пользователям быстрее просматривать видеокурсы. Важно отметить также, что специальный режим воспроизведения может применяться не только к видеофайлам, но и к звуковому сопровождению без видео.

Чтобы включить специальный режим воспроизведения, нужно присвоить свойству MediaEiement.PlaybackRate определенное значение. По умолчанию оно имеет значение 1, в результате чего выполняется нормальное воспроизведение. При значении 1.5 источник выполняется на 50% быстрее, а при значении 2 — вдвое быстрее. Аналогично можно уменьшить скорость воспроизведения, присвоив значение меньше единицы. Например, при значении 0.5 скорость воспроизведения уменьшается в два раза, причем тоже без изменения тональности.

Ниже приведен код ползунка, позволяющий протестировать специальный режим воспроизведения. При перемещении ползунка его новое значение передается объекту MediaEiement через простое выражение связывания (частично изменен пример аудиоплеера, показанного в предыдущей статье). При этом скорость воспроизведения немедленно изменяется:

<MediaElement x:Name="media" AutoPlay="False" Source="OldSpice.mp4" Stretch="Uniform" MediaOpened="media_MediaOpened"
         Grid.ColumnSpan="2" HorizontalAlignment="Center" />
    ...
<Slider Value="{Binding ElementName=media, Path=PlaybackRate, Mode=TwoWay}" Grid.Row="4" Grid.Column="1" 
         Maximum="4" Minimum="0" />

Учитывайте, что при слишком большой или малой скорости воспроизведения данный эффект не проявится. Например, при скорости в четыре раза больше нормальной вы, скорее всего, не услышите никакого звука вообще.

Мультимедийные команды

В Silverlight встроены средства получения команд воспроизведения от специальных кнопок, например тех, что расположены на панели клавиатуры. Это такие команды, как воспроизведение, пауза, перемотка, увеличение громкости и т.д.

Запустить мультимедийную команду можно с помощью беспроводного устройства наподобие домашнего театра (обычно такие устройства используются совместно с Windows Media Center) или с помощью расширенной мультимедийной клавиатуры, содержащей специальные кнопки. При нажатии кнопки на клавиатура надстройка Silverlight получает сообщение об этом и генерирует событие MediaCommand элемента, имеющего фокус. Событие поднимается вверх по иерархии элементов, пока не достигает объекта страницы.

Технически объект MediaCommand не связан с элементом MediaElement. События MediaCommand передаются всем элементам Silverlight. Разработчик приложения сам решает, что должно сделать приложение при получении мультимедийной команды. Чаще всего имеет смысл выполнить какую-либо операцию в MediaElement (например, запустить воспроизведение видео), однако разработчик может закодировать любую другую реакцию, например выполнение какой-либо процедуры или запуск анимации.

При использовании мультимедийных команд необходимо учитывать, что, если приложение выполняется в полноэкранном режиме, они, скорее всего, будут неработоспособными. Это объясняется тем, что операционная система перехватывает мультимедийные команды и направляет их соответствующим программам (таким, как Media Player в Windows или iTunes в Mac). Даже когда эти программы не выполняются, операционная система все равно перехватывает и подавляет мультимедийные команды.

На рисунке ниже показана программа Silverlight (измененный аудиоплеер), в которой используются мультимедийные команды. Интерфейс программы содержит кнопку, переключающую ее в полноэкранный режим. Проверьте, перехватываются ли мультимедийные команды в вашей системе. Ниже приведен обработчик щелчка на кнопке:

private void cmdFull_Click_1(object sender, RoutedEventArgs e)
{
      Application.Current.Host.Content.IsFullScreen =
           !Application.Current.Host.Content.IsFullScreen;
}
Видеостраница, получающая мультимедийные команды

Можно создать страницу, содержащую более одного раздела с выполняемым содержимым, однако в большинстве приложений используется только один раздел, как в данном примере. В этом случае легче всего подключить обработчик события MediaCommand к корневому элементу, чтобы страница получала мультимедийные команды независимо от того, какой элемент имеет фокус:

<UserControl x:Class="SilverlightMedia.MainPage"
    ...
    MediaCommand="UserControl_MediaCommand_1">
    ...

Теперь остается лишь закодировать реакцию на фактическое событие. Ниже приведен код, обрабатывающий три возможные мультимедийные команды: воспроизведение, пауза и переключение между воспроизведением и паузой. Соответствующие кнопки есть почти на всех мультимедийных клавиатурах:

private void UserControl_MediaCommand_1(object sender, MediaCommandEventArgs e)
{
            if (e.MediaCommand == System.Windows.Media.MediaCommand.Play)
            {
                media.Play();
            }
            else if (e.MediaCommand == System.Windows.Media.MediaCommand.Pause)
            {
                media.Pause();
            }
            else if (e.MediaCommand == System.Windows.Media.MediaCommand.TogglePlayPause)
            {
                if (media.CurrentState == MediaElementState.Paused ||
                    media.CurrentState == MediaElementState.Stopped)
                {
                    media.Play();
                }
                else if (media.CurrentState == MediaElementState.Playing)
                    media.Pause();
            }
}

Данный код довольно "многословный", потому что в ссылках на перечисление MediaCommand приходится писать полностью квалифицированные имена System.Windows.Media.MediaCommand. Если написать только MediaCommand, компилятор подумает, что это ссылка на событие MediaCommand в текущем пользовательском элементе управления.

Перехватывать можно не только указанные выше мультимедийные команды. В таблице ниже приведен полный список значений MediaCommand:

Значения перечисления MediaCommand
Функция Назначение
Play Воспроизведение
Pause Пауза, т.е. временная приостановка воспроизведения
TogglePlayPause Двустороннее переключение между режимами воспроизведения и паузы
Stop Остановка воспроизведения и возврат к началу или предыдущему состоянию
Record Начало записи. Эта команда обычно работает как переключатель, поэтому ее следующий экземпляр приводит к остановке записи
FastForward Быстрая перемотка вперед
Rewind Быстрая перемотка назад
NextTrack Переход к следующей дорожке или медиафайлу
PreviousTrack Переход к предыдущей дорожке или медиафайлу
IncreaseVolume Увеличение громкости на одну ступень
DecreaseVolume Уменьшение громкости на одну ступень
MuteVolume Временное отключение звука
ChannelUp Переход к следующему аудиоканалу
ChannelDown Переход к предыдущему аудиоканалу

Например, чтобы обработать изменение громкости, приведенный ниже код нужно поместить в конец предыдущего примера:

else if (e.MediaCommand == System.Windows.Media.MediaCommand.IncreaseVolume)
{
      media.Volume += .1;
}
else if (e.MediaCommand == System.Windows.Media.MediaCommand.DecreaseVolume)
{
      media.Volume -= .1;
}

Существует также несколько мультимедийный команд, специфичных для Silverlight на платформе Xbox: Menu, Title, Info, Display, Guide и TV.

Списки воспроизведения

Платформа Silverlight поддерживает метафайлы Windows Media, представляющие собой списки воспроизведения (playlists). Список воспроизведения содержит указатели на медиафайлы. Метафайл Windows Media обычно имеет расширение .wax, .wvx, .wmx, .wpl или .asx. Некоторые средства метафайлов не поддерживаются и могут вызвать ошибку, например ошибку команды сценария. Полный список неподдерживаемых средств метафайлов Windows Media можно найти в документации Silverlight.

Ниже приведен список воспроизведения (метафайл), ссылающийся на два видеофайла:

<asx version="3.0">
   <title>Список воспроизведения</title>
   <entry>
      <title>Видеофайл 1</title>
      <ref href="Video1.wmv" /> 
   </entry>
   <entry>
      <title>Видеофайл 2</title>
      <ref href="Video2.wmv" /> 
   </entry> 
</asx>

Если в свойство Source элемента MediaElement вставить ссылку на приведенный выше метафайл, элемент немедленно начнет воспроизведение файла Video1.wmv (конечно, если он существует), а затем — файла Video2.wmv. В данном случае оба файла расположены в одном и том же каталоге на сервере. Список воспроизведения находится в той же папке, однако вы должны задать в атрибуте href другие папки и серверы.

Обычно файлы .asx используются с потоковыми файлами .asf. В этом случае файл .asx содержит ссылку на файл .asf.

Пройди тесты
Лучший чат для C# программистов