' ***********************************************************************
' Author : Elektro
' Modified : 07-21-2014
' ***********************************************************************
' <copyright file="PlaylistEditor.vb" company="Elektro Studios">
' Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************
#Region " Imports "
Imports System.ComponentModel
Imports System.IO
Imports System.Text
#End Region
#Region " PlaylistEditor "
''' <summary>
''' Contains methods to manage the contents of a multimedia playlist file.
''' This class cannot be inherited.
''' </summary>
Public NotInheritable Class PlaylistEditor
#Region " Properties "
''' <summary>
''' Gets the playlist filepath.
''' </summary>
''' <value>The playlist filepath.</value>
Public ReadOnly Property FilePath As String
Get
Return Me._FilePath
End Get
End Property
Private _FilePath As String
''' <summary>
''' Gets the playlist type.
''' </summary>
''' <value>The playlist type.</value>
Public ReadOnly Property Type
Get
Return Me._Type
End Get
End Property
Private _Type As PlaylistType
''' <summary>
''' Gets the playlist file encoding.
''' </summary>
''' <value>The playlist file encoding.</value>
Public ReadOnly Property FileEncoding As Encoding
Get
Return Me._Encoding
End Get
End Property
Private _Encoding As Encoding
''' <summary>
''' Gets a value indicating whether the append mode is activated.
''' </summary>
''' <value><c>true</c> if append mode is activated; otherwise, <c>false</c>.</value>
Public ReadOnly Property Append As Boolean
Get
Return Me._Append
End Get
End Property
Private _Append As Boolean
#End Region
#Region " Enumerations "
''' <summary>
''' Indicates the type of a playlist.
''' </summary>
<Description("Enumeration used as 'PlaylistType' parameter of 'New' constructor.")>
Public Enum PlaylistType As Integer
''' <summary>
''' M3U Playlist.
''' Documentation: http://en.wikipedia.org/wiki/M3U
''' </summary>
M3U = 0I
''' <summary>
''' PLS Playlist.
''' Documentation: http://en.wikipedia.org/wiki/PLS_%28file_format%29
''' </summary>
PLS = 1I
End Enum
#End Region
#Region " Types "
''' <summary>
''' Contains extended info of a playlist track.
''' </summary>
Public Class TrackInfo
#Region " Properties "
''' <summary>
''' Gets the track index.
''' Don't set this value manually.
''' This value is automatically set by some of the <see cref="PlaylistEditor"/> methods,
''' and has any effect for other purposes.
''' </summary>
''' <value>The track index.</value>
Public Property Index As Integer
''' <summary>
''' Gets or sets the track filepath.
''' </summary>
''' <value>The track filepath.</value>
Public Property Path As String
''' <summary>
''' Gets or sets the track title.
''' </summary>
''' <value>The track title.</value>
Public Property Title As String
''' <summary>
''' Gets or sets the track length.
''' </summary>
''' <value>The track length.</value>
Public Property Length As TimeSpan
#End Region
#Region " Hidden Methods "
''' <summary>
''' Serves as a hash function for a particular type.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub GetHashCode()
End Sub
''' <summary>
''' Determines whether the specified System.Object instances are considered equal.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub Equals()
End Sub
''' <summary>
''' Determines whether the specified System.Object instances are the same instance.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Private Shadows Sub ReferenceEquals()
End Sub
''' <summary>
''' Returns a String that represents the current object.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub ToString()
End Sub
#End Region
End Class
#End Region
#Region " Constructors "
''' <summary>
''' Prevents a default instance of the <see cref="PlaylistEditor"/> class from being created.
''' </summary>
Private Sub New()
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="PlaylistEditor"/> class.
''' </summary>
''' <param name="PlaylistFile">Indicates the playlist filepath.</param>
''' <param name="PlaylistType">Indicates the type of the playlist.</param>
''' <param name="Append">
''' If set to <c>true</c> the <see cref="PlaylistEditor"/> instance will assume that the playlist file already exist,
''' and will append any new entries in the existing file.
''' If set to <c>false</c> the <see cref="PlaylistEditor"/> instance will assume that the playlist file does not exist,
''' and will create the file.
''' </param>
''' <param name="FileEncoding">
''' Optionally indicates the file encoding to write/read the playlist content.
''' The default value is <see cref="Encoding.Default"/>
''' </param>
Public Sub New(ByVal PlaylistFile As String,
ByVal PlaylistType As PlaylistType,
ByVal Append As Boolean,
Optional ByVal FileEncoding As Encoding = Nothing)
Me._FilePath = PlaylistFile
Me._Type = PlaylistType
Me._Encoding = If(FileEncoding IsNot Nothing, FileEncoding, Encoding.Default)
Me._Append = Append
If Not _Append Then
Me.AddHeaders()
End If
End Sub
#End Region
#Region " Hidden Methods "
''' <summary>
''' Serves as a hash function for a particular type.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub GetHashCode()
End Sub
''' <summary>
''' Determines whether the specified System.Object instances are considered equal.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub Equals()
End Sub
''' <summary>
''' Determines whether the specified System.Object instances are the same instance.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Private Shadows Sub ReferenceEquals()
End Sub
''' <summary>
''' Returns a String that represents the current object.
''' </summary>
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub ToString()
End Sub
#End Region
#Region " Private Methods "
''' <summary>
''' Adds the playlist headers in the playlist file.
''' This method should be called first before add any entry in the playlist.
''' </summary>
Private Sub AddHeaders()
Dim sb As New StringBuilder
Select Case Me._Type
Case PlaylistType.M3U
sb.AppendLine("#EXTM3U")
Case PlaylistType.PLS
With sb
.AppendLine("[playlist]")
.AppendLine("NumberOfEntries=0")
.AppendLine("Version=2")
End With
End Select
File.
WriteAllText(Me._FilePath, sb.
ToString,
Me._Encoding
) sb.Clear()
End Sub
''' <summary>
''' Gets the amount of total entries of a PLS playlist file.
''' </summary>
''' <returns>The current number of total entries.</returns>
Private Function GetPLSNumberOfEntries() As Integer
Dim PlaylistContent
As String = File.
ReadAllText(Me._FilePath,
Me._Encoding
)
Dim StartIndex As Integer =
PlaylistContent.IndexOf("=") + 1I
Dim EndIndex As Integer =
PlaylistContent.IndexOf(ControlChars.NewLine, StartIndex) - StartIndex
Return PlaylistContent.Substring(StartIndex, PlaylistContent.IndexOf(String.Empty, EndIndex))
End Function
''' <summary>
''' Fixes the track index count of a PLS playlist file.
''' This method shoould be called after remove a track from the playlist.
''' </summary>
Private Sub FixPLSTrackIndex()
Dim PlaylistContent
As List
(Of String) = File.
ReadAllLines(Me._FilePath,
Me._Encoding
).
ToList Dim TrackCount As Integer = 0I
For Index As Integer = 0 To (PlaylistContent.Count - 1I)
If PlaylistContent(Index).StartsWith("File", StringComparison.OrdinalIgnoreCase) Then
TrackCount += 1I
PlaylistContent(Index) = String.Format("File{0}={1}",
CStr(TrackCount),
PlaylistContent(Index).Substring(PlaylistContent(Index).IndexOf("="c) + 1I))
ElseIf PlaylistContent(Index).StartsWith("Title", StringComparison.OrdinalIgnoreCase) Then
PlaylistContent(Index) = String.Format("Title{0}={1}",
CStr(TrackCount),
PlaylistContent(Index).Substring(PlaylistContent(Index).IndexOf("="c) + 1I))
ElseIf PlaylistContent(Index).StartsWith("Length", StringComparison.OrdinalIgnoreCase) Then
PlaylistContent(Index) = String.Format("Length{0}={1}",
CStr(TrackCount),
PlaylistContent(Index).Substring(PlaylistContent(Index).IndexOf("="c) + 1I))
End If
Next Index
Dim NumberOfEntriesEntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.ToLower Like "numberofentries=#*"
End Function)
PlaylistContent(NumberOfEntriesEntryIndex) =
String.Format("NumberOfEntries={0}", CStr(TrackCount))
File.
WriteAllLines(Me._FilePath, PlaylistContent,
Me._Encoding
)
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Adds a new track entry in the playlist.
''' </summary>
''' <param name="Path">Indicates the track path to add.</param>
''' <param name="AllowDuplicate">
''' If set to <c>true</c> an exception will be thrown if the track already exists in the playlist.
''' </param>
''' <exception cref="System.Exception">The TrackPath already exist in the playlist.</exception>
Public Sub Add(ByVal [Path] As String,
Optional ByVal AllowDuplicate As Boolean = False)
If Not AllowDuplicate AndAlso Me.Exist([Path]) Then
Throw New Exception("The TrackPath already exist in the playlist.") With {.Source = [Path]}
End If
Dim sb As New StringBuilder
Select Case Me._Type
Case PlaylistType.M3U
With sb
.AppendLine()
.AppendLine([Path])
File.
AppendAllText(Me._FilePath, .
ToString,
Me._Encoding
) .Clear()
End With
Case PlaylistType.PLS
Dim EntryCount As Integer = Me.GetPLSNumberOfEntries()
With sb
.
AppendLine(File.
ReadAllText(Me._FilePath,
Me._Encoding
).
Replace("NumberOfEntries=" & CStr(EntryCount),
"NumberOfEntries=" & CStr(EntryCount + 1I)))
.AppendLine(String.Format("File{0}={1}", CStr(EntryCount + 1I), [Path].Replace("\", "/")))
File.
WriteAllText(Me._FilePath, .
ToString,
Me._Encoding
) .Clear()
End With
End Select
End Sub
''' <summary>
''' Adds a new track entry in the playlist, with extended track information.
''' </summary>
''' <param name="Path">Indicates the track to add.</param>
''' <param name="Title">Indicates the track title.</param>
''' <param name="Length">Indicates the track length.</param>
Public Sub Add(ByVal [Path] As String,
ByVal Title As String,
ByVal Length As TimeSpan,
Optional ByVal AllowDuplicate As Boolean = False)
If Not AllowDuplicate AndAlso Me.Exist([Path]) Then
Throw New Exception("The TrackPath already exist in the playlist.") With {.Source = [Path]}
End If
Dim sb As New StringBuilder
Select Case Me._Type
Case PlaylistType.M3U
With sb
.AppendLine()
.AppendLine(String.Format("#EXTINF:{0},{1}",
CStr(Math.Truncate(Length.TotalSeconds)),
Title))
.AppendLine([Path])
File.
AppendAllText(Me._FilePath, .
ToString,
Me._Encoding
) .Clear()
End With
Case PlaylistType.PLS
Dim EntryCount As Integer = Me.GetPLSNumberOfEntries()
With sb
.
AppendLine(File.
ReadAllText(Me._FilePath,
Me._Encoding
).
Replace("NumberOfEntries=" & CStr(EntryCount),
"NumberOfEntries=" & CStr(EntryCount + 1I)))
.AppendLine(String.Format("File{0}={1}", CStr(EntryCount + 1I), [Path].Replace("\", "/")))
.AppendLine(String.Format("Title{0}={1}", CStr(EntryCount + 1I), Title))
.AppendLine(String.Format("Length{0}={1}", CStr(EntryCount + 1I), CStr(Math.Truncate(Length.TotalSeconds))))
File.
WriteAllText(Me._FilePath, .
ToString,
Me._Encoding
) .Clear()
End With
End Select
End Sub
''' <summary>
''' Adds a new track entry in the playlist, with extended track information.
''' </summary>
''' <param name="TrackInfo">A <see cref="TrackInfo"/> instance containing the extended track information.</param>
Public Sub Add(ByVal TrackInfo As TrackInfo,
Optional ByVal AllowDuplicate As Boolean = False)
Me.Add(TrackInfo.Path, TrackInfo.Title, TrackInfo.Length, AllowDuplicate)
End Sub
''' <summary>
''' Removes the specified track entry from the playlist.
''' </summary>
''' <param name="Path">Indicates the track path to remove it's entry.</param>
''' <exception cref="System.Exception">The TrackPath was not found in the playlist.</exception>
Public Sub Remove(ByVal [Path] As String)
If Not Me.Exist([Path]) Then
Throw New Exception("The TrackPath was not found in the playlist.") With {.Source = [Path]}
End If
Dim PlaylistContent
As List
(Of String) = File.
ReadAllLines(Me._FilePath,
Me._Encoding
).
ToList
Select Case Me._Type
Case PlaylistType.M3U
Dim EntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.Equals([Path], StringComparison.OrdinalIgnoreCase)
End Function)
PlaylistContent.RemoveAt(EntryIndex)
If PlaylistContent(EntryIndex - 1).StartsWith("#EXTINF", StringComparison.OrdinalIgnoreCase) Then
PlaylistContent.RemoveAt(EntryIndex - 1)
End If
File.
WriteAllLines(Me._FilePath, PlaylistContent,
Me._Encoding
)
Case PlaylistType.PLS
Dim EntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.ToLower Like "file#*" & [Path].Replace("\", "/").ToLower
End Function)
Dim TrackIndexDelimStartIndex As Integer =
PlaylistContent(EntryIndex).IndexOf("e", StringComparison.OrdinalIgnoreCase) + 1I
Dim TrackIndexDelimEndIndex As Integer =
PlaylistContent(EntryIndex).IndexOf("=", StringComparison.OrdinalIgnoreCase)
Dim TrackIndex As Integer =
PlaylistContent(EntryIndex).Substring(TrackIndexDelimStartIndex,
TrackIndexDelimEndIndex - TrackIndexDelimStartIndex)
PlaylistContent.RemoveAt(EntryIndex)
Dim TitleEntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.ToLower Like String.Format("title{0}=*", CStr(TrackIndex))
End Function)
If TitleEntryIndex <> -1I Then
PlaylistContent.RemoveAt(TitleEntryIndex)
End If
Dim LengthEntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.ToLower Like String.Format("length{0}=*", CStr(TrackIndex))
End Function)
If LengthEntryIndex <> -1I Then
PlaylistContent.RemoveAt(LengthEntryIndex)
End If
Dim NumberOfEntriesEntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.ToLower Like "numberofentries=#*"
End Function)
PlaylistContent(NumberOfEntriesEntryIndex) =
String.Format("NumberOfEntries={0}", CStr(Me.GetPLSNumberOfEntries() - 1I))
File.
WriteAllLines(Me._FilePath, PlaylistContent,
Me._Encoding
)
Me.FixPLSTrackIndex()
End Select
End Sub
''' <summary>
''' Removes the specified track entry from the playlist.
''' </summary>
''' <param name="TrackIndex">Indicates the track index to remove it's entry.</param>
''' <exception cref="System.IndexOutOfRangeException">TrackIndex is out of range</exception>
Public Sub Remove(ByVal TrackIndex As Integer)
Dim Track = Me.GetTrack(TrackIndex)
If Track IsNot Nothing Then
Me.Remove(Track.Path)
Else
Throw New IndexOutOfRangeException("TrackIndex is out of range") With {.Source = TrackIndex}
End If
End Sub
''' <summary>
''' Sets the extended track info of the specified track.
''' </summary>
''' <param name="Path">Indicates the track path to set its extended track info.</param>
''' <param name="TrackInfo">A <see cref="TrackInfo" /> instance containing the extended info to set.</param>
''' <exception cref="System.Exception">The TrackPath was not found in the playlist.</exception>
Public Sub [Set](ByVal [Path] As String,
ByVal TrackInfo As TrackInfo)
If Not Me.Exist([Path]) Then
Throw New Exception("The TrackPath was not found in the playlist.") With {.Source = [Path]}
End If
Dim Track As TrackInfo = Me.GetTrack([Path])
With Track
.Path = TrackInfo.Path
.Title = TrackInfo.Title
.Length = TrackInfo.Length
End With
Dim PlaylistContent
As List
(Of String) = File.
ReadAllLines(Me._FilePath,
Me._Encoding
).
ToList
Select Case Me._Type
Case PlaylistType.M3U
Dim EntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.Equals([Path], StringComparison.OrdinalIgnoreCase)
End Function)
PlaylistContent(EntryIndex) = String.Format("#EXTINF:{0},{1}",
CStr(Math.Truncate(Track.Length.TotalSeconds)),
Track.Title) & Environment.NewLine & Track.Path
If PlaylistContent(EntryIndex - 1I).StartsWith("#EXTINF", StringComparison.OrdinalIgnoreCase) Then
PlaylistContent.RemoveAt(EntryIndex - 1I)
End If
File.
WriteAllLines(Me._FilePath, PlaylistContent,
Me._Encoding
)
Case PlaylistType.PLS
Track.Path = Track.Path.Replace("\", "/")
Dim EntryIndex As Integer =
PlaylistContent.FindIndex(Function(Item As String)
Return Item.ToLower Like "file#*" & [Path].Replace("\", "/").ToLower
End Function)
PlaylistContent(EntryIndex) = String.Format("File{0}={1}", CStr(Track.Index), Track.Path) & Environment.NewLine &
String.Format("Title{0}={1}", CStr(Track.Index), Track.Title) & Environment.NewLine &
String.Format("Length{0}={1}", CStr(Track.Index), CStr(Math.Truncate(Track.Length.TotalSeconds)))
If PlaylistContent.Count > (EntryIndex + 1) Then
If PlaylistContent(EntryIndex + 2I).StartsWith("Title", StringComparison.OrdinalIgnoreCase) _
OrElse PlaylistContent(EntryIndex + 2I).StartsWith("Length", StringComparison.OrdinalIgnoreCase) Then
PlaylistContent.RemoveAt(EntryIndex + 2I)
End If
End If
If PlaylistContent.Count > EntryIndex Then
If PlaylistContent(EntryIndex + 1I).StartsWith("Title", StringComparison.OrdinalIgnoreCase) _
OrElse PlaylistContent(EntryIndex + 1I).StartsWith("Length", StringComparison.OrdinalIgnoreCase) Then
PlaylistContent.RemoveAt(EntryIndex + 1I)
End If
End If
File.
WriteAllLines(Me._FilePath, PlaylistContent,
Me._Encoding
)
End Select
End Sub
''' <summary>
''' Sets the extended track info of the specified track.
''' </summary>
''' <param name="TrackIndex">Indicates the track index to set its extended track info.</param>
''' <param name="TrackInfo">A <see cref="TrackInfo" /> instance containing the extended info to set.</param>
''' <exception cref="System.IndexOutOfRangeException">TrackIndex is out of range</exception>
Public Sub [Set](ByVal TrackIndex As Integer,
ByVal TrackInfo As TrackInfo)
If Not Me.Exist(TrackIndex) Then
Throw New IndexOutOfRangeException("TrackIndex is out of range") With {.Source = TrackIndex}
End If
Me.[Set](Me.GetTrack(TrackIndex).Path, TrackInfo)
End Sub
''' <summary>
''' Gets the extended track information (if any) of the specified track in the playlist.
''' </summary>
''' <param name="Path">Indicates the track path.</param>
''' <returns>
''' If the track contains extended iformation,
''' the return value is a <see cref="TrackInfo"/> instance containing the track info.
''' Otherwise, the return value is an emptiness <see cref="TrackInfo"/> instance.
''' </returns>
Public Function GetTrack(ByVal Path As String) As TrackInfo
Dim PlaylistContent
As List
(Of String) = File.
ReadAllLines(Me._FilePath,
Me._Encoding
).
ToList Dim TInfo As New TrackInfo
Select Case Me._Type
Case PlaylistType.M3U
Dim EntryIndex As Integer = PlaylistContent.FindIndex(Function(Item As String)
Return Item.Equals([Path], StringComparison.OrdinalIgnoreCase)
End Function) - 1I
If PlaylistContent(EntryIndex).StartsWith("#EXTINF", StringComparison.OrdinalIgnoreCase) Then
Dim TitleDelimIndex As Integer = PlaylistContent(EntryIndex).IndexOf(","c) + 1I
Dim LengthDelimIndex As Integer = PlaylistContent(EntryIndex).IndexOf(":"c) + 1I
With TInfo
'.Index = EntryIndex
.Path = [Path]
.Title = PlaylistContent(EntryIndex).Substring(TitleDelimIndex)
.Length = TimeSpan.FromSeconds(PlaylistContent(EntryIndex).Substring(LengthDelimIndex,
(TitleDelimIndex - LengthDelimIndex)))
End With
End If
Case PlaylistType.PLS
[Path] = [Path].Replace("\", "/")
Dim Entry As String = (From Item As String In PlaylistContent
Where Item.ToLower Like String.Format("file#*={0}", [Path].ToLower)).FirstOrDefault
If Not String.IsNullOrEmpty(Entry) Then
Dim IndexDelimStartIndex As Integer =
Entry.IndexOf("e", StringComparison.OrdinalIgnoreCase) + 1I
Dim IndexDelimEndIndex As Integer =
Entry.IndexOf("=", StringComparison.OrdinalIgnoreCase)
Dim EntryIndex As Integer = Entry.Substring(IndexDelimStartIndex,
IndexDelimEndIndex - IndexDelimStartIndex)
Dim TitleEntry As String = (From Item As String In PlaylistContent
Where Item.StartsWith(String.Format("Title{0}=", CStr(EntryIndex)), StringComparison.OrdinalIgnoreCase)).
FirstOrDefault
Dim LengthEntry As String = (From Item As String In PlaylistContent
Where Item.StartsWith(String.Format("Length{0}=", CStr(EntryIndex)), StringComparison.OrdinalIgnoreCase)).
FirstOrDefault
With TInfo
.Index = EntryIndex
.Path = [Path]
.Title = If(Not String.IsNullOrEmpty(TitleEntry),
TitleEntry.Substring(TitleEntry.IndexOf("=") + 1I),
Nothing)
.Length = If(Not String.IsNullOrEmpty(TitleEntry),
TimeSpan.FromSeconds(LengthEntry.Split("=").LastOrDefault),
Nothing)
End With
End If
End Select
Return TInfo
End Function
''' <summary>
''' Gets the track path and its extended track information (if any) of the specified track index in the playlist.
''' </summary>
''' <param name="TrackIndex">Indicates the track index.</param>
''' <returns>
''' If the track index exist,
''' the return value is a <see cref="TrackInfo"/> instance containing the track path and its extended info (if any).
''' Otherwise, the return value is <c>Nothing</c>.
''' </returns>
Public Function GetTrack(ByVal TrackIndex As Integer) As TrackInfo
Dim PlaylistContent
As List
(Of String) = File.
ReadAllLines(Me._FilePath,
Me._Encoding
).
ToList
Select Case Me._Type
Case PlaylistType.M3U
Dim TrackCount As Integer = 0I
For Index As Integer = 0I To (PlaylistContent.Count - 1I)
If Not String.IsNullOrEmpty(PlaylistContent(Index)) _
AndAlso Not PlaylistContent(Index).StartsWith("#EXT", StringComparison.OrdinalIgnoreCase) Then
TrackCount += 1I
If TrackCount = TrackIndex Then
Dim TInfo As TrackInfo = Me.GetTrack(PlaylistContent(Index))
With TInfo
.Index = TrackIndex
.Path = PlaylistContent(Index)
End With
Return TInfo
End If
End If
Next Index
Case PlaylistType.PLS
For Index As Integer = 0I To (PlaylistContent.Count - 1I)
If PlaylistContent(Index).StartsWith(String.Format("File{0}=", CStr(TrackIndex)),
StringComparison.OrdinalIgnoreCase) Then
Return Me.GetTrack(PlaylistContent(Index).Substring(PlaylistContent(Index).IndexOf("="c) + 1I))
End If
Next Index
End Select
Return Nothing
End Function
''' <summary>
''' Gets all the tracks and its extended track information (if any) in the playlist.
''' </summary>
''' <returns>
''' A <see cref="List(Of TrackInfo)"/> object containing the track entries and its extended info (if any).
''' </returns>
Public Function GetTracks() As List(Of TrackInfo)
Dim PlaylistContent
As List
(Of String) = File.
ReadAllLines(Me._FilePath,
Me._Encoding
).
ToList Dim TInfo As New List(Of TrackInfo)
Dim TrackCount As Integer = 0I
Select Case Me._Type
Case PlaylistType.M3U
For Index As Integer = 0I To (PlaylistContent.Count - 1I)
If Not String.IsNullOrEmpty(PlaylistContent(Index)) _
AndAlso Not PlaylistContent(Index).StartsWith("#EXT", StringComparison.OrdinalIgnoreCase) Then
TrackCount += 1
TInfo.Add(Me.GetTrack(TrackCount))
End If
Next
Case PlaylistType.PLS
For Index As Integer = 0I To (PlaylistContent.Count - 1I)
If PlaylistContent(Index).StartsWith("File", StringComparison.OrdinalIgnoreCase) Then
TrackCount += 1I
TInfo.Add(Me.GetTrack(TrackCount))
End If
Next Index
End Select
Return TInfo
End Function
''' <summary>
''' Determines whether the specified track exists in the playlist.
''' </summary>
''' <param name="Path">Indicates the track path.</param>
''' <returns>
''' <c>true</c> if the track already exists in the playlist, <c>false</c> otherwise.
''' </returns>
Public Function Exist(ByVal [Path] As String) As Boolean
Dim ReturnValue As Boolean = False
Select Case Me._Type
Case PlaylistType.M3U
ReturnValue
= (From Item
As String In
File.
ReadAllLines(Me._FilePath,
Me._Encoding
) Where Item.StartsWith([Path], StringComparison.OrdinalIgnoreCase)).
Any()
Case PlaylistType.PLS
ReturnValue
= (From Item
As String In
File.
ReadAllLines(Me._FilePath,
Me._Encoding
) Where Item.ToLower Like "file#*" & [Path].Replace("\", "/").ToLower).
Any()
End Select
Return ReturnValue
End Function
''' <summary>
''' Determines whether the specified track exists in the playlist.
''' </summary>
''' <param name="TrackIndex">Indicates the track index.</param>
''' <returns><c>true</c> if the track already exists in the playlist, <c>false</c> otherwise.</returns>
''' <exception cref="System.IndexOutOfRangeException">TrackIndex should be greater than 0.</exception>
Public Function Exist(ByVal TrackIndex As Integer) As Boolean
If TrackIndex <= 0 Then
Throw New IndexOutOfRangeException("TrackIndex should be greater than 0.") With {.Source = TrackIndex}
End If
Return (Me.Count >= TrackIndex)
End Function
''' <summary>
''' Counts the amount of track entries in the playlist.
''' </summary>
''' <returns>
''' The amount of track entries in the playlist.
''' </returns>
Public Function Count() As Integer
Return Me.GetTracks.Count
End Function
#End Region
End Class
#End Region