【问题标题】:.net mcisendstring - Using resources instead of full paths.net mcisendstring - 使用资源而不是完整路径
【发布时间】:2012-03-14 15:43:03
【问题描述】:

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

以下是 mcisendstring 的一些怪癖:

  • mcisendstring 讨厌空格,空格会导致崩溃(无法加载文件) - 添加引号
  • 路径中的点会导致加载失败(仅点应用于扩展)
  • 非常长的路径会导致加载失败(允许的最大字符数为 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

附:我在我的项目中使用 XNA Graphics,而且我还有 NuGet 的 BizArk Core。因此,如果我可以使用其中任何一个,请告诉我如何使用其中任何一个来完成我需要做的事情。提前感谢您的帮助。

【问题讨论】:

  • 这对于 mciSendString 是不可能的。但当然可以使用 XNA:msdn.microsoft.com/en-us/library/bb195053.aspx
  • 好的,我查看了页面,但是,它对我没有任何帮助,哈哈。我将如何在 .net 中执行此操作(不是 C# 或 C++)

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


【解决方案1】:

如上所述,这是一个旧线程,但我想 Google 仍然会有人找到它(就像我今天所做的那样)。

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

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

下面非常简单的代码可以做到这一点:

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)

【讨论】:

    【解决方案2】:

    我知道这是一个超级旧的线程,但如果它对任何人有帮助,这里有一个解决方案。

    您必须使用完整路径,但假设您的资源存储在 /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/,让你不知道你的文件夹的完整路径,因为VB.NET 会自己找到它。

    【讨论】:

    • 这个答案毫无意义,因为资源的全部意义在于它们不是文件,而是编译成可执行文件的数据。项目中的资源文件夹仅用于存储源文件。将 EXE 从输出文件夹复制到另一台机器后,就应用程序而言,该文件夹不再存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    相关资源
    最近更新 更多