VB.net单exe文件内MP3和WAV音乐文件播放
一、实现音乐文件(MP3和WAV)内嵌exe
笔者使用的开发环境为VS2017,具体添加步骤如下图所示,将1.mp3和2.wav添加到Resources目录下,然后鼠标右击选择属性,然后在资源里把将1.mp3和2.wav在添加一遍,即可完成音乐文件的内嵌。
二、实现WAV音乐播放
.net框架下自带了WAV的播放类 My.Computer.Audio,可以简单的调用Play和Stop方法实现WAV的播放和停止
'wav播放
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
My.Computer.Audio.Play(My.Resources._2, AudioPlayMode.Background)
End Sub
'wav停止
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
My.Computer.Audio.Stop()
End Sub
三、实现MP3音乐播放
通常使用 media player 控件来播放,但如果添加了 media player 控件的话会增加一个 wmp.dll 文件, 不符合要求, 所以这里使用一个 API 函数来播放
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long,ByVal hwndCallback As Long) As Long
mciSendString具体的使用方法这里就不在详细描述,可以到https://baike.baidu.com/item/mciSendString/2905255?fr=aladdin研究。
mciSendString播放过程中碰到界面卡住的问题,考虑使用多线程,不料,使用线程播放后根本播放不了,后来参考了https://www.codeproject.com/questions/183548/how-to-use-mcisendstring-in-a-threaded-application后成功解决了多线程播放问题。
'多线程播放实现类(需放在窗口类的后面否则无法正常运行)
Public Class mciTest
Private mciConsumerThread As Thread
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long,
ByVal hwndCallback As Long) As Long
Private Declare Auto Function PlaySound Lib "winmm.dll" (ByVal lpszSoundName As String, ByVal hModule As Integer, ByVal dwFlags As Integer) As Integer
Dim syncMciResult As Long
Public Sub New()
' The consumer side is started in its own thread
' create one from where the mciSendString method gets called
mciConsumerThread = New Thread(AddressOf threadedMCIconsumer)
mciConsumerThread.IsBackground = True
mciConsumerThread.Start()
End Sub
Private Sub threadedMCIconsumer()
Do
SyncLock MonitorLock
' wait for relase of MonitorLock object;
' when this statement exits, a new mciCommand
' has been issued
Monitor.Wait(MonitorLock)
' the object has been released, so make the mci call
' from this thread and put the return value into the
' syncMciResult field
If syncMciCommand <> "" Then
syncMciResult = mciSendString(syncMciCommand, Nothing, 0, IntPtr.Zero)
End If
' tell the other thread that a result has been obtained.
Monitor.Pulse(MonitorLock) ' [This exits the Monitor.wait(MonitorLock)
' command on the other thread.]
' start loop all over again, waiting for the next command.
End SyncLock
Loop
' As this is a background-thread, the loop exits
' when the thread is aborted from outside.
End Sub
' The producer is the command being called instead of issuing
' mciSendString directly:
Public Function mciReplacement(ByVal Command As String) As Integer
Dim nonLockedReturn As Integer ' this will be the return value
SyncLock MonitorLock
' The MonitorObject has been freed temporarily by the
' threadedMCIconsumer thread.
' Grab the syncMciCommand variable and memorize the mciCommand
syncMciCommand = Command
' Release the MonitorObject, so the other thread
' can process the mciSendString
Monitor.Pulse(MonitorLock) ' [This exits the Monitor.wait(MonitorLock) command
' on the other thread.]
' Now wait until the mci-thread signals the arrival of the result.
Monitor.Wait(MonitorLock)
' result has been written into syncMciResult
nonLockedReturn = syncMciResult
End SyncLock
' use nonLockedReturn to get the result safely out of SyncLock
Return nonLockedReturn
End Function
'The synced variables need to be defined
Private MonitorLock As New Object()
Private mciReturnValue As Integer
Private syncMciCommand As String
End Class
’具体窗体实现播放、暂停、恢复、停止功能
Imports System.Threading '多线程
Public Class Form1
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long,
ByVal hwndCallback As Long) As Long
'Private Declare Auto Function PlaySound Lib "winmm.dll" (ByVal lpszSoundName As String, ByVal hModule As Integer, ByVal dwFlags As Integer) As Integer
Dim mName
Dim cMci As New mciTest()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
mName = Get_MP3()
mciSendString("open " & mName & " Alias audiofile", "", 0, 0)
'cMci.mciReplacement("open " & mName & " alias audiofile")
End Sub
''获取wav文件
'Function Get_WAV()
' Dim path As String = Application.StartupPath + "\2.wav"
' Dim fs As New System.IO.FileStream(path, System.IO.FileMode.Create)
' fs.Write(My.Resources._2, 0, My.Resources._2.Length)
' fs.Close()
' Return path
'End Function
'获取MP3文件
Function Get_MP3()
Dim path As String = Application.StartupPath + "\1.mp3"
Dim fs As New System.IO.FileStream(path, System.IO.FileMode.Create)
fs.Write(My.Resources._1, 0, My.Resources._1.Length)
fs.Close()
Return path
End Function
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
cMci.mciReplacement("open " & mName & " alias audiofile")
cMci.mciReplacement("play audiofile")
'cMci.mciReplacement("pause audiofile")
'cMci.mciReplacement("resume audiofile")
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
cMci.mciReplacement("stop audiofile")
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
cMci.mciReplacement("pause audiofile")
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
cMci.mciReplacement("resume audiofile")
End Sub
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
System.IO.File.Delete(mName) '退出程序后删除音乐文件
End Sub
'wav播放
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
My.Computer.Audio.Play(My.Resources._2, AudioPlayMode.Background)
End Sub
'wav停止
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
My.Computer.Audio.Stop()
End Sub
End Class