23 Ocak 2011

Windows Phone 7 Media Element

Windows Phone, ses ve görüntü dosyalarını oynatabilmek için de oldukça başarılı bir ortam sunmaktadır. Kullanımı kolay ve gelişmiş Silverlight mediaelement nesnesi ile phone uygulamalarımıza güçlü media özellikleri kazandırabiliriz. Bu makalemizde yeni bir Windows Phone 7 uygulaması oluşturarak, örneklerle mediaelement komponentini inceleyeceğiz.


Mediaelement komponenti ile, oynatacağımız .mp3 veya .wav uzantılı dosyaları projemize ekleyerek, ya da uzak bir sunucuda yayınlanan bir media kaynağına erişim sağlayarak da bu dosyaları oynatabiliriz. Uzak sunucuda yer alan media dosyasının Uri adresini mediaelement' in Source Property 'sine bağlamamız bunun için yeterli olacaktır. Eğer uzak sunucudaki bir dosyaya erişmek yerine bu dosyaları projemize eklemek istiyorsak, bu dosyaların BuildAction özelliğinin "Content" ve CopyToOutput özelliğinin de "Copy Always" 
olmasına dikkat edelim.



Dikkat edilmesi gereken önemli bir nokta da windows phone için hangi codec bileşenlerinin desteklendiğidir. Örneğimize başlamadan önce, desteklenen windows phone media codec listesini buradan (Supported 
Media Codecs for Windows Phone)  inceleyebilirsiniz.


Projemize content olarak ekleyeceğimiz bir mp3 dosyasını oynatarak örneğimize başlayalım. Tabii her zamanki gibi ilk iş olarak Visual Studio / File / New / Project / Visual C# / Silverlight For Windows Phone template'i seçip, yeni bir Windows Phone projesi oluşturalım. Toolbox penceresinden mediaelement ' i tutup sürükleyerek default olarak oluşturulmuş olan MainPage.xaml sayfamızın üzerine bırakalım.












Bilgisayarımda hazır bulunan örnek müziklerimden Sleep Away.mp3 dosyasını da projeme content olarak ekliyorum. Copy To Output Directory özelliğini Always True olarak seçiyorum. AutoPlay="True"  olarak 
seçip, ilk açılışta otomatik olarak mp3 dosyasının çalınmasını sağlayacağım.


XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="2,0,2,0">
     <MediaElement x:Name="myMediaElement" Margin="10" 
                   Source="/Sleep Away.mp3" AutoPlay="True"/>
</Grid>


Benzer bir şekilde, yukarıdaki mediaelement nesnesinin Source özelliğine uzak bir sunucuda yer alan dosyanın Uri adresini set edeceğim. Test amacıyla uzak sunucu olarak kendi bilgisayarımda bulunan iis dizini altına 
(inetpub/wwwroot) mymuzik isminde bir klasör oluşturup Kalimba.mp3 isimli dosyamı buraya kopyalıyorum. Bu yöntem ile media dosyalarının direk olarak IIS' den yayınlanması tabiki doğru bir çözüm değildir. Sağlıklı bir çözüm için Windows Media Services veya IIS Smooth Streaming yöntemleri kullanılabilir. Eğer 
Windows Media Sevis'i kurmak istiyorsak, http://daron.yondem.com/tr/PermaLink.aspx?guid=c44b96e8-e240-4ede-8c1f-7bdc000da97f linkinde yer alan makaleyi de inceleyebilirsiniz. (Ayrıca iis smoot streaming incelemek isteyenler http://www.iis.net/download/SmoothStreaming adresini ziyaret edebilirler.) Bu makalemizin konusu media dosyalarının yayınlanması olmadığı için kaldığımız yerden devam edelim.


XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="2,0,2,0">
    <MediaElement x:Name="myMediaElement" Margin="10" 
                  Source="http://localhost/mymuzik/Kalimba.mp3" 
                  AutoPlay="True"/>
</Grid>


MediaElement nesnesinin Source özelliğini direk olarak set ettiğimiz için ilgili media dosyasının yüklenmesi belirli bir zaman alabilir. Ya da oynatacağımız dosya içinde oluşmuş bozulmalardan kaynaklı yavaşlamaları 
engellemek için de öncelikle dosyayı telefonumuzun isolated storage alanına indirerek oynatmayı da deneyebiliriz. (Windows Phone Isolated Storage konusunuda ayrıca bir makalede inceleyebiliriz.) Isolated Storage alanı, adından da anlaşılacağı üzere uygulamamız tarafından kullanabileceğimiz, diğer uygulamalardan yalıtılmış bir yazma ve yazdıklarımızı okuma alnıdır. Uygulamamız için özel olarak tahsis edilmiş bir bellek alanıdır. Şimdi WebClient nesnesi ile uzak sunucumuzdaki Kalimba.mp3 dosyamıza okuma çağrısında bulunalım ve sonucu asenkron olarak elde edelim. Elde edeceğimiz result değeri Stream tipinde olacaktır. Gelen stream değerini bir döngü içerisinde öncelikle isolated storage alanına yazdıktan sonra mediaelement' 

imizin SetSource özelliğini kullanarak oynatalım.

XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="2,0,2,0">
    <MediaElement x:Name="myMediaElement" Margin="10" />
</Grid>

C#
public MainPage() {
  InitializeComponent();
  Loaded += MainPage_Loaded;
}
 
void MainPage_Loaded(object sender, RoutedEventArgs e) {
  WebClient web = new WebClient();
  web.OpenReadCompleted += web_OpenReadCompleted;
  Uri myAddress = new Uri("http://localhost/mymuzik/Kalimba.mp3");
  web.OpenReadAsync(myAddress);
}
 
