none
如何在代码里面实现PlaySound? RRS feed

  • 问题

  • 也就是要实现:
    要求:
    1)不允许xaml文件中有MediaElement标记,因为我要作成通用的类库,任意地方均可调用。
    2)也不允许调用Html的BGSOUND标记完成,因为这样实际是调用Web服务器的东西,效率太低。
    3)声音文件作为文件是以“内容(Content)”方式,不是“资源(Resource)”方式包含在XAP文件中。
    4)我的目的其实就是要给用户提供声音警告,声音文件不会很长。
    Public Function PlaySound(ByVal SoundUrl As String)
         '中间如何实现
    End Function
    提示:
    1)可以在代码中动态创建MediaElement,播放出声音。我弄了,但是很不稳定(有时候可以播放出声音,有时候不能),所以请高手给个好的代码。
    2009年10月12日 3:42

答案

  • 你好,

    可以把声音文件上传到http://skydrive.live.com/然后贴一下下载链接吗?我测试一下看看. 我记得之前的SL版本中对小文件音频文件的播放好像是有一些问题.我会去确认一下.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework http://cfx.codeplex.com/! If you have any feedback, please tell us.
    2009年10月13日 7:18
    版主
  • TFSoft你好! 
    以下是我很久前写的一个sl游戏的声音播放代码,相当稳定。
     internal static class SoundPlayer
        {
            internal static Canvas Content = new Canvas();
            private const int slotCount = 0x10;

            private static MediaElement GetSoundSlot()
            {
                foreach (MediaElement element in Content.Children)
                {
                    if ((element.CurrentState == MediaElementState.Paused) || (element.CurrentState == MediaElementState.Stopped))
                    {
                        return element;
                    }
                }
                if (Content.Children.Count < 0x10)
                {
                    MediaElement element2 = new MediaElement {
                        Volume = 1.0
                    };
                    Content.Children.Add(element2);
                    return element2;
                }
                return null;
            }

            internal static void Play(string sound)
            {
                MediaElement soundSlot = GetSoundSlot();
                if (soundSlot != null)
                {
                    soundSlot.Volume = .5;
                    soundSlot.SetSource(ReadMediaFile("/JacGame;component/Content/sound/" + sound));
                }
            }

            private static Stream ReadMediaFile(string filename)
            {
                Stream stream = null;
                try
                {
                    XmlXapResolver resolver = new XmlXapResolver();
                    stream = resolver.GetEntity(new Uri(filename, UriKind.Relative), null, null) as Stream;
                }
                catch
                {
                    throw new Exception(string.Format("Failed to load: {0}!", filename));
                }
                return stream;
            }
        }

    以上如果你要的声音文件是利用context形式存在的话你可以把play方法里边的ReadMediaFile("/JacGame;component/Content/sound/" + sound),改为你的声音文件的相对地址。如(/content/sound/aa.mp3)

    希望我的回复对你有所帮助!


    jaocb lai
    2009年11月9日 6:56
    版主

全部回复

  • 你好,
    目前只能通过MediaElement来播放声音. 请问能否提供一个不能播放声音的例子?我测试一下看看.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework http://cfx.codeplex.com/! If you have any feedback, please tell us.
    2009年10月13日 5:17
    版主
  • 本来已经做好测试工程,但是不知道如何在论坛里面发文件
    只好把关键代码拷贝
    TFSndClick.mp3其实是一个非常小的声音文件,
    我只是需要播放一个很短的声音来提示用户。

    Imports System.IO
    Imports System.Windows.Resources
    Imports System.Threading
    Namespace AT
        Public Class TFSoundUrl
            Public Const SndClick As String = "App_Snd/TFSndClick.mp3"
        End Class
        Public Class TFSound
            Public Shared Sub PlaySound(ByVal TheSoundUrl As String)
                Dim Smi As StreamResourceInfo = Application.GetResourceStream(New Uri(TheSoundUrl, UriKind.Relative))
                Dim Buf(Smi.Stream().Length - 1) As Byte
                Smi.Stream().Read(Buf, 0, Buf.Length - 1)
                Dim El As New MediaElement() : El.AutoPlay = True
                El.Stop() : El.SetSource(New MemoryStream(Buf)) : El.Play()
                Thread.Sleep(300)  'Add this line, the PlaySound function seems to be better. But I'm not sure.
            End Sub
        End Class
    End Namespace

    To Test PlaySound, Just....
    ---------------------------------------------------------
       TFSound.PlaySound(TFSoundUrl.SndClick)
    ---------------------------------------------------------


    2009年10月13日 6:37
  • 你好,

    可以把声音文件上传到http://skydrive.live.com/然后贴一下下载链接吗?我测试一下看看. 我记得之前的SL版本中对小文件音频文件的播放好像是有一些问题.我会去确认一下.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework http://cfx.codeplex.com/! If you have any feedback, please tell us.
    2009年10月13日 7:18
    版主
  • TFSoft你好! 
    以下是我很久前写的一个sl游戏的声音播放代码,相当稳定。
     internal static class SoundPlayer
        {
            internal static Canvas Content = new Canvas();
            private const int slotCount = 0x10;

            private static MediaElement GetSoundSlot()
            {
                foreach (MediaElement element in Content.Children)
                {
                    if ((element.CurrentState == MediaElementState.Paused) || (element.CurrentState == MediaElementState.Stopped))
                    {
                        return element;
                    }
                }
                if (Content.Children.Count < 0x10)
                {
                    MediaElement element2 = new MediaElement {
                        Volume = 1.0
                    };
                    Content.Children.Add(element2);
                    return element2;
                }
                return null;
            }

            internal static void Play(string sound)
            {
                MediaElement soundSlot = GetSoundSlot();
                if (soundSlot != null)
                {
                    soundSlot.Volume = .5;
                    soundSlot.SetSource(ReadMediaFile("/JacGame;component/Content/sound/" + sound));
                }
            }

            private static Stream ReadMediaFile(string filename)
            {
                Stream stream = null;
                try
                {
                    XmlXapResolver resolver = new XmlXapResolver();
                    stream = resolver.GetEntity(new Uri(filename, UriKind.Relative), null, null) as Stream;
                }
                catch
                {
                    throw new Exception(string.Format("Failed to load: {0}!", filename));
                }
                return stream;
            }
        }

    以上如果你要的声音文件是利用context形式存在的话你可以把play方法里边的ReadMediaFile("/JacGame;component/Content/sound/" + sound),改为你的声音文件的相对地址。如(/content/sound/aa.mp3)

    希望我的回复对你有所帮助!


    jaocb lai
    2009年11月9日 6:56
    版主