Воспроизведение аудио с помощью триггеров

До сих пор переход от класса MediaPlayer к MediaElement не дал никаких преимуществ (помимо поддержки видео). Однако при использовании MediaElement также появляется возможность управлять аудио декларативно, через XAML-разметку, а не код. Это делается с помощью триггеров и раскадровок. Единственный новый ингредиент — MediaTimeline, который управляет временной шкалой аудио- или видеофайла и работает совместно с MediaElement для координации воспроизведения. Класс MediaTimeline унаследован от Timeline и добавляет свойство Source, идентифицирующее аудиофайл, который предназначен для воспроизведения.
Следующий код разметки демонстрирует простой пример. В нем используется действие BeginStoryboard для запуска воспроизведения звука, когда выполняется щелчок на кнопке. (Понятно, что с тем же успехом можно отреагировать и на другие события мыши и клавиатуры.):
Поскольку этот пример воспроизводит аудио, позиция MediaElement несущественна. В данном примере он размещается внутри Grid, перед Button. (Порядок не важен, поскольку во время выполнения программы MediaElement не будет иметь никакого визуального представления.) Когда осуществляется щелчок на кнопке, создается Storyboard с MediaTimeline. Обратите внимание, что источник в свойстве MediaElement.Source не указывается. Вместо этого источник передается через свойство MediaTimeline.Source.
Когда вы используете MediaElement в качестве цели для MediaTimeline, уже не имеет значения, установлены ли свойства LoadedBehavior и UnloadedBehavior. После применения MediaTimeline аудио или видео будет управляться таймером анимации WPF (конкретно — экземпляром класса MediaClock, который представлен в свойстве MediaElement.Clock).
Для управления воспроизведением в MediaElement можно использовать единственный экземпляр Storyboard — другими словами, можно не только останавливать, но также временно приостанавливать и возобновлять воспроизведение:

