1

我正在转换一个用 Silverlight 编写的应用程序,到目前为止,我已经成功解决了所有问题,除了一个:

由于某种原因,模拟器拒绝播放应用程序的任何音频文件,甚至没有抛出异常。我查过了,在铃声类别中它可以发出声音。

原始代码是:

<Grid x:Name="sharedFullScreenFilePathContainer"
Tag="{Binding StringFormat=\{0\},Converter={StaticResource fullScreenImageConverter}}">

    <Image x:Name="fullScreenImage" Stretch="Fill"
Source="{Binding ElementName=sharedFullScreenFilePathContainer,Path=Tag, StringFormat=../Assets/images/\{0\}.jpg}"
ImageFailed="onFullScreenImageFailedToLoad" MouseLeftButtonDown="onPressedOnFullScreenImage" />

    <MediaElement x:Name="mediaPlayer" AutoPlay="True"
Source="{Binding ElementName=sharedFullScreenFilePathContainer,Path=Tag, StringFormat=../Assets/sounds/\{0\}.wma}" />
</Grid>

所以,我设置到这个项目的上下文的图像真的被显示了,但是我设置的路径上真正存在的声音没有播放(我已经检查了“Bin”文件夹)。

我尝试使用代码而不是 xaml,但我仍然遇到同样的问题。

我试过这个(虽然它通常用于背景音乐):

AudioTrack audioTrack = new AudioTrack(new Uri("../Assets/sounds/" + fileToOpen, UriKind.Relative), "", "", "", null);
BackgroundAudioPlayer player = BackgroundAudioPlayer.Instance;
player.Track = audioTrack;
player.Play();

它没有播放任何东西,也没有抛出任何异常。

我也尝试了下一个代码,但它引发了异常(找不到文件异常),可能是因为我没有正确调用它:

Stream stream = TitleContainer.OpenStream("@Assets/sounds/" + fileToOpen);
SoundEffect effect = SoundEffect.FromStream(stream);
FrameworkDispatcher.Update();
effect.Play();

我也尝试过使用 wma 文件,但也没有用。

我还尝试使用 mp3 文件的“复制到输出目录”参数(“始终”和“仅当新”)和“构建操作”参数(“无”和“内容”)。没有什么帮助。

谁能帮帮我吗?我很长时间没有为 Silverlight/WP 开发,我不知道如何修复它。

顺便说一句,因为稍后我需要知道声音何时播放完毕(并且还能够停止它),所以无论如何我都想使用代码。如果你也能告诉我怎么做,我会很高兴(如果需要,我可以在新帖子上问)。


编辑:好的,我发现了问题:在使用MediaPlayer.Play()方法时,我不断收到一个奇怪的异常,在检查了异常之后,我发现这是一个已知问题,而且我需要调用FrameworkDispatcher.Update(); 就在我调用 Play() 方法之前。

所以解决方案是做这样的事情:

Song song = Song.FromUri(...);
MediaPlayer.Stop(); 
FrameworkDispatcher.Update();
MediaPlayer.Play(song);

例外是:

System.Windows.ni.dll 中发生“System.InvalidOperationException”

我在这里找到了解决方案。

现在的问题是为什么,为什么我在 windows phone 的演示中没有找到任何相关的东西?另外,我想知道这个函数是做什么的。


好的,既然没有人给我两个问题的答案,我仍然希望给予赏金,我会问另一个问题:

如果除了使用 windows phone 的 MediaPlayer 类之外真的没有解决方案,我如何捕获完成播放音频文件的事件?即使获取音频文件的持续时间也不起作用(无论我尝试使用哪个类,都会返回 0 length )...

4

5 回答 5

2

BackgroundAudioPlayer 只能播放来自隔离存储或远程 URI 的文件这就是为什么你可以在这里做任何事情的原因!

如果您将文件作为应用程序中的资源,您必须首先将它们复制到独立存储,然后将独立存储中的文件引用到您的 BackgroundAudioPlayer。

    private void CopyToIsolatedStorage()
    {
        using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
        {
            string[] files = new string[] 
                { "Kalimba.mp3", 
                    "Maid with the Flaxen Hair.mp3", 
                    "Sleep Away.mp3" };

            foreach (var _fileName in files)
            {
                if (!storage.FileExists(_fileName))
                {
                    string _filePath = "Audio/" + _fileName;
                    StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));

                    using (IsolatedStorageFileStream file = storage.CreateFile(_fileName))
                    {
                        int chunkSize = 4096;
                        byte[] bytes = new byte[chunkSize];
                        int byteCount;

                        while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
                        {
                            file.Write(bytes, 0, byteCount);
                        }
                    }
                }
            }
        }
    }

