.net mcisendstring - использование ресурсов вместо полных путей - PullRequest
0 голосов
/ 14 марта 2012

Хорошо, поэтому я создал класс SOUND, используя mciSendString. Я использую его для воспроизведения музыки и других звуковых файлов для создаваемой мной игры в стиле RPG. Это работает, и это работает хорошо ... однако. Моя проблема в том, что ему нужен полный путь к звуковому файлу, чтобы он работал (не уверен, правда ли это).

Вот некоторые из особенностей mcisendstring:

  • mcisendstring Ненавидит пробелы, пробелы могут вызвать сбой (сбой при загрузке файла) - ДОБАВИТЬ ЦИТАТЫ
  • Точки в пути могут вызвать сбой загрузки (для расширения должна быть только точка)
  • Очень длинные пути вызовут сбой при загрузке (максимально допустимое количество символов - 255)
  • Относительные пути вызовут сбой при загрузке ... (нельзя использовать что-то вроде chicken.mp3 ... необходимо использовать C: \ chicken.mp3)
  • .wav файлы не будут загружаться, если repeat = true

Я попытался добавить файлы к своим ресурсам и попытался установить путь к ресурсу, однако он сказал: 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 в своем проекте, и у меня также есть ядро ​​BizArk NuGet. Так что, если я могу использовать любой из них, пожалуйста, скажите мне, как я могу использовать любой из них, чтобы сделать то, что мне нужно сделать. Заранее спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 16 сентября 2017

Как уже упоминалось выше, это старая ветка, но я думаю, что в 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)
0 голосов
/ 02 ноября 2015

Я знаю, что это супер старая тема, но если она кому-нибудь поможет, вот решение.

Вам придется использовать полный путь, но, если ваши ресурсы хранятся в /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 находит его сам.

...