Dziś temat multimediów. WPF jako nastawiony na interface użytkownika ma dużo do powiedzenia w tej kwestii. Zacznijmy zatem po kolei przyglądać się co mamy do dyspozycji.
SoundPlayer
To najprostsza klasa, którą mamy do dyspozycji jeśli chcemy odtworzyć dźwięki.
SoundPlayer player = new SoundPlayer("plik.wav");
player.Play();
Ze względu na swoją prostotę ma też swoje ograniczenia.
odtwarza tylko pliki .wav
nie ma wsparcia dla wielu dźwięków odtwarzanych jednocześnie
nie ma możliwości zmiany głośności
SystemSounds
Jeśli chcemy odegrać proste dźwięki systemowe, możemy skorzystać z tej klasy. definiuje ona kilka podstawowych dźwięków, każdy z których udostępnia metodę Play.
SystemSounds.Asterisk.Play();
SoundPlayerAction
Aby umożliwić deklaratywne odtwarzanie dźwięków powstała ta klasa. Dzięki niej możemy bezpośrednio w XAMLu zdefiniować jaki dźwięk ma zostać odgrany, gdy jakieś zdarzenie zajdzie. Zdefiniujmy odtwarzanie pliku, gdy przycisk zostanie naciśnięty:
<Button Content="play">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<SoundPlayerAction Source="click.wav" />
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
MediaPlayer
To klasa dużo bardziej rozbudowana niż wspomniany wcześniej SoundPlayer. Nie tylko wspiera więcej formatów niż poprzednik (audio i wideo) to dodatkowo posiada funkcje umożliwiające sterowanie odtwarzanym zasobem jak i odpowiednią jego konfigurację - np. przewijanie, regulacja głośności, pobranie długości klipu itp. Jak tego użyć. Wyłącznie z kodu:
MediaPlayer player = new MediaPlayer();
player.Open(new Uri("roar.wma", UriKind.Relative));
player.Play();
Tak jak wspomniałem, MediaPlayer ma dosyć duże możliwości, ale jest używalna tylko z kodu. Aby wykorzystać pełną moc XAML'a musimy skorzystać z następnych klas.
MediaElement oraz MediaTimeline
MediaElement to XAMLowy odpowiednik klasy MediaPlayer. Umożliwia nam te sam właściwości a przy okazji jest dostępny jako element języka XAML.
<StackPanel>
<MediaElement Source="roar.wma" />
</StackPanel>
MediaTimeline natomiast, jest tym dla klasy MediaElement czym SoundPlayerAction jest dla SoundPlayer. Możemy zatem użyć jej w eventach i animacjach.
<MediaElement x:Name="audio" />
<Button Content="Hover">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<BeginStoryboard x:Name="playStoryboard">
<Storyboard>
<MediaTimeline Source="roar.wma" Storyboard.TargetName="audio" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click">
<StopStoryboard BeginStoryboardName="playStoryboard" />
</EventTrigger>
</Button.Triggers>
</Button>
Wideo
Do wideo używamy ostatnio omawianej klasy MediaElement jednak w przypadku wideo, mamy do dyspozycji kilka dodatkowych właściwości, które warto omówić.
Możemy dla przykładu przyciąć wideo oraz wyświetlać je z półprzeźroczystością.
<Button Content="I'm below the video" />
<MediaElement x:Name="video" Source="walker.wmv" Opacity="0.7" >
<MediaElement.Clip>
<EllipseGeometry Center="80,80" RadiusX="180" RadiusY="180" />
</MediaElement.Clip>
</MediaElement>
Możemy też reagować na błędy związane z danymi za pomocą eventu MediaFailed.
Speech
WPF daje nam też możliwość zamiany tekstu w mowę oraz operację odwrotną czyli rozpoznawanie mowy i zamianę jej na formę tekstową. Aby skorzystać z tej funkcjonalności należy dodać do projektu System.Speech.dll.
Aby zmusić naszą aplikcję do wypowiedzenia pierwszych słów, należy skorzystać z klasy SpeechSynthesizer.
SpeechSynthesizer speech = new SpeechSynthesizer();
speech.Speak("I'm talking");
Można także robić to asynchronicznie za pomocą funkcji SpeakAsync. Oczywiście oprócz tego mamy jeszcze dużo więcej możliwości jak chociażby wybór głosu.
speech.SelectVoiceByHints(VoiceGender.Female, VoiceAge.Teen);
Oczywiście odpowidnie głosy musimy ściągnąć - są one dostępne w Speech SDK.
Oczywiście mamy dużo większe możliwości konfiguracyjne. Za pomocą klasy PromptBuilder. Umożliwia ona zbudowanie całej wypowiedzi wraz z odpowiednią intonacją: przerwami, przyśpieszaniem wypowiedzi lub jej zwalnianiem.
PromptBuilder builder = new PromptBuilder(CultureInfo.CurrentUICulture);
builder.AppendTextWithHint("WPF", SayAs.SpellOut);
builder.AppendText("jest");
builder.AppendBreak(PromptBreak.Small);
builder.AppendText("ekstra", PromptEmphasis.Strong);
SpeechSynthesizer speech = new SpeechSynthesizer();
speech.Speak(builder);
To tylko mały pokaz możliwości tej klasy.
Rozpoznawanie mowy
WPF udostępnia także rozpoznawanie głosu:
SpeechRecognizer recognizer = new SpeechRecognizer();
recognizer.SpeechRecognized += recognizer_SpeechRecognized;
Oczywiście i w tym przypadku możemy więcej kontrolować za pomocą gramatyki. Jednak jest to dosyć zaawansowana sprawa i nie sądzę, aby jej znajomość była bardzo wymagana na egzaminie - MSDN on GrammerBuilder
Na dziś tyle. Następnym razem będzie o zasobach w WPF.