XBMC 12.3 Frodo

…ein Ausflug hinter die Kulissen eines XBMC-Scrapers.

XBMC ist ein hervorragendes Werkzeug um Filme zuschauen, aber auch um diese zu verwalten. Wer mehr haben will als einfaches Abspielen, der kommt nicht drum herum sich etwas mit dem Datenbanken-Konzept von XBMC zu befassen und hat sicherlich festgestellt, dass das System nicht immer alles auf Anhieb erkennen und zuordnen kann.

Zunächste einmal sei gesagt, dass XBMC nicht wissen kann was sich hinter einer Datei verbirgt. Diese Information muss zunächst ermittelt werden, das geht entweder indem man eine eigene Beschreibungdatei erzeugt, sie von XBMC erzeugen lässt oder die interne Datenbank des Systems direkt befüllt. Grundsätzoch existieren für XBMC zwei Arten von Beschreibungsdateien, zum einem eine gewöhnliche Textdatei, die oft Releases aus der Raubkopiererszene beiligt und eine native Beschreibungsdatei in XML. Die Zuordnung ist für XBMC durch den Dateinamen gegeben. Die Beschreibungsdatei von FilmXY.avi lautet FilmXY.nfo usw.

Die XML-Beschreibungsdatei hat eine für XBMC verständliche Struktur, so lautet der Eintrag für den Film “Die Abenteuer von Rabbi Jacob”:

title Abenteuer des Rabbi Jacob, Die/title
originaltitle Les aventures de Rabbi Jacob/originaltitle
year 1973 /year
id tt0069747 /id

Liegt diese Information vor, dann muss sie nicht mehr ermittelt werden und der Inhalt ist eindeutig identifiziert.

Bei Nicht-Nativen NFO-Dateien fehlt diese klare Struktur und die Information kann vom System nicht ermittelt werden. XBMC versucht in einem solchen Fall in der gesamten Datei nach der einzig verwertbaren Information, nach der IMDb-ID zu suchen. Diese Information bezieht sich auf die größte Filmdatenbank im Internet und ist eindeutig. Sie beginnt mit den beiden Zeichen “tt”, gefolgt von einer siebenstelligen Zahl, das macht es leicht sie bspw. mit einem Regulären Ausdruck zu finden:

(tt\d{7})

Wenn es etwas genauer gehen soll und man annimmt, die URL auf den entsprechenden Film wäre in der Datei zu finden, so lautet der Ausruck entsprechend:

http://.*?(tt\d{7})

Wobei in unserem Fall “http://www.imdb.com/title/tt0069747/” gefunden wird und der Wert in den Klammern direkt die ID zur Weiterverarbeitung liefert.

Wenn Daten aus dem Internet geladen werden sollen, dann verwendet XBMC so genannte Scraper. Das sind kleine Hilfsprogramme, die innerhalb des System gestartet werden und gegen Datenbanken prüfen. Dies kann durch eine Programmierschnittstelle (API) erfolgen, wenn die externe Datenbank dies anbietet oder etwas “schmutziger” durch Parsen einer gewöhnlichen Internertseite. Der Vorteil einer API ist, dass alle Antworten die das externe System liefert stanardisiert sind. Die vermutlich wichtigsten Webseiten die eine solche Schnittstelle für deutsche Filme bieten sind TheMovieDB/ (TMDB) und Fanart.tv. Entsprechende Scraper sind sowohl für XBMC, als auch Zusatztools verfügbar.

Ich selbst nutze TMDB in meinem XML-Aggregator “RSSit!” um ein Cover, sowie die Filmbeschreibung anzufordern. In “NFOit!” verwende ich zunächst TMDB und anschließend Fanart.tv um zusätzliche Inhalte herunterzuladen. Für beide Seiten ist ein so genannter API-Key erforderlich, damit könnte der Betreiber zu eifrige Programme identifizieren, aussperren oder verlangsamen. Deswegen sind einige Entwickler dazu übergegangen keinen eigenen API-Schlüssel mehr auszuliefern. Der Anwender müsste ihn sich dann selbst besorgen und dem Programm mitteilen. Das gilt aber nicht für die internen XBMC-Scraper und sei nur am Rande erwähnt.

 

Die Suche per API

