2011-01-06 57 views
2

我在與Silverlight中MediaElement控制的Windows Phone 7。我的目標是困難的,當用戶按下一個按鈕來播放兩個音。我想出的方法是每個音調都有一個MediaElement。 (有可能是一個更好的辦法?)麻煩與MediaElement的在Silverlight

<phone:PhoneApplicationPage 
    x:Class="MediaElementTest.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    SupportedOrientations="Portrait" Orientation="Portrait" 
    shell:SystemTray.IsVisible="True"> 

    <StackPanel x:Name="LayoutRoot" Background="Transparent"> 

      <MediaElement 
       x:Name="firstTone" 
       MediaEnded="firstTone_MediaEnded" 
       Source="{Binding FirstTone}" /> 
      <MediaElement 
       x:Name="secondTone" 
       Source="{Binding SecondTone}" /> 
      <Button Content="Play" Click="Button_Click" /> 

    </StackPanel> 

</phone:PhoneApplicationPage> 

代碼隱藏:

public partial class MainPage : PhoneApplicationPage 
    { 
     public Uri FirstTone 
     { 
      get 
      { 
       return new Uri("A.mp3", UriKind.Relative); 
      } 
     } 

     public Uri SecondTone 
     { 
      get 
      { 
       return new Uri("B.mp3", UriKind.Relative); 
      } 
     } 

     public MainPage() 
     { 
      InitializeComponent(); 
      LayoutRoot.DataContext = this; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      firstTone.Stop(); 
      secondTone.Stop(); 

      firstTone.Play(); 
     } 

     private void firstTone_MediaEnded(object sender, RoutedEventArgs e) 
     { 
      secondTone.Play(); 
     } 
    } 

當我按一下按鈕,無音播放。爲什麼是這樣?我究竟做錯了什麼?

回答

0

我不知道爲什麼你聽到什麼都沒有,但如果你想聽到的兩個連續的色調,當用戶點擊一個按鈕,爲什麼不結合音的時間提前到一個單一的文件,然後玩那個?

+0

直到運行時纔會知道播放的兩個音。 (如果我要預先製作所有可能的組合,這將是大量文件,我寧願以編程方式進行。) – 2011-01-06 15:57:53

+0

噢,好的。我會留下我的回答,所以沒有人提出相同的建議。 – MusiGenesis 2011-01-06 16:02:55

+0

我的猜測是你的Uris有問題。我建議在網上查找代碼示例,然後逐漸修改。 – MusiGenesis 2011-01-06 16:05:10

1

你可以得到各種奇怪的事情相對於Silverlight應用程序的URI和它們的位置去;並且數據綁定是非常難以得到正確的。我的建議是通過直接在XAML中硬編碼絕對URI到MP3文件來解決這個問題。一旦你得到了這個工作,切換到相對URI,當它工作時,切換到數據綁定到代碼隱藏(或ViewModel或其他)。

如果你有放置在獨立存儲文件,這樣的事情應該工作(沒有測試它在WP7):

var store = IsolatedStorageFile.GetUserStoreForApplication(); 
var iStream = store.OpenFile("a.mp3", System.IO.FileMode.Open,FileAccess.Read); 
firstTone.SetSource(iStream); 
firstTone.Play(); 
+0

我不確定WP7應用程序中絕對的URI是什麼。你不是指「c:\ path \ to \ project \ a.mp3」,是嗎? – 2011-01-06 18:09:19

1

不要使用MediaElement這一點。相反,請添加對Microsoft.Xna.Framework.dll的引用(是的,即使在Silverlight項目中),然後使用SoundEffect

類似:

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 

using (var stream = TitleContainer.OpenStream("a.mp3")) 
{ 
    var effect = SoundEffect.FromStream(stream); 
    effect.Play(); 

    // This will pause while the first sound plays 
    // so they don't play over each other but as it also blocks! 
    Thread.Sleep(effect.Duration); 
} 

using (var stream = TitleContainer.OpenStream("b.mp3")) 
{ 
    var effect = SoundEffect.FromStream(stream); 
    effect.Play(); 
} 
1

的MediaElement的是用於在同一時間玩了一盤磁帶。正如其他人所提到的,使用SoundEffect或SoundEffectInstance類來模擬聲音。您一次最多可播放16個SoundEffects。

此外,使用MediaElement的可能會導致認證的麻煩,如果你不小心。例如,如果您在XAML中設置MediaElement源,則會導致手機中當前正在播放的媒體停止播放。除非您要求用戶許可停止播放媒體,否則您將無法通過認證。

0

我從來沒有能夠得到多個MediaElements對一個手機應用程序的工作。我看到和你一樣的問題,我無法播放媒體。

我相信你只能有一個活動,但我還沒有看到機制的文檔,以這種效果。我解決它的方法是在App.XAML中定義一個MediaElement

<!--Application Resources--> 
<Application.Resources> 
    <MediaElement 
     x:Key='mediaElement' AutoPlay='True' Source='/music/GroovinIntro.wav'/> 
</Application.Resources> 

然後將其作爲Application類的屬性公開。

public MediaElement MediaElement 
{ 
    get 
    { 
    return this.Resources["mediaElement"] as MediaElement; 
    } 
} 

然後像這樣調用MediaElement。

App.Current.MediaElement.Source = new Uri(_musicLocation, UriKind.Relative);