naudio 在处理 vb.net 后没有释放文件,我认为这确实是一个声明问题
naudio not releasing file after dispose vb.net, It's really an declaration issue I think
我只有在真正卡住的时候才会post这里,所以就这样吧。
我正在创建一个程序,我可以使用 taglib-sharp 编辑 MP3 文件的元数据(所有数据都来自 mysql 数据库)。
如果我使用 naudio 预览音频文件,我可以听到音频没有问题并且我可以停止它,所以一切都很好。
为了我的代码中发生的事情,这是从列表框中选择一个文件的问题,然后我按下 'play' 按钮开始,然后按下另一个按钮停止。我的错误是在我尝试保存元数据时显示右键单击上下文菜单。
问题是当我去编辑我刚刚播放的同一个文件的元数据时,出现错误 - 正如下面的代码示例所示。当我尝试调用 mp3.save() 行时,我收到以下错误:
************** 异常文本 **************
System.IO.IOException: The process cannot access the file
'C:\temp\test.mp3' because it is being used by another process. at
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess
access, Int32 rights, Boolean useRights, FileShare share, Int32
bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String
msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess
access, FileShare share) at
TagLib.File.LocalFileAbstraction.get_WriteStream() at
TagLib.File.set_Mode(AccessMode value) at
TagLib.NonContainer.File.Save() at
LinersDB_META.Form1.menuChoice(Object sender, EventArgs e) in
C:\Users\smonro\source\repos\WindowsApp1\WindowsApp1\Form1.vb:line
2281 at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key,
EventArgs e) at
System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e) at
System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) at
System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea) at
System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks) at
System.Windows.Forms.Control.WndProc(Message& m) at
System.Windows.Forms.ToolStrip.WndProc(Message& m) at
System.Windows.Forms.ToolStripDropDown.WndProc(Message& m) at
System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg,
IntPtr wparam, IntPtr lparam)
等等
我知道为什么会这样,但我不知道如何解决它。
根据这个 page,(在 C# 中)我需要发布 "Mp3FileReader"。
在我的例子中,它将是 "data" - 这个:
将数据调暗为新 NAudio.Wave.Mp3FileReader(file)
问题是,它作为私有变量在私有子程序中。
但是,当我需要同时声明文件时,我正在努力了解如何进行此声明 public,但它也需要知道,并且每次我选择时都重新初始化不同的音频文件。
有什么想法吗?
我是否应该尝试重新安排我的程序以不同方式工作?提前致谢。
'...
Imports System.IO 'File Operations
Imports TagLib ' Tagging
Imports NAudio
'...
'Wave out device for playing the sound
Public Shared Wave1 As New NAudio.Wave.WaveOut 'Wave out device for playing the sound
Public Sub start_audio()
Dim file As String = "C:\test\test.mp3"
If IO.File.Exists(file) Then
Dim data As New NAudio.Wave.Mp3FileReader(file)
Wave1.Init(data)
Wave1.Play()
End If
End Sub
Public Sub Button5_Click_1(sender As Object, e As EventArgs) Handles Button5.Click
Wave1.Stop()
End Sub
Public Sub menuChoice(ByVal sender As Object, ByVal e As EventArgs)
Dim item = CType(sender, ToolStripMenuItem)
Dim selection = CInt(item.Tag)
Select Case selection
Case 1
' Remove the Artwork
'Insert Album art and save to file and dispose.
If IO.File.Exists(GLOBAL_Full_Path) Then
Wave1.Stop()
Wave1.Dispose()
System.GC.Collect()
System.GC.WaitForPendingFinalizers()
Dim mp3 As TagLib.File = TagLib.File.Create(GLOBAL_Full_Path)
' Clear the artwork from the file.. (It's a big process)
Dim pics As Picture = New Picture()
Dim picsFrame As New TagLib.Id3v2.AttachedPictureFrame(pics)
picsFrame.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg
'set the type of picture (front cover)
picsFrame.Type = TagLib.PictureType.FrontCover
picsFrame.Description = "" ' So the Actual location of the image is not stored in the file. This would otherwise reveal internal systems to the public.
'Id3v2 allows more than one type of image, just one is needed here.
Dim pictFrames() As TagLib.IPicture = {picsFrame}
'set the pictures in the tag
mp3.Tag.Pictures = pictFrames
' ******************************************
' Error occurs here after a file has been played.
mp3.Save()
' Error occurs here
' ******************************************
mp3.Dispose()
End If
Case Else
End Select
End Sub
经过@TnTinMn 的指点,我终于解决了这个问题。虽然这不是完整的示例,但我现在通过添加和更改一些小的东西解决了这个问题。
Imports NAudio
' NEW/required to get the Mp3FileReader, so it can be dynamically populated.
Imports NAudio.Wave
Dim WavePlayOut As New NAudio.Wave.WaveOut 'Wave out device for playing the sound
Dim WaveFile As String = "" ' *** NEW/Declared ***
Dim WaveData As Mp3FileReader ' *** Changed ***
Public Sub start_audio()
If File_ListView.SelectedItems.Count > 0 Then
WaveFile = TxtBx_Path.Text & "\" & File_ListView.FocusedItem.Text
If WavePlayOut IsNot Nothing Then
WavePlayOut = New NAudio.Wave.WaveOut
End If
If WaveData IsNot Nothing Then
WaveData.Dispose()
WaveData = New Mp3FileReader(WaveFile)
If WaveData.Length > 1 Then
If IO.File.Exists(WaveFile) Then
WavePlayOut.Init(WaveData)
WavePlayOut.Play()
End If
End If
Else
WaveData = New Mp3FileReader(WaveFile)
If WaveData.Length > 1 Then
If IO.File.Exists(WaveFile) Then
WavePlayOut.Init(WaveData)
WavePlayOut.Play()
End If
End If
End If
End If
End Sub
要卸载音频文件,请使用以下命令:
If WaveData IsNot Nothing Then
WaveData.Dispose()
End If
If WavePlayOut IsNot Nothing Then
WavePlayOut.Stop()
WavePlayOut.Dispose()
End If
我只有在真正卡住的时候才会post这里,所以就这样吧。
我正在创建一个程序,我可以使用 taglib-sharp 编辑 MP3 文件的元数据(所有数据都来自 mysql 数据库)。 如果我使用 naudio 预览音频文件,我可以听到音频没有问题并且我可以停止它,所以一切都很好。 为了我的代码中发生的事情,这是从列表框中选择一个文件的问题,然后我按下 'play' 按钮开始,然后按下另一个按钮停止。我的错误是在我尝试保存元数据时显示右键单击上下文菜单。
问题是当我去编辑我刚刚播放的同一个文件的元数据时,出现错误 - 正如下面的代码示例所示。当我尝试调用 mp3.save() 行时,我收到以下错误:
************** 异常文本 **************
System.IO.IOException: The process cannot access the file 'C:\temp\test.mp3' because it is being used by another process. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) at TagLib.File.LocalFileAbstraction.get_WriteStream() at TagLib.File.set_Mode(AccessMode value) at TagLib.NonContainer.File.Save() at LinersDB_META.Form1.menuChoice(Object sender, EventArgs e) in C:\Users\smonro\source\repos\WindowsApp1\WindowsApp1\Form1.vb:line 2281 at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea) at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ToolStrip.WndProc(Message& m) at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
等等
我知道为什么会这样,但我不知道如何解决它。
根据这个 page,(在 C# 中)我需要发布 "Mp3FileReader"。
在我的例子中,它将是 "data" - 这个: 将数据调暗为新 NAudio.Wave.Mp3FileReader(file)
问题是,它作为私有变量在私有子程序中。
但是,当我需要同时声明文件时,我正在努力了解如何进行此声明 public,但它也需要知道,并且每次我选择时都重新初始化不同的音频文件。
有什么想法吗?
我是否应该尝试重新安排我的程序以不同方式工作?提前致谢。
'...
Imports System.IO 'File Operations
Imports TagLib ' Tagging
Imports NAudio
'...
'Wave out device for playing the sound
Public Shared Wave1 As New NAudio.Wave.WaveOut 'Wave out device for playing the sound
Public Sub start_audio()
Dim file As String = "C:\test\test.mp3"
If IO.File.Exists(file) Then
Dim data As New NAudio.Wave.Mp3FileReader(file)
Wave1.Init(data)
Wave1.Play()
End If
End Sub
Public Sub Button5_Click_1(sender As Object, e As EventArgs) Handles Button5.Click
Wave1.Stop()
End Sub
Public Sub menuChoice(ByVal sender As Object, ByVal e As EventArgs)
Dim item = CType(sender, ToolStripMenuItem)
Dim selection = CInt(item.Tag)
Select Case selection
Case 1
' Remove the Artwork
'Insert Album art and save to file and dispose.
If IO.File.Exists(GLOBAL_Full_Path) Then
Wave1.Stop()
Wave1.Dispose()
System.GC.Collect()
System.GC.WaitForPendingFinalizers()
Dim mp3 As TagLib.File = TagLib.File.Create(GLOBAL_Full_Path)
' Clear the artwork from the file.. (It's a big process)
Dim pics As Picture = New Picture()
Dim picsFrame As New TagLib.Id3v2.AttachedPictureFrame(pics)
picsFrame.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg
'set the type of picture (front cover)
picsFrame.Type = TagLib.PictureType.FrontCover
picsFrame.Description = "" ' So the Actual location of the image is not stored in the file. This would otherwise reveal internal systems to the public.
'Id3v2 allows more than one type of image, just one is needed here.
Dim pictFrames() As TagLib.IPicture = {picsFrame}
'set the pictures in the tag
mp3.Tag.Pictures = pictFrames
' ******************************************
' Error occurs here after a file has been played.
mp3.Save()
' Error occurs here
' ******************************************
mp3.Dispose()
End If
Case Else
End Select
End Sub
经过@TnTinMn 的指点,我终于解决了这个问题。虽然这不是完整的示例,但我现在通过添加和更改一些小的东西解决了这个问题。
Imports NAudio
' NEW/required to get the Mp3FileReader, so it can be dynamically populated.
Imports NAudio.Wave
Dim WavePlayOut As New NAudio.Wave.WaveOut 'Wave out device for playing the sound
Dim WaveFile As String = "" ' *** NEW/Declared ***
Dim WaveData As Mp3FileReader ' *** Changed ***
Public Sub start_audio()
If File_ListView.SelectedItems.Count > 0 Then
WaveFile = TxtBx_Path.Text & "\" & File_ListView.FocusedItem.Text
If WavePlayOut IsNot Nothing Then
WavePlayOut = New NAudio.Wave.WaveOut
End If
If WaveData IsNot Nothing Then
WaveData.Dispose()
WaveData = New Mp3FileReader(WaveFile)
If WaveData.Length > 1 Then
If IO.File.Exists(WaveFile) Then
WavePlayOut.Init(WaveData)
WavePlayOut.Play()
End If
End If
Else
WaveData = New Mp3FileReader(WaveFile)
If WaveData.Length > 1 Then
If IO.File.Exists(WaveFile) Then
WavePlayOut.Init(WaveData)
WavePlayOut.Play()
End If
End If
End If
End If
End Sub
要卸载音频文件,请使用以下命令:
If WaveData IsNot Nothing Then
WaveData.Dispose()
End If
If WavePlayOut IsNot Nothing Then
WavePlayOut.Stop()
WavePlayOut.Dispose()
End If