Nehmen wir nun an wir haben eine Datei vorliegen, die “Golem.mpg” heißt. Der Name kann ermittelt und per Suchstring an TMDB übergeben werden:

https://api.themoviedb.org/3/search/movie?api_key=###&query=golem&year=&language=de

Das Ergebnis ist nicht eindeutig, da mehrere Filme mit dem Namensbestandteil “Golem” existieren:

{"page":1,"results":[{"adult":false,"backdrop_path":"/zr0MJVtm5GXu3ZkYaKHoCrS3A2r.jpg","id":107983,"original_title":"Golem","release_date":"1980-03-18","poster_path":"/2i0vYTo7ljwS1IRmX4Odxwt1U7u.jpg","popularity":0.23,"title":"Golem","vote_average":7.0,"vote_count":1},{"adult":false,"backdrop_path":"/AsirpraS3EhlOXyh4u9Z4HI5dlP.jpg","id":131573,"original_title":"Golem","release_date":"1993-01-01","poster_path":"/x4ua9H6iwuDnE2gaVkh7GuCMCpj.jpg","popularity":0.23,"title":"Golem","vote_average":0.0,"vote_count":0},{"adult":false,"backdrop_path":"/hxfA7xqiXgxOFmoedKUNWXT3Jva.jpg","id":10695,"original_title":"Der Golem","release_date":"1915-01-15","poster_path":"/g1TagpjtOqK8AGKpp6uAKTfab6F.jpg","popularity":0.46,"title":"Der Golem","vote_average":4.0,"vote_count":1},{"adult":false,"backdrop_path":null,"id":169479,"original_title":"Le golem","release_date":"1936-02-13","poster_path":"/ywpZQwCPw1KYYBrgpiYewPHT0ux.jpg","popularity":0.46,"title":"Le golem","vote_average":0.0,"vote_count":0},{"adult":false,"backdrop_path":null,"id":29607,"original_title":"Miami Golem","release_date":"1985-11-12","poster_path":"/43vizf7Q0hVd8IM5bmABJOfYmfe.jpg","popularity":0.23,"title":"Miami Golem","vote_average":0.0,"vote_count":0},{"adult":false,"backdrop_path":null,"id":217297,"original_title":"Birth of a Golem","release_date":"1990-08-27","poster_path":"/37oIzWhnDfHoHl8Nno7olpGpTNm.jpg","popularity":0.345,"title":"Birth of a Golem","vote_average":0.8,"vote_count":1},{"adult":false,"backdrop_path":"/nQf7ItYxdWAyIVfi4KwnWSHdzQp.jpg","id":2972,"original_title":"Der Golem, wie er in die Welt kam","release_date":"1920-10-28","poster_path":"/4bEe5VljUBOirzPbKbpvtMPnKnz.jpg","popularity":0.5090475,"title":"Der Golem, wie er in die Welt kam","vote_average":8.3,"vote_count":3},{"adult":false,"backdrop_path":"/wfrbwY2dxRSxOctikysHNLNk4lX.jpg","id":125510,"original_title":"Slayers Great","release_date":"1997-08-02","poster_path":"/mErnTroMPQRG7G5TL6wWtnO3OW3.jpg","popularity":0.23,"title":"Slayers Great","vote_average":4.0,"vote_count":1},{"adult":false,"backdrop_path":null,"id":36918,"original_title":"Císařův pekař – Pekařův císař","release_date":"1952-01-04","poster_path":"/bMVVipnmfg7r3MZTBkrDdFI3gGR.jpg","popularity":0.368,"title":"Císařův pekař – Pekařův císař","vote_average":8.5,"vote_count":1}],"total_pages":1,"total_results":9}

Es ist ein einschränkendes Kriterium erforderlich, bspw. eine Jahreszahl. Die Datei hätte also bspw. “Golem (1936).mpg” heißen müssen, der Suchstring sähe dann so aus:

https://api.themoviedb.org/3/search/movie?api_key=###&query=golem&year=1936&language=de

Und lieferte ein eindeutiges Ergebnis:

{"page":1,"results":[{"adult":false,"backdrop_path":null,"id":169479,"original_title":"Le golem","release_date":"1936-02-13","poster_path":"/ywpZQwCPw1KYYBrgpiYewPHT0ux.jpg","popularity":0.46,"title":"Le golem","vote_average":0.0,"vote_count":0}],"total_pages":1,"total_results":1}

