2011-01-06 138 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);