Ich habe mich schon vor längerer Zeit von @Tibiamicus: für eine kleine YTInformation-Klasse inspirieren lassen.
Referenz hierbei ist immer sein Thread.
Mir hat seine Herangehensweise nicht wirklich gefallen, sodass ich mir dachte, das besser zu machen. Imho ist mir das auch gelungen.
Ich möchte mich nicht weiter mit irgendwelchen Kleinigkeiten herumschlagen, daher "nur" der Sourcecode Austausch.
Was im voraus schon gegeben sein muss:
Jetzt die vmtl. tollste Frage: "Warum Reflection?!" - Wirst du sehen, später.
Ich nutze eine kleine
Ich habe dazu dann noch eine Wrapper-Klasse geschrieben, sodass die Informationen zu den einzelnen Teilen des Videos erreichbar sind.
Die Dokumentation ist etwas .. kurz geraten, weil ich per se keine Dokumentation nutze. Naja.
Jedenfalls kann mit diesem Modul ein Video auf alle Informationen geprüft werden.
Zudem noch ein kleines Anwendungsbeispiel:
Ich werde zu diesem Modul keinen Support geben, da ihr euch sicherlich selbst erschließen könnt, wie was funktionieren soll. Wenn nicht, hier noch ein paar Links:
Im Anhang findet ihr eine Solution (VS2013RC) mit einem C#- und einem VB-Projekt. Beides .NET 4.5.
Referenz hierbei ist immer sein Thread.
Mir hat seine Herangehensweise nicht wirklich gefallen, sodass ich mir dachte, das besser zu machen. Imho ist mir das auch gelungen.
Ich möchte mich nicht weiter mit irgendwelchen Kleinigkeiten herumschlagen, daher "nur" der Sourcecode Austausch.
Was im voraus schon gegeben sein muss:
- System.Web ist importiert
- System.Net ist importiert
- System.Reflection ist importiert
Jetzt die vmtl. tollste Frage: "Warum Reflection?!" - Wirst du sehen, später.
Ich nutze eine kleine
Structure
um mir die Arbeit mit YT Links zu vereinfachen:VB.NET-Quellcode
- ''' <summary>
- ''' Eine Struktur, die die Videoinformationen hält
- ''' </summary>
- ''' <remarks></remarks>
- Public Structure VideoInfo
- Private _url As String
- Private _type As String
- ''' <summary>
- ''' der Fallback Host
- ''' </summary>
- Public Property FallBack_Host As String
- ''' <summary>
- ''' Irgendn Tag, der irgendwie gesetzt werden muss.
- ''' </summary>
- Public Property ITag As Integer
- ''' <summary>
- ''' Qualität .. oder so
- ''' </summary>
- Public Property Quality As String
- ''' <summary>
- ''' Signatur des Videos, afaik.
- ''' </summary>
- Public Property Sig As String
- ''' <summary>
- ''' Die URL des Videos
- ''' </summary>
- Public Property Url As String
- Get
- Return _url
- End Get
- Set(value As String)
- ' die URL soll bitte keine komischen HTML-Escapes beinhalten
- _url = HttpUtility.UrlDecode(value)
- End Set
- End Property
- ''' <summary>
- ''' der Typ des Videos.
- ''' </summary>
- Public Property Type As String
- Get
- Return _type
- End Get
- Set(value As String)
- ' keine HTML-Escapes
- _type = HttpUtility.UrlDecode(value)
- End Set
- End Property
- ''' <summary>
- ''' doller FileType. (webm, flv, mp4)
- ''' </summary>
- Public ReadOnly Property FileType As String
- Get
- ' dafür muss man wissen, wie der FileType aufgebaut ist.
- ' einfach mal durchsteppen und gucken
- Return Type.Split(";"c)(0).Split("/"c)(1).Replace("x-", "")
- End Get
- End Property
- ''' <summary>
- ''' Gibt die Download-URL zurück
- ''' </summary>
- Public Overrides Function ToString() As String
- ' Download-Url aufbauen
- Return String.Format("{0}&fallback_host={1}&signature={2}", Url, FallBack_Host, Sig)
- End Function
- End Structure
Ich habe dazu dann noch eine Wrapper-Klasse geschrieben, sodass die Informationen zu den einzelnen Teilen des Videos erreichbar sind.
VB.NET-Quellcode
- ''' <summary>
- ''' Ein Modul, was Methoden zur Verarbeitung von YT-Videos bereitstellt
- ''' </summary>
- Public Module YTInformation
- ''' <summary>
- ''' Gibt generisch alle Keys des Videos zurück. (url_encoded_fmt_stream_map, Author, etc.)
- ''' </summary>
- ''' <param name="videoId">die VideoID. Und nur die. Keine URL!</param>
- Public Function Information(videoId As String) As Dictionary(Of String, String)
- Return Information(videoId).ToDictionary(Function(item) item.Key, Function(item) item.Value)
- End Function
- ''' <summary>
- ''' Gibt alle VideoInfos zu einer URL_ENCODED_FMT_STREAM_MAP.
- ''' </summary>
- ''' <param name="data">url_encoded_fmt_stream_map und nur das.</param>
- Public Iterator Function UrlMap(data As String) As IEnumerable(Of VideoInfo)
- Dim splitted As String() = data.Split(","c)
- For Each item As String In splitted
- Yield urlInfo(item)
- Next
- End Function
- Private Iterator Function _information(videoId As String) As IEnumerable(Of KeyValuePair(Of String, String))
- Dim client As New WebClient()
- Dim data As String = client.DownloadString(New Uri("http://youtube.com/get_video_info?&video_id=" & videoId))
- Dim splitted As String() = data.Split("&"c)
- For Each item As String In splitted
- Yield New KeyValuePair(Of String, String)(item.Split("="c)(0), item.Split("="c)(1))
- Next
- End Function
- Private Function urlInfo(line As String) As VideoInfo
- Dim info As New VideoInfo()
- Dim infoType As Type = info.GetType()
- Dim properties As Dictionary(Of String, PropertyInfo) = infoType.GetProperties().ToDictionary(Function(item) item.Name.ToLower(), Function(item) item)
- Dim data As String() = line.Split("&"c)
- For Each item As String In data
- Dim split As String() = item.Split("="c)
- properties(split(0).ToLower()).SetValue(info, Convert.ChangeType(split(1), properties(split(0).ToLower()).PropertyType))
- Next
- Return info
- End Function
- End Module
Die Dokumentation ist etwas .. kurz geraten, weil ich per se keine Dokumentation nutze. Naja.
Jedenfalls kann mit diesem Modul ein Video auf alle Informationen geprüft werden.
Zudem noch ein kleines Anwendungsbeispiel:
VB.NET-Quellcode
- Sub Main()
- Console.WriteLine("Video Id")
- Dim id As String = Console.ReadLine()
- Dim test As Dictionary(Of String, String) = YTInformation.Information(id)
- Dim dat As String = HttpUtility.UrlDecode(test("url_encoded_fmt_stream_map"))
- Dim t As IEnumerable(Of VideoInfo) = YTInformation.UrlMap(dat)
- Dim index As Integer = 0
- Console.WriteLine(String.Join(Environment.NewLine, t.Select(Function(item) increment(index).ToString() & ") " & item.Type & " " & item.Quality)))
- Console.WriteLine("Index")
- If Integer.TryParse(Console.ReadLine(), index) Then
- Dim info As VideoInfo = t.ElementAt(index)
- Dim client As New WebClient()
- Dim url As String = info.ToString()
- Dim decode As String = HttpUtility.UrlDecode(test("title"))
- For Each c As Char In Path.GetInvalidFileNameChars()
- decode = decode.Replace(c, "-"c)
- Next
- Dim fileType As String = info.FileType
- client.DownloadFile(url, decode & "." & fileType)
- End If
- End Sub
- Private Function increment(ByRef num As Integer) As Integer
- num += 1
- Return num
- End Function
Ich werde zu diesem Modul keinen Support geben, da ihr euch sicherlich selbst erschließen könnt, wie was funktionieren soll. Wenn nicht, hier noch ein paar Links:
System.Collections.Generic.IEnumerable(Of T)
System.Type.GetProperties()
Yield
Iterator
System.Convert.ChangeType
Im Anhang findet ihr eine Solution (VS2013RC) mit einem C#- und einem VB-Projekt. Beides .NET 4.5.