Die ID 169479 bezieht sich hier auf die interne TMDB-ID, die sich von der IMDb-ID unterscheidet. Werden weitere Informationen gebraucht, so muss eine weitere Suche mit der TMDB-ID abgesetz werden:

https://api.themoviedb.org/3/movie/169479?api_key=###&language=de

Das Ergebnis lautet dann:

{"adult":false,"backdrop_path":null,"belongs_to_collection":null,"budget":0,"genres":[],"homepage":null,"id":169479,"imdb_id":"tt0027688","original_title":"Le golem","overview":null,"popularity":0.46,"poster_path":"/ywpZQwCPw1KYYBrgpiYewPHT0ux.jpg","production_companies":[],"production_countries":[{"iso_3166_1":"CZ","name":"Czech Republic"},{"iso_3166_1":"FR","name":"France"}],"release_date":"1936-02-13","revenue":0,"runtime":null,"spoken_languages":[{"iso_639_1":"fr","name":"Français"}],"status":"Released","tagline":null,"title":"Le golem","vote_average":0.0,"vote_count":0}

und liefert uns erst jetzt auch die IMDb-ID “tt0027688”. Wäre uns diese also von vornherein bekannt, so könnte die Abfrage direkt so aussehen:

https://api.themoviedb.org/3/movie/tt0027688?api_key=###&language=de

Das Ergebnis wäre identisch zur Abfrage mit der TMDB-ID:

{"adult":false,"backdrop_path":null,"belongs_to_collection":null,"budget":0,"genres":[],"homepage":null,"id":169479,"imdb_id":"tt0027688","original_title":"Le golem","overview":null,"popularity":0.46,"poster_path":"/ywpZQwCPw1KYYBrgpiYewPHT0ux.jpg","production_companies":[],"production_countries":[{"iso_3166_1":"CZ","name":"Czech Republic"},{"iso_3166_1":"FR","name":"France"}],"release_date":"1936-02-13","revenue":0,"runtime":null,"spoken_languages":[{"iso_639_1":"fr","name":"Français"}],"status":"Released","tagline":null,"title":"Le golem","vote_average":0.0,"vote_count":0}

Das zur Funktionsweise eines Scrapers. Wenn eine native NFO existiert, dann muss XBMC nichts weiter tun, als die direkt mit den gegebenen Daten zu arbeiten. Die Ermittlung geht sehr schnell, da keine Datenbank befragt werden muss. Eine eigene NFO ist auch dann wichtig, wenn die Daten in der externen Datenbank schlecht gepflegt oder falsch sind. Auch sind Fehler in der API möglich. Ich habe bei der Implementierung einen Fall gehabt bei dem ein Film fälschlicherweise als Serie einsortiert war. Durch die Query-Suche wurde also eine gültige ID geliefert, die Abfrage des Films lieferte dann einen unerwarteten Fehler. Hier hat die API meiner Meinung nach einen konzeptionellen Fehler, denn sie unterscheidet nicht nur nach ID, sondern überlässt es dem Entwickler zu ermitteln ob es sich um einen Film oder Serie handelt. Diese Information ist aber ggf. nicht vorhanden. Viel mehr sollte zusammen mit der ID auch die Information übermittelt werden, ob es sich bei dem Datensatz um einen Film handelt oder nicht. Ferner ist es möglich, dass ein Film überhaupt nicht in der Datenbank verzeichnet ist (ausländische Filme, dazu später mehr), dann müsste man entweder dort selbst einen Eintrag vornehmen oder eben eine eigene NFO erzeugen.

Um eine eigene NFO zu erzeugen gibt es mittlerweile mehrere gute Werkzeuge, die trotzdem Schwächen aufweisen. Besonders hervorzuheben ist der seit kurzem wieder gepflegte Ember Media Manager (EMM) und MediaElch. Beide Programme können mit mittelgroßen Sammlungen umgehen und bieten für unterschiedliche Webseiten Scraper an. Bei Ember lohnt sich der Aufwand für mich nicht, denn er ist nicht in der Lage sowohl Daten von TMDB, als auch parallel von Fanart.tv zu liefern. Außerdem ist er bei reiner Suche etwas schwerfällig geworden, was dazu führt, dass man die IMDb-ID selbst ermitteln und ihm mitteilen muss. Außerdem benötigt er für TMDB einen eigenen API-Key, was einige Anwender abschreckt.

Als Best Practice hat sich für mich folgendes Vorgehen etabliert: Alle Medien erhalten einen sprechenden Namen mit Jahresangaben, sowie bei schwierigen Titeln eine eigene NFO-Datei mit dem Link auf den Film bei IMDb. Jeder Titel steckt dabei in seinem eigenen Verzeichnis, das ist wichtig, da Extrafanart und andere Unterordner sich sonst mit anderen Titeln überschneiden würden. Dannach wird der Film von XBMC gescrapt, wenn alles korrekt erkannt und auch alle “Artwork“ heruntergeladen sind, wird unter „System -> Video -> Videodatenbank“ die Datenbank “separat” pro Datei exportieren. Nun hat jeder Titel eine eigene NFO, sowie ergänzende Daten, wie Poster und Hintergrundbilder erhalten. Wenn hier etwas nicht stimmt, dann kann dies manuell mit Notepad++ oder mit Ember geändert werden. Ab jetzt kann die eigene XBMC-Datenbank ohne Online-Verbindung immer wieder neu aufgebaut werden.

Sonderfall – Ausländische Filme

Eine Filmdatenbank wie TMDB kann Informationen zu einem Titel in mehreren Sprachen liefern, gute Scraper berücksichtigen dies natürlich und geben eine entsprechende Information bei der Abfrage mit. Schlechte Scraper parsen eine Webseite und liefern Daten entsprechend nur in einer Sprache aus. Das ist bei dem Scraper für Kinopoisk.ru der Fall, dieses Addon liefert Informationen nur in der russischen Sprache zurück und konvertiert dabei nicht einmal nach Unicode. Wird auf einem Unicode-XBMC eingelesen, dann kann keiner der Texte verwendet werden, hier muss also der Scraper umgeschrieben oder die Daten im Nachhinein konvertiert werden. Leider hält sich die Popularität von TMDB im russichsprachigen Raum in Grenzen, weswegen der integrierte Scraper oft keine Ergebnisse liefern würde.

Wenn ein negatives Ergebnis für die eingestellte Sprache kommt, dann macht XBMC immer einen Fallback auf Englisch. Ist also Deutsch eingestellt und ein russischer Film gescrapt, dann ist die Wahrscheinlichkeit sehr hoch, dass keine deutsche Beschreibung vorhanden  ist. XBMC versucht es dann mit Englisch und der Eintrag landet in englischer Sprache in der eigenen Sammlung. Am obigen Beispiel ist zu sehen, dass für den Film Golem von 1936 keine Beschreibung vorhanden ist, wenn die Datenbank einen Eintrag in deutscher Sprache liefern soll. Eine Abfrage in englischer Sprache liefert zumindest eine kurze Beschreibung:

{"adult":false,"backdrop_path":null,"belongs_to_collection":null,"budget":0,"genres":[],"homepage":"","id":169479,"imdb_id":"tt0027688","original_title":"Le golem","overview":"The Golem, a giant creature created out of clay by a rabbi, comes to life in a time of trouble to protect the Jews of Prague from persecution.","popularity":0.3404,"poster_path":"/ywpZQwCPw1KYYBrgpiYewPHT0ux.jpg","production_companies":[],"production_countries":[{"iso_3166_1":"CZ","name":"Czech Republic"},{"iso_3166_1":"FR","name":"France"}],"release_date":"1936-02-13","revenue":0,"runtime":96,"spoken_languages":[{"iso_639_1":"fr","name":"Français"}],"status":"Released","tagline":"","title":"The Golem","vote_average":0.0,"vote_count":0}

Deswegen habe ich in meinen eigenen Programmen (RSSit! und NFOit!) neben Englisch eine weitere Alternativsprache eingeführt. Zunächst wird nach DE gesucht, wird kein Ergebnis geliefert, dann wird RU verwendet und erst dann EN. Eine solche Möglichkeit ist mir bislang in keinem anderen Programm begegnet, deswegen kann ich nur ermuntern selbst Hand anzulegen.

About Roman

Das ist mein Profil. Es gibt viele Profile, doch dieses gehört mir. Ohne mein Profil bin ich nichts und ohne mich ist mein Profil nichts.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

 

Post Navigation