然后你可以列出你的歌曲列表

    private static List<AudioTrack> _playList = new List<AudioTrack>
    {
        new AudioTrack(new Uri("Kalimba.mp3", UriKind.Relative), 
                        "Kalimba", 
                        "Mr. Scruff", 
                        "Ninja Tuna", 
                        null),

        new AudioTrack(new Uri("Maid with the Flaxen Hair.mp3", UriKind.Relative), 
                        "Maid with the Flaxen Hair", 
                        "Richard Stoltzman", 
                        "Fine Music, Vol. 1", 
                        null),

        new AudioTrack(new Uri("Sleep Away.mp3", UriKind.Relative), 
                        "Sleep Away", 
                        "Bob Acri", 
                        "Bob Acri", 
                        null),

        // A remote URI
        new AudioTrack(new Uri("http://traffic.libsyn.com/wpradio/WPRadio_29.mp3", UriKind.Absolute), 
                        "Episode 29", 
                        "Windows Phone Radio", 
                        "Windows Phone Radio Podcast", 
                        null)
    };

并播放您的曲目!

    private void PlayNextTrack(BackgroundAudioPlayer player)
    {
        if (++currentTrackNumber >= _playList.Count)
        {
            currentTrackNumber = 0;
        }

        PlayTrack(player);
    }

    private void PlayPreviousTrack(BackgroundAudioPlayer player)
    {
        if (--currentTrackNumber < 0)
        {
            currentTrackNumber = _playList.Count - 1;
        }

        PlayTrack(player);
    }

    private void PlayTrack(BackgroundAudioPlayer player)
    {
        // Sets the track to play. When the TrackReady state is received, 
        // playback begins from the OnPlayStateChanged handler.
        player.Track = _playList[currentTrackNumber];
    }
于 2013-02-05T13:25:46.457 回答
2

如果您希望 MediaElement 从您的代码中工作,您可以执行以下操作!

        MediaElement me = new MediaElement();
        // Must add the MediaElement to some UI container on 
        // your page or some UI-control, otherwise it will not play!
        this.LayoutRoot.Children.Add(me);
        me.Source = new Uri("Assets/AwesomeMusic.mp3", UriKind.RelativeOrAbsolute);
        me.Play();
于 2013-02-06T22:53:10.350 回答
0

音轨播放存储在隔离存储中或通过 Internet 流式传输的音频文件。

于 2013-01-27T16:00:42.693 回答
0

播放存储在应用程序包中的音频文件对我来说很好。我在项目文件夹 Resources\Alarms 中有名为“Alarm01.wma”的文件。然后我像这样播放这些声音:

using Microsoft.Xna.Framework.Media;
...
Song s = Song.FromUri("alarm", new Uri(@"Resources/Alarms/Alarm01.wma", UriKind.Relative));
MediaPlayer.Play(s);

也不要忘记参考Microsoft.Xna.Framework库。

我想它也应该适用于存储在 IsolatedStorage 中的 mp3 文件和文件。

于 2013-02-05T09:16:56.883 回答
0

改用 MediaElement,这可以播放存储在您的应用程序中的媒体文件,但在应用程序停止时停止播放(您可以为您的应用程序提供一些提前机会,以便它继续运行,但它不会很好地工作)

在您的 XAML 中:

        <Button x:Name="PlayFile"
                Click="PlayFile_Click_1"
                Content="Play mp3" />

在您的代码后面:

    MediaElement MyMedia = new MediaElement();
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        this.LayoutRoot.Children.Add(MyMedia);

        MyMedia.CurrentStateChanged += MyMedia_CurrentStateChanged;
        MyMedia.MediaEnded += MyMedia_MediaEnded;
    }

    void MyMedia_MediaEnded(object sender, RoutedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Ended event " + MyMedia.CurrentState.ToString());
        // Set the source to null, force a Close event in current state
        MyMedia.Source = null;
    }

    void MyMedia_CurrentStateChanged(object sender, RoutedEventArgs e)
    {

        switch (MyMedia.CurrentState)
        {
            case System.Windows.Media.MediaElementState.AcquiringLicense:
                break;
            case System.Windows.Media.MediaElementState.Buffering:
                break;
            case System.Windows.Media.MediaElementState.Closed:
                break;
            case System.Windows.Media.MediaElementState.Individualizing:
                break;
            case System.Windows.Media.MediaElementState.Opening:
                break;
            case System.Windows.Media.MediaElementState.Paused:
                break;
            case System.Windows.Media.MediaElementState.Playing:
                break;
            case System.Windows.Media.MediaElementState.Stopped:
                break;
            default:
                break;
        }

        System.Diagnostics.Debug.WriteLine("CurrentState event " + MyMedia.CurrentState.ToString());
    }

    private void PlayFile_Click_1(object sender, RoutedEventArgs e)
    {
        // Play Awesome music file, stored as content in the Assets folder in your app
        MyMedia.Source = new Uri("Assets/AwesomeMusic.mp3", UriKind.RelativeOrAbsolute);
        MyMedia.Play();
    }
于 2013-02-05T21:10:36.143 回答