Imports System.IO
Public Class Form1
Public RND As New Random
Public g As BufferedGraphics
Public g2 As BufferedGraphics
Public fonts20 As New Font("微软雅黑", 20)
Public fonts11 As New Font("微软雅黑", 11)
Public 居中画字样式 As StringFormat
Public 播放器 As 歌曲
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
g = BufferedGraphicsManager.Current.Allocate(PictureBox1.CreateGraphics, PictureBox1.DisplayRectangle)
g2 = BufferedGraphicsManager.Current.Allocate(PictureBox2.CreateGraphics, PictureBox2.DisplayRectangle)
读取音乐文件并且刷新listview1()
居中画字样式 = New StringFormat()
居中画字样式.LineAlignment = StringAlignment.Center
居中画字样式.Alignment = StringAlignment.Center
Dim 集合 As New List(Of String)
'第一种方法,可以获得索引,推荐
For I = 0 To 集合.Count - 1
Debug.Print(集合(I))
Next
'第二种方法,方便快速但是没索引或者需要另外定义变量
For Each I In 集合
Debug.Print(I)
Next
End Sub
Public Sub 读取音乐文件并且刷新listview1()
ListView1.BeginUpdate()
ListView1.Items.Clear()
' Dim files As String() = Directory.GetFiles("C:\Users\panwei\Desktop\Music")
Dim files As String() = Directory.GetFiles(Application.StartupPath)
For Each file As String In files
If Path.GetExtension(file) = ".flac" OrElse Path.GetExtension(file) = ".mp3" Then
Dim music = New 歌曲(file)
Dim t As ListViewItem = New ListViewItem({music.歌曲名, music.歌曲类型, music.歌曲长度_秒, Int(music.是否有歌词)})
t.Tag = file
t.BackColor = Color.FromArgb(RND.Next(200, 255), RND.Next(200, 255), RND.Next(200, 255))
ListView1.Items.Add(t)
music.close()
End If
Next
ListView1.EndUpdate()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If 播放器 IsNot Nothing Then
'绘制进度条和进度条歌词
g.Graphics.Clear(Color.Black)
g.Graphics.FillRectangle(Brushes.Green, New RectangleF(0, 0, 播放器.当前播放时间_百分比 * PictureBox1.Width, PictureBox1.Height))
g.Graphics.DrawString(播放器.当前播放时间_时分格式 & "/" & 播放器.歌曲长度_时分格式, fonts20, Brushes.Gold, 0, 0)
For I = 1 To 播放器.歌词.Count - 2
If 播放器.歌词(I + 1).歌词时间_秒 > 播放器.当前播放时间_秒 Then
g.Graphics.DrawString(播放器.歌词(I).歌词文本, fonts20, Brushes.Gold, New Rectangle(Point.Empty, PictureBox1.Size), 居中画字样式)
Exit For
End If
Next
g.Render()
'绘制歌词
g2.Graphics.Clear(Color.Black)
g2.Graphics.DrawString("当前歌曲没有歌词", Me.Font, Brushes.Red, 0, 0)
Dim 当前歌词 As Boolean = False
For I = 0 To 播放器.歌词.Count - 2
If 播放器.歌词(I + 1).歌词时间_秒 > 播放器.当前播放时间_秒 And 当前歌词 = False Then
Dim se = 播放器.歌词(I).颜色
Dim se2 = Color.FromArgb(se.R - 100, se.G - 100, se.B - 100)
Dim 当前歌词长度 = 播放器.歌词(I + 1).歌词时间_秒 - 播放器.歌词(I).歌词时间_秒
Dim 这句歌词现在播放到 = 播放器.当前播放时间_秒 - 播放器.歌词(I).歌词时间_秒
g2.Graphics.FillRectangle(New SolidBrush(se2), New Rectangle((I Mod 3) * (PictureBox2.Width / 3), Int(I / 3) * 当前绘制高度, (PictureBox2.Width / 3) * (这句歌词现在播放到 / 当前歌词长度), 当前绘制高度))
g2.Graphics.DrawString(播放器.歌词(I).歌词文本, fonts11, Brushes.Red, New Rectangle((I Mod 3) * (PictureBox2.Width / 3), Int(I / 3) * 当前绘制高度, (PictureBox2.Width / 3), 当前绘制高度), 居中画字样式)
当前歌词 = True
Else
g2.Graphics.FillRectangle(New SolidBrush(播放器.歌词(I).颜色), New Rectangle((I Mod 3) * (PictureBox2.Width / 3), Int(I / 3) * 当前绘制高度, (PictureBox2.Width / 3), 当前绘制高度))
Dim str = 播放器.歌词(I).歌词文本
If 显示当前歌词时间.Checked = True Then
str += vbCrLf & 播放器.歌词(I).歌词时间_分秒格式
End If
g2.Graphics.DrawString(str, Me.Font, Brushes.Black, New Rectangle((I Mod 3) * (PictureBox2.Width / 3), Int(I / 3) * 当前绘制高度, (PictureBox2.Width / 3), 当前绘制高度), 居中画字样式)
End If
Next
g2.Render()
End If
End Sub
Public 当前绘制高度 As Integer = 35
Private Sub 进度条弹起(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
If 播放器 IsNot Nothing Then
播放器.当前播放时间_百分比 = e.X / PictureBox1.Width
End If
End Sub
Private Sub PictureBox2_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox2.MouseUp
Dim X As Integer = Int(e.X / (PictureBox2.Width / 3))
Dim Y As Integer = Int(e.Y / 当前绘制高度)
Dim INDEX = X + Y * 3
If INDEX < 播放器.歌词.Count Then
播放器.当前播放时间_秒 = 播放器.歌词(INDEX).歌词时间_秒
播放器.播放音乐()
End If
End Sub
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
If ListView1.SelectedItems.Count >= 1 Then
If 播放器 IsNot Nothing Then
播放器.close()
播放器 = Nothing
End If
播放器 = New 歌曲(ListView1.SelectedItems(0).Tag)
播放器.播放音乐()
If 播放器.是否有歌词 = True Then
当前绘制高度 = PictureBox2.Height / (播放器.歌词.Count / 3 + 1)
End If
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Try
If ListView1.SelectedItems.Count >= 1 Then
If ListView1.SelectedItems(0).Index >= 1 Then
Dim ID = ListView1.SelectedItems(0).Index - 1
ListView1.SelectedItems.Clear()
ListView1.Items(ID).Selected = True
ListView1.Focus()
End If
End If
Catch ex As Exception
End Try
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
'Try
If ListView1.SelectedItems.Count >= 1 Then
If ListView1.SelectedItems(0).Index < ListView1.Items.Count - 1 Then
Dim ID = ListView1.SelectedItems(0).Index + 1
ListView1.SelectedItems.Clear()
ListView1.Items(ID).Selected = True
ListView1.Focus()
End If
End If
' Catch ex As Exception
' End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
If 播放器.播放状态 = 歌曲.播放.停止 Or 播放器.播放状态 = 歌曲.播放.暂停 Then
Button1.Text = "暂停"
播放器.播放状态 = 歌曲.播放.播放
ElseIf 播放器.播放状态 = 歌曲.播放.播放 Then
Button1.Text = "播放"
播放器.播放状态 = 歌曲.播放.暂停
End If
Catch ex As Exception
End Try
End Sub
End Class
Imports System.IO
Imports NAudio
Imports NAudio.Wave
Public Class 歌曲
Private 随机数 As Random
Private 文件流 As WaveStream
Private 播放组件 As IWavePlayer
Public 路径 As String
Public 路径_lrc As String
Public 是否有歌词 As Boolean = False
Public 歌曲名 As String
Public 歌曲类型 As String
Public 歌词 As New List(Of 单条歌词)
Public 歌曲长度_秒 As Double
Public Sub close()
播放组件.Dispose()
文件流.Dispose()
End Sub
Public Sub New(歌曲路径 As String)
文件流 = New MediaFoundationReader(歌曲路径)
播放组件 = New WaveOut()
播放组件.Init(文件流)
歌曲长度_秒 = TimeSpan转秒(文件流.TotalTime)
路径 = 歌曲路径
歌曲名 = Path.GetFileNameWithoutExtension(路径)
歌曲类型 = Path.GetExtension(路径)
随机数 = New Random
解析歌词()
End Sub
Private Sub 解析歌词()
Dim 路径_lrc = $"{ Path.GetDirectoryName(路径)}\{Path.GetFileNameWithoutExtension(路径)}.lrc"
If System.IO.File.Exists(路径_lrc) = False Then
是否有歌词 = False
Exit Sub
End If
是否有歌词 = True
Dim STR = IO.File.ReadAllText(路径_lrc)
Dim arr = Split(STR, vbLf)
For Each ss In arr
' Try
If InStr(ss, "[") > 0 And InStr(ss, "]") > 0 And InStr(ss, ":") > 0 Then
Dim 时间 = Split(ss, "]")(0)
Dim 歌词_ = Split(ss, "]")(1)
If 歌词_.Length >= 1 Then
歌词.Add(New 单条歌词(时间, 歌词_, Color.FromArgb(随机数.Next(200, 255), 随机数.Next(200, 255), 随机数.Next(200, 255))))
End If
End If
' Catch ex As Exception
' End Try
Next
End Sub
Public Structure 单条歌词
Public 歌词文本 As String
Public 歌词时间_秒 As Double
Public 歌词时间_分秒格式 As String
Public 颜色 As Color
Sub New(歌词时间 As String, 歌词_文本 As String, colors As Color)
歌词文本 = 歌词_文本
Dim str = 歌词时间
str = str.Replace("[", "")
str = str.Replace("]", "")
Try
Dim 分 = Split(str, ":")(0)
Dim 秒 = Double.Parse(Split(str, ":")(1))
歌词时间_秒 = 秒 + 分 * 60
歌词时间_分秒格式 = $"{分}:{Int(秒)}"
颜色 = colors
Catch ex As Exception
End Try
End Sub
End Structure
Public Sub 播放音乐()
播放组件.Play()
End Sub
Public Sub 暂停音乐()
播放组件.Pause()
End Sub
Public Sub 停止音乐()
播放组件.Stop()
当前播放时间_百分比 = 0
End Sub
Public Property 当前播放时间_百分比() As Double
Get
Return 当前播放时间_秒 / 歌曲长度_秒
End Get
Set(ByVal value As Double)
文件流.Position = value * 文件流.Length
End Set
End Property
Public Shared Function TimeSpan转秒(T As TimeSpan) As Double
Return T.Minutes * 60 + T.Seconds + T.Milliseconds / 1000
End Function
Public Shared Function 秒转时分格式(s As Double) As String
Return Strings.Right("0" & Int(s / 60), 2) & ":" & Strings.Right("0" & Int(s Mod 60), 2)
End Function
Public ReadOnly Property 当前播放时间_时分格式() As String
Get
Return 秒转时分格式(TimeSpan转秒(文件流.CurrentTime))
End Get
End Property
Public ReadOnly Property 歌曲长度_时分格式() As String
Get
Return 秒转时分格式(歌曲长度_秒)
End Get
End Property
Public Property 当前播放时间_秒() As Double
Get
Return TimeSpan转秒(文件流.CurrentTime)
End Get
Set(ByVal value As Double)
文件流.Position = (value / 歌曲长度_秒) * 文件流.Length
End Set
End Property
Public Property 播放状态() As 播放
Get
If 播放组件.PlaybackState = PlaybackState.Playing Then Return 播放.播放
If 播放组件.PlaybackState = PlaybackState.Paused Then Return 播放.暂停
If 播放组件.PlaybackState = PlaybackState.Stopped Then Return 播放.停止
End Get
Set(ByVal value As 播放)
If value = 播放.播放 Then 播放音乐()
If value = 播放.暂停 Then 暂停音乐()
If value = 播放.停止 Then 停止音乐()
End Set
End Property
Public Enum 播放
停止 = 0
播放 = 1
暂停 = 2
End Enum
End Class