.net mcisendstring - 使用资源而不是完整路径

时间:2012-03-14 15:43:03

标签: .net audio audio-streaming embedded-resource mcisendstring

好的,所以我使用mciSendString创建了一个SOUND类。我用它来播放我正在制作的RPG风格游戏的音乐和其他声音文件。它有效,而且效果很好......但是。我的问题是它需要声音文件的完整整个路径才能使它工作(不确定这是否正确)。

以下是mcisendstring的一些问题:

  • mcisendstring仇恨空格,空格会导致崩溃(无法加载文件) - ADD QUOTES
  • 路径中的点可能导致无法加载(只有点应该用于扩展)
  • 非常长的路径将导致加载失败(允许的最大字符数为255)
  • 相对路径会导致加载失败...(不能使用像chicken.mp3这样的东西......必须使用C:\ chicken.mp3)
  • 如果repeat = true ,
  • .wav文件将无法加载

我尝试将文件添加到我的资源并尝试设置资源的路径,但它说:Value of type '1-dimensional array of Byte' cannot be converted to 'String'

非常感谢任何帮助:)

这是我的代码:

Public Class SOUND

Public Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
(ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Integer, ByVal hwndCallback As Integer) As Integer
'Command String VERY IMPORTANT

Private oName As String = Nothing

Public Property Name As String
    Set(value As String)
        oName = value
    End Set
    Get
        Return oName
    End Get
End Property

Public Sub Play(ByVal id As Integer, ByVal repeat As Boolean, Optional volume As Integer = 1000)

    If repeat = True Then

        mciSendString("Open " & GetFile(id) & " alias " & oName, CStr(0), 0, 0) 'Open the file
        mciSendString("play " & oName & " repeat ", CStr(0), 0, 0) 'then play with repeating value

    Else

        mciSendString("Open " & GetFile(id) & " alias " & oName, CStr(0), 0, 0)
        mciSendString("play " & oName, CStr(0), 0, 0)

    End If

    'Optionally Set Volume
    mciSendString("setaudio " & oName & " volume to " & volume, CStr(0), 0, 0)

End Sub

Public Sub Kill(ByVal song As String)

    mciSendString("close " & song, CStr(0), 0, 0)
    oName = Nothing

End Sub

' Media Library
Private Function GetFile(ByVal id As Integer) As String

    Dim path As String = ""

    'mcisendstring Hates spaces, spaces will cause crash (failure to load file) - ADD QUOTES
    'Dots in path can cause failure to load (only dot should be for the extention)
    'Very Long Paths will cause failure to load (Max Characters allowed is 255)
    'Relative paths will cause failure to load...(cannot use something like chicken.mp3 ... must use ex:[C:\chicken.mp3])
    '.wav files will fail to load if repeat = true

    Select Case id

        Case 0 'Game Over

            path = "C:\FinalFantasy7-SendaDreamIntoTheUniverse.mp3"

        Case 1 'Battle Sequence

            path = "C:\FinalFantasyTactics-Garland_Magic.mp3"

        Case 2 'Battle Victory

            path = "C:\FinalFantasyLegend2-Victory.mp3"

        Case 3 'Mission Time

            path = "C:\FinalFantasyAdventure-Mission.mp3"

    End Select

    path = Chr(34) & path & Chr(34)
    'Chr(34) is quotes...cannot just use "" because it will think that it is part of the string/path itself.


    Return path
End Function

结束班

我需要什么:

  • 我需要以某种方式将.mp3文件作为可用于路径的资源,或者我需要一些其他方法,而不是将这些文件放在根驱动器或其他完整的计算机路径中。

我需要的一些例子

更改

Select Case id

            Case 0 'Game Over

                path = "C:\FinalFantasy7-SendaDreamIntoTheUniverse.mp3"
End Select

Select Case id

            Case 0 'Game Over

                path = My.Resources.FinalFantasyAdventure_Mission
End Select

我如何播放声音:

(在另一个测试表格上)

Dim intSound As Integer = 0
Dim snd As New SOUND 'SOUND is the sound class with mcisendstring

Private Sub PlaySoundBtn_Click(sender As System.Object, e As System.EventArgs) Handles PlaySoundBtn.Click

    intSound += 1

    With snd
        .Name = "SOUND" & intSound 'SOUND is the alias along with the number (this one is SOUND1)
        .Play(3, True, 500)
        '3 is the song ID, True is for the repeat, 500 is for the optional volume (Max = 1000)
    End With

End Sub

P.S。我在我的项目中使用XNA Graphics,我也有NuGet的BizArk Core。因此,如果我可以使用其中任何一个,那么请告诉我如何使用其中任何一个来做我需要做的事情。提前感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

如上所述,这是一个老话题,但我想谷歌仍会有人找到它(就像我今天所做的那样)。

只是一个额外的建议,有时您不会将您的音频文件放在输出目录中,或者可能希望分发独立​​的可执行文件。还存在可以从输出目录中删除文件的风险,并且能够重新创建它是很方便的。此外,将资源作为可执行文件的一部分并在输出目录中占用的空间不仅仅是将其作为可执行文件的一部分,因此有时仅值暂时将文件放在磁盘上(并在以后删除它) )而不是必须有永久副本,所以你可以访问它。

在这些情况下,能够在运行时从资源中获取文件并将其保存到您可以访问的某个位置(如果您想稍后删除它可能是临时文件位置),这很有用。

以下非常简单的代码可以做到:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

    SaveResourceObject("FinalFantasyAdventure_Mission", "C:\FinalFantasyAdventure_Mission.mp3")

End Sub

Sub SaveResourceObject(Resource as String, FileName as String)
    Dim myMemStream As New System.IO.MemoryStream
    My.Resources.ResourceManager.GetObject(Resource).CopyTo(myMemStream)
    Dim myBytes() As Byte = myMemStream.ToArray
    My.Computer.FileSystem.WriteAllBytes(FileName, myBytes, False)
End Sub

注意,上面代码中的Resource变量实际上是资源的名称,而不是资源本身。因此,如果您尝试执行以下操作,则会收到错误:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    SaveResourceObject(My.Resources.FinalFantasyAdventure_Mission, "C:\FinalFantasyAdventure_Mission.mp3")
End Sub

如果您愿意,可以轻松修改代码以接受实际资源作为参数。

注意,我已经使用过" C:\"在上面的示例中,我建议您在应用程序数据文件夹中创建自己的文件夹,您可以使用该文件夹找到:

Dim AppDataPath as String = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData)

或者,更简单地说,如果您已导入System.Environment:

Dim AppDataPath as String = GetFolderPath(SpecialFolder.ApplicationData)

答案 1 :(得分:-1)

我知道这是一个超级老线程,但如果它对任何人都有帮助,那么这就是解决方案。

您必须使用完整路径,但假设您的资源存储在/projectfolder/resources/中,您可以使用

Dim filePath As String = Chr(34) & Application.StartupPath & "/../../Resources/myMusic.mp3" & Chr(34)
mciSendString("open " & filePath & " alias myMusic", CStr(0), 0, 0)

在VB.NET项目中,Application.StartupPath是存储.exe的文件夹的完整路径。通常是path/projectfolder/bin/debug/path/projectfolder/bin/release/的文件夹。将/../../resources/附加到/projectfolder/resources/会使您进入httpd -t,这样您就不会知道文件夹的完整路径,因为VB.NET会找到它。

相关问题