Entfernen von unnötigen Dingen aus Videotiteln

  • Allgemein

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von nikeee13.

    Entfernen von unnötigen Dingen aus Videotiteln

    Hi,

    mein Anliegen hat eigentlich nicht viel mit programmieren zu tun. Aber irgendwie schon.

    Es geht um die Titel von YouTube-Videos, speziell um Videos, die Musik beinhalten.

    Wer schon mal ein (in)offizielles Musikvideo auf YouTube gesehen hat, wird wahrscheinlich bemerkt haben, dass im Videotitel meist so Sachen wie (1080p), [HD], (with Lyrics), Full HD 1080p oder HQ Audio stehen. Ich arbeite momentan an einer Software, die u. A. in der Lage sein soll, den Videotitel von solchen "Verunreinigungen" zu befreien (so gut es geht natürlich), um - im Idealfall - nur Titel, Interpret und eventuell wichtige Zusätze im Titel zu haben.
    Auf keinen Fall sollte es vorkommen, dass wichtige Infos herausgefiltert werden, also lieber zu wenig als zu viel wegnehmen.

    Später sollen die gefilterten Songtitel eventuell dafür verwendet werden können, eine Abfrage an diverse Datenbanken zu stellen, um entsprechende Infos/Covers zu erhalten. Das kann aber erstmal vernachlässigt werden.

    Wie geht man sowas am Besten an? Einfaches filtern über mehrere RegEx-Patterns? Wenn ja: Würde man da überhaupt noch durch so etwas komplexes durchsteigen?

    Oder mit einem neuronalen Netz arbeiten? In welchem Format würde man solch ein Netz füttern? Ich könnte mir nur vorstellen, dass man die Bits der Ascii-Werte nimmt, sie in Floats (0.0/1.0) konvertiert und dann so an das Netz gibt. Andere ERfahrungen habe ich damit leider noch nicht machen können, bisher hab ich es imemr so (oder ähnlich) gemacht. Dann hätte man aber ein Netz, das ca 40*8 == 320 (bei 40 Zeichen) Eingangsneuronen hat. Das würde bestimmt ewig zum trainieren brauchen.
    Außerdem: Woher bekomme ich die Lerndaten? Welche Parameter (z. B. Anzahl an Neuronen) wären da angemessen?

    Gibt es sonst noch ansätze, die man gehen kann?

    nikeee
    Von meinem iPhone gesendet

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nikeee13“ ()

    Ich würde per einfachem Replace Sachen wie deine Beispiele oben entfernen. Zusätzlich könntest du versuchen, den verbleibenden String mithilfe von Datenbanken mit Interpreten und Liedern zu erkennen.

    EDIT:
    Könntest du vielleicht eine Liste mit solchen Titeln zum Testen bereitstellen?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nafets3646“ ()

    Ka ob du vor hast, die Lib auch mit Internetanbindung zu mahen. Wenn ja, würde ich den extrahierten Titel als Google und/oder YouTube Sucheingabe verwenden und die Wörter mit den meisten Matches weiterverwenden.
    To make foobar2000 a real random music player, I figured out the only way to achieve this is to use Windows Media Player.

    At some point in time, you recognize that knowing more does not necessarily make you more happy.

    nafets3646 schrieb:

    Könntest du vielleicht eine Liste mit solchen Titeln zum Testen bereitstellen?
    Hier: holz.nu/tunnel
    Das ist in etwa das, was das Ding als Input bekommt (also die Videotitel).

    nafets3646 schrieb:

    per einfachem Replace Sachen wie deine Beispiele oben entfernen
    Das Problem dabei ist, dass sich die Sachen zu stark voneinander unterscheiden. Wenn replace, dann wird das sicherlich nur mit RegEx vernünftig gehen. Da muss ich aber ebenfalls ziemlich viele Titel betrachten und schauen, was dort so geschrieben wurde.
    Ich denke, man würde mit einer Kombination von RegEx und diversen stichwortlistne schon relativ weit kommen. Ich warte aber noch auf die Meisteridee, mit der das viel zuverlässiger gehen würde.

    Chrisber schrieb:

    die Lib auch mit Internetanbindung zu mahen
    Es wird ein HTML-Basierter Mediaplayer, der YT-Videos abspielt. Dementsprechend könnte man da bestimmt eine REST-Google-API benutzen. Für die Google-APIs braucht man aber so gut wie immer einen Developer Key, welchen ich bei der Anwendung aber nicht beilegen kann, da der nicht öffentlich zugänglich sein darf. Da die Anwendung open source ist und via gh-pages gehostet wird, wird das schwer, weil ich möchte, dass man den Player verwenden kann, ohne sich das Repo zu klonen, eine Config-Datei anzupassen und nen eigenen Webserver zu starten.

    Einfach eine Musik-Datenbank abfragen geht leider auch nicht immer, da die Musik ja teilweise nicht mal von irgendeinem Publisher vertrieben wird und deshalb nicht zwingend in irgendwelchen Musik-DBs sein muss.
    Von meinem iPhone gesendet
    Ich hab mal nen kleinen Regex-Pattern-Generator geschrieben und ihn mit ein paar Sachen gefüttert. Herausgekommen ist das folgende Pattern (ich kann auch gerne den generier-Code posten):
    Spoiler anzeigen

    Quellcode

    1. (?<=(^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)) (((cover|mashup))|((144|240|360|480|720|1080) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (p)*)|((full)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* hd)|((with|w/)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (lyric|lyrics) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (video)*)|((hq)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (audio) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (hq)*)|((official|live)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (hd)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* ( ( (music)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* video ) | music|version ))|((great|good|awesome|high|low)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (video|audio)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* quality)) ([(((cover|mashup))|((144|240|360|480|720|1080) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (p)*)|((full)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* hd)|((with|w/)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (lyric|lyrics) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (video)*)|((hq)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (audio) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (hq)*)|((official|live)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (hd)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* ( ( (music)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* video ) | music|version ))|((great|good|awesome|high|low)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (video|audio)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* quality))|(^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)]*? (((cover|mashup))|((144|240|360|480|720|1080) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (p)*)|((full)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* hd)|((with|w/)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (lyric|lyrics) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (video)*)|((hq)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (audio) (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (hq)*)|((official|live)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (hd)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* ( ( (music)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* video ) | music|version ))|((great|good|awesome|high|low)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* (video|audio)* (^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_)* quality)))* (?=(^|$|\s|,|\.|/|\\|\(|\)|\{|\}|\[|\]|\||\-|_))

    Dann noch die Regexoptions IgnoreCase und IgnorePatternWhitespace dazu und das Ding braucht bei mir nen Bruchteil einer Sekunde. Verwendet hab ich das in Verbindung mit einem Reges.Replace und als replacement einen leeren String. Du kannst es gerne probieren, aber eigentlich sollte das die meisten Sachen entfernen können :)

    MfG Stefan

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „nafets3646“ ()

    Hallo nikeee13

    Also ich habe in meinem letzten Projekt genau diese Funktionalität eingebaut - funktionierte auch, soweit ich mich erinnere, einwandfrei. Wenn du willst, kann ich dir mal den Teil demigrieren und geben. ^^

    Grüsse

    Higlav

    PS: Hab's damals mit Regex gemacht.
    @nafets3646 dieses Pattern sieht fr micha us, als hättest du einfach verschiedene Stichwörter genommen und diese dann zwischen immer die gleichen Tags gepackt.
    Wäre es dann nicht eleganter, diese Wörter zu nehmen, in ein Array zu packen, einzeln durchzugehen und immer in das Standard-Pattern einzusetzen?
    Genau das habe ich auch schon von Anfang an im Kopf gehabt. Man braucht dann quasi nur ein Standard-Pattern, das nicht zu lose aber acuh nicht zu stark ist.

    @Higlav jeder macht es ja nicht zu 100% gleich, von daher wäre es interessant zu wissen, wie du das Problem angegangen bist und was du so für Tests berücksichtig hast.

    Ich muss mir auch erstmal ein tool schreiben, mit dem ich alle Videotitel aus einer Playlist bekomme, denn sonst kann man das ja nicht vernünftig testen.
    Von meinem iPhone gesendet
    Naja, ich habe für verschiedene Teilkonstrukte Patterns, zum Beispiel für 720p, 1080p, ... Dazu kommt ein Pattern, welches verschiedene Zeichen (unter anderem ()[]{}/\| ) definiert, was dann am Anfang und Ende des Patterns eingesetzt wird (daher sieht es so stark nach Wiederholungen aus). Vorher ist mir aufgefallen, dass ich einen grundlegenden Fehler in der Enugu sanken setzung des Patterns habe (man kommt locker von 2,5k Zeichen auf unter 1k, ohne jegliche Funktionalität zu verlieren). natürlich wäre es möglich, ein dutzend verschiedene Regexes als Endprodukt zu generieren, jedoch bevorzuge ich persönlich ein einzelnes, welches zur Laufzeit aus verschiedenen Parametern zusammengesetzt wird.
    Jap, verstehe. :)
    Also ich habe zuerst mal den Titel standardisiert: Das heisst, ich habe alle möglichen Wandlungen von "feat.", "available", "Preview", "Trailer", "Release", "vs", "1 Jul", etc. auf eine Standart-Notation geändert und Klammern neutralisiert("(|[|{" -> " ( " und umgekehrt).
    Dann hiess es, den standardisierten String normal zu parsen: Zuerst der Interpret, dann optional weitere Interpreten, dann das alles entscheidende " - ", welches mir sagt, dass jetzt der Titel kommt. Der kann in Klammer ja noch einen alternativen Titel haben - ebenfalls berücksichtigen. Dann kommen in Klammern optionale weitere Interpreten dazu(die werden wie die anderen gesammelt wie Fifa-Kärtchen ;) ), dann kommt noch evtl. eine Klammer, die sagt, wessen Remix es ist, oder zu was es "gemashupt" wurde, dann noch optional den zusatz, dass es ein Trailer ist, der wiederum optional noch das voraussichtliche Veröffentlichungsdatum hintenangestellt hat, was ich natürlich ebenfalls auslese.
    Blablabla und am Schluss habe ich eine Struktur, die mir alle Daten hält. :thumbup:
    Wenn's anders rum ist, kann man das gar nicht dedektieren: Risen - Blue und Blue - Risen... :/ Aber das HD-Zeugs steht immer ganz alleine in Klammern, welche dann beim neutralisieren(erster Schritt) rausgeschnitten werden - oder sie stehen nicht in Klammern; Dann werden sie trotzdem gelöscht, wenn ich mich recht entsinne. ^^
    Also, ich habe hier mal eine verkürzte Version meines Riesen-Regexes:
    Spoiler anzeigen

    Quellcode

    1. (?<=(^|$|[\s/\-])) (((144|240|360|480|720|1080) (^|$|[\s/\-])* (p)*)|((full)* (^|$|[\s/\-])* hd)|((with|w/)* (^|$|[\s/\-])* (lyric|lyrics) (^|$|[\s/\-])* (video)*)|((hq)* (^|$|[\s/\-])* (audio) (^|$|[\s/\-])* (hq)*)|((official|live)* (^|$|[\s/\-])* (hd)* (^|$|[\s/\-])* ( ( (music)* (^|$|[\s/\-])* video ) | music|version ))|((ultra)* (^|$|[\s/\-])* (great|good|awesome|high|low)* (^|$|[\s/\-])* (video|audio)* (^|$|[\s/\-])* quality)|((available|out) (^|$|[\s/\-])* (soon|now)*)) (?=(^|$|[\s/\-]))

    Hoffentlich erkennt man jetzt besser die einzelnen Pattern, aus welchen das Gesamtpattern zusammengesetzt ist.

    Für besseres Testen habe ich mal versucht, einen kleinen Code zu schreiben, welcher den Inhalt einer Playlist herunterlädt:

    C#-Quellcode

    1. public IEnumerable<string> GetVideoTitles(string playlistId)
    2. {
    3. string gdata = new WebClient().DownloadString(string.Format(@"https://gdata.youtube.com/feeds/api/playlists/{0}?v=2", playlistId)); //Von der GData Api den Playlist-Feed abholen
    4. foreach(Match m in Regex.Matches(gdata, "<media:title.*?>(?<title>.*?)</media:title>").OfType<Match>().Skip(1)) //Der erste media:title-Tag beinhaltet den Titel der Playlist -> verwerfen
    5. yield return m.Groups["title"].Value; //Alle Titel yielden
    6. yield break;
    7. }

    Aus einem mir nicht bekannten Grund gibt dieser Code aber nur die ersten ~25 Videos in einer Playlist. Ich wäre demjenigen sehr dankbar, der diesen Code verbessern könnte :)
    @nafets3646 das ist wohl mit Absicht so. Man kann bis zu 50 Stück afu einmal abfragen:
    stackoverflow.com/a/10365437/785210
    Irgendwo hab ich auch mal gelesen, dass man noch ein offset definieren kann, find's aber nicht mehr.

    Wenn ich dann am Ende mit RegEx arbeiten würde, würde ich das Matching auf dem Client machen, was bedeuten soll, dass das Pattern auch unter JS funktionieren muss. RegEx ist zwar weitgehend standardisiert, aber viele packen da noch ihren eigenen Kram rein.

    Das Pattern arbeitet für mein Anliegen aber noch zu unzuverlässig. Ich glaube ich belasse das erstmal dabei, dass ich nichts mache.
    Von meinem iPhone gesendet