Единственная сложность состоит в том, что нужно не забыть определить все триггеры для управления раскадровкой в одной коллекции. Затем их можно присоединить к соответствующим элементам управления, используя свойство EventTrigger.SourceName. В данном примере все триггеры объявлены внутри панели StасkPanel, содержащей кнопки.
Воспроизведение множества звуков
Хотя в предыдущем примере демонстрировалось воспроизведение единственного медиафайла, нет никаких причин, которые помешали бы расширить его, добавив возможность одновременного воспроизведения нескольких аудиофайлов. В показанном ниже примере добавлены две кнопки, каждая из которых запускает воспроизведение собственного звука. Когда выполняется щелчок на кнопке, создается новый объект Storyboard, с новой MediaTimeline, которая используется для воспроизведения отдельного аудиофайла через один и тот же MediaElement:
В этом примере, если быстро щелкнуть на обеих кнопках подряд, обнаружится, что второй звук прервет воспроизведение первого. Это следствие применения одного и того же MediaElement для обеих временных шкал. Более гибкий (но и более ресурсоемкий) подход предусматривает использование отдельного MediaElement для каждой кнопки и установке каждой MediaTimeline на соответствующий MediaElement. (В этом случае можно задать свойство Source непосредственно в дескрипторе MediaElement, поскольку оно не изменяется.) Если теперь быстро щелкнуть подряд на двух кнопках, оба звука будут воспроизводиться одновременно.
То же самое касается класса MediaPlayer. Для воспроизведения нескольких аудиофайлов понадобится несколько объектов MediaPlayer. Если решено использовать в коде MediaPlayer или MediaElement, то появляется шанс провести более разумную оптимизацию, которая, например, позволит воспроизводить одновременно только два звука, но не больше.
Базовый прием заключается в определении двух объектов MediaPlayer с переключением между ними всякий раз, когда требуется запустить воспроизведение нового звука. (Отслеживать, какой объект использовался последний раз, можно с помощью переменной булевского типа.) Чтобы облегчить применение этого приема, можно поместить имена аудиофайлов в свойство Tag соответствующего элемента, так что коду обработки событий понадобится только найти нужный MediaPlayer, установить свойство Source и вызвать метод Play().
C # WPF как повторить воспроизведение MediaElement из обработчика событий с медиа-содержимым без объявления нового источника?
Я проигрываю видео в WPF. Я хочу, чтобы оно зацикливалось, поэтому когда срабатывает событие mediaended, я воспроизводю свое видео. так что это даст мне петлю. проблема в том, почему я должен снова создавать новый источник? почему я не могу просто назвать игру?
Я почему-то не хочу делать это в XAML.
взгляните на мой фрагмент кода:
или есть ли правильный способ зацикливаться НЕ в XAML, а в файле .cs?
задан 12 мая ’11, 05:05
5 ответы
Вместо того, чтобы сбрасывать Source в начале обработчика Media_Ended, попробуйте вернуть значение Position в исходное положение. Свойство Position — это TimeSpan, поэтому вы, вероятно, захотите что-то вроде .
ответ дан 12 мая ’11, 10:05
спасибо за ваш ответ. Я пробовал это раньше, но безуспешно. видео не воспроизводится. — Психокрио
Хммм . странно. Я тестировал его, но с аудиофайлом, а не с видео. Не уверен, почему видео будет другим — посмотрю еще раз. — ЯнР
По некоторым причинам эта комбинация иногда не работает! В моем случае для gif. — Евгений Наида
Вам даже не нужно устанавливать LoadedBehavior как Вручную Оставь это Play.
И сбросьте свою позицию в СМИ на MediaEnded.
Новое положение видео должно быть больше нуля:
Я заставляю его работать, устанавливая UnloadedBehavior = «Manual» и следующий код
Установка нулевого положения не сработала .
это сработало для меня! установка на ноль не сработала. следовал инструкциям здесь и работал у меня. мой случай был анимированной гифкой. — Faldeland
Я думаю, вам стоит использовать этот код:
Я надеюсь, это поможет.
Создан 15 июля ’12, 00:07
Пожалуйста, не предоставляйте ответы «только код». Как вы думаете, почему это ответ? — Ли Тейлор
Это сработало для меня, вы не можете вызвать «Play», если для LoadBehaviour уже установлено значение Play в XAML. — Марк Фельдман
Вам не нужно снова устанавливать источник, просто установите позицию медиаэлемента на начало события media_ended
Возможно, вам потребуется установить для MediaElement.LoadedBehavior значение Manual
РЕДАКТИРОВАТЬ
Я попытался загрузить файл asf с тегом REPEAT, и он отлично работает
Но я думаю, что встроенный механизм обработки списков воспроизведения медиаэлемента имеет некоторые недостатки. Я рекомендую использовать обходной путь, упомянутый в приведенной ниже ссылке.
Оставьте здесь комментарий, если у вас возникли проблемы
ответ дан 16 мая ’11, 11:05
кажется, что он работает, если носитель представляет собой один файл, но не работает, если я использую файл списка воспроизведения, такой как формат файла .wpl или .asx. какая-нибудь подсказка? — Психокрио
Итак, после того, как весь список воспроизведения закончен . вы хотите повторить с первого файла, верно? — Biju
Также как вы управляете своим списком воспроизведения? AFIK MediaElement не имеет встроенного механизма обработки списков воспроизведения. — Biju
да. Я хочу воспроизвести все с самого начала. Поэтому я сделал все то же, что и ваша инструкция, но источником мультимедиа является файл .wpl. Я пробовал файл .asx, но результат тот же. Он не повторяется. если я использую медиа-источник, такой как lexus.mp4, все будет хорошо, используя вашу инструкцию .. любая идея? — Психокрио
@ biju, спасибо, приятель, я попробую и снова посмотрю, как. thnx. — Психокрио
Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками c# wpf events event-handling mediaelement or задайте свой вопрос.