void web_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) {
  if (e.Error == null) {
    using (var s = e.Result) {
      using (var isolatedFile = new IsolatedStorageFileStream("Kalimba.mp3",
      FileMode.Create, IsolatedStorageFile.GetUserStoreForApplication())) {
        int i;
        var buffer = new byte[10000];
        while ((i = s.Read(buffer, 0, buffer.Length)) > 0) {
          isolatedFile.Write(buffer, 0, i);
        }
        isolatedFile.Seek(0, SeekOrigin.Begin);
        this.myMediaElement.SetSource(isolatedFile);
      }
    }
  }
}

Şimdi de yukarıdaki örneğimizden farklı olarak, uzak bir sunucu da bulunan örnek bir videoyu oynatarak medielement nesnemizin özelliklerini tanımaya çalışalım. Xaml kodlarımızı aşağıdaki gibi hazırlayalım. 
MediaElement'in Source'una Uri adresini C# kodu ile set edeceğiz. 


XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <MediaElement 
            Height="423" 
            Width="438"
            Margin="5" 
            Name="myMediaElement" 
            VerticalAlignment="Top"
            AutoPlay="True"/>
        <TextBlock 
            Height="34" 
            HorizontalAlignment="Left" 
            Margin="12,476,0,0" 
            Name="txtState" 
            Text="" 
            VerticalAlignment="Top" 
            Width="152" FontSize="24" />
        <TextBlock 
            Height="34" 
            HorizontalAlignment="Left" 
            Margin="175,476,0,0" 
            Name="txtPercentage" 
            Text="" 
            VerticalAlignment="Top" 
            Width="90" FontSize="24" />
    </Grid>
</Grid>

Videomuz otomatik olarak öncelikle telefonumuzun belleğine alınacaktır. Playing (Oynatma) başlamadan önce, buffering (arabelleğe alma) için gereken süreyi de dilersek belirtebiliriz. Bunun için mediaelement' in BufferingTime özelliğine TimeStamp türünde değer atanabilir. 
Şimdi C# ile uzuk sunucudaki video ile bağlantı kurarak, media element nesnemizde oluşacak state'leri (opening, buffering, playing), buffering olan miktarı ekranımıza yazdıralım.

C#
public MainPage()
{
    InitializeComponent();
    Loaded += MainPage_Loaded;
}
 
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    myMediaElement.CurrentStateChanged +=
      myMediaElement_CurrentStateChanged;
    myMediaElement.BufferingProgressChanged +=
      myMediaElement_BufferingProgressChanged;
    myMediaElement.Source =
      new Uri("http://mschannel9.vo.msecnd.net/o9/mix/09/wmv/key01.wmv");
}
 
void myMediaElement_BufferingProgressChanged(object sender, RoutedEventArgs e)
{
    double percent = myMediaElement.BufferingProgress;
    string str = percent == 1d ? "Ok." : string.Format("{0:P}", percent);
    txtPercentage.Text = str;
}
 
void myMediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
{
    txtState.Text = myMediaElement.CurrentState.ToString();
}
 
F5 ile emulatör üzerinden uygulamamızı başlatalım, txtState TextBlock üzerinde o an ki durumu, txtPercentage TextBlock üzerinde ise yüzde olarak ne kadarlık buffer miktarının tamamlandığını göreceğiz.




































Buffering tamamlandıktan sonra video'nun oynamaya başladığını ve txtState TextBlock nesnesine "Playing", txtPercentage üzerine ise "Ok." yazılacağını göreceğiz. Media Element komponentimizin genel olarak ne tür de özelliklere ve methodlara sahip olduğunu bir tablo üzerinden inceleyerek makalemizi sonlandıralım.

Property (Özellik) Açıklama
Source Oynatılacak media dosyasının Uri adresidir.
Volume Oynayan dosyanın ses düzeyini belirlemek için kullanılır. Default
olarak 0.5'dir (Orta seviye).
Position TimeStamp türü ile oynayan media dosyasının zaman çizelgesinde,
hangi pozisyonda olduğu bilgisidir. Dilersek Position değerini set
ederek, istediğimiz pozisyondan başlatabiliriz.
NaturalDuration TimeSpan türünde oynayan dosyanın ne kadar uzunlukta olduğunu
belirtir.
IsMuted İstenirse oynayan dosya sessiz duruma getirilebilir. O an ki ses
durumu da (kapalı/açık) elde edilebilir.
DownloadProgress Yüzdelik olarak ne kadar download edildiği bilgisini tutar.
CanPause Oynayan media'nın pause olup, olamayacağı bilgisini verir.
ReadOnly'dir.
CanSeek Position değerine müdahale edilip edilemeyeceği bilgisini döner.
Methods
Pause Eğer CanPause property true ise Pause methodu ile media durdurulur.
Pause durumunda oynayan son film karesi görüntülenecektir.
Play Media dosyasını oynatır. Eğer durum stop veya pause ise tekrar
oynamaya başlayacaktır.
Stop Oynayan media dosyası durdurulacaktır. Bu durumda ilk film karesi
ekranda gösterilecektir.
SetSource Stream bir değeri parametre olarak set edebiliriz. Yukarıdaki
örneğimizde de yaptığımız gibi Isolated Storage alanına depolanmış bir media' yı oynatmak için oldukça kullanışlıdır.


Bir sonraki makalemizde görüşmek üzere.
Kolay gelsin.

Hiç yorum yok: