iTunes DB Check
Hin und wieder neigt iTunes bekanntlich ja dazu durch “geschicktes” Umorganisieren Referenzen zu den Audio-Dateien zu verlieren. Bei großen Mediatheken ist es dann meist ziemlich aufwändig die paar wenigen fehlerhaften Titel zu finden (wow, sie sind mit einem Ausrufezeichen gekennzeichnet! *scroll*). Für diesen Fall kann man allerdings auch wieder auf Objective-C oder Apple Script zurückgreifen, mit ersterem befasst sich das heutige Beispiel.
- (void) checkLibrary
{
NSLog(@"Checking iTunes Library ...");
id mediathek = [[[[self->iTunesApp sources] objectWithName:@"Mediathek"]
libraryPlaylists] objectAtIndex:0];
id tracks = [mediathek fileTracks];
long long numberOfTracks = [tracks count];
NSLog(@"Number of tracks: %lld", numberOfTracks);
id fileManager = [[NSFileManager alloc] init];
long i = 0;
long invalid = 0;
for (iTunesFileTrack* track in tracks)
{
i++;
if (i % 1000 == 0)
{
NSLog(@"Status: %ld of %lld", i, numberOfTracks);
}
id location = [track location];
BOOL exists = [fileManager fileExistsAtPath:[location relativePath]];
if (!exists)
{
invalid++;
NSLog(@"Invalid Track: %@, %@", [track artist], [track name]);
}
}
NSLog(@"Finished: %ld of %lld checked, %ld tracks with invalid location",
i, numberOfTracks, invalid);
}
Zunächst wird eine Referenz zur Mediathek angelegt. In Zeile 4 wird auf eine (initialisierte und mit einem gestarteten iTunes verknüpfte) iTunesApplication Instanz zugegriffen. sources ist dabei eine Liste aller Quellen, z.B. eben die Mediathek oder auch eine CD, sofern eingelegt. Aus der als SBElementArray zurückgegebenen Liste wird die Mediathek “gefiltert” und deren libraryPlaylist geladen. Die Library Playlist ist eine spezielle iTunes Liste, die alle in iTunes verfügbaren Inhalte enthält.
Über die Property fileTracks (Zeile 7) erhält man eine Referenz auf ein weiteres SBElementArray das alle Tracks enthält. Im Gegensatz zur “üblichen” Tracks Property, werden die Einträge dabei nicht als iTunesTrack sondern als iTunesFileTrack zurückgegeben.
@interface iTunesFileTrack : iTunesTrack @property (copy) NSURL *location; // the location of the file represented by this track - (void) refresh; // update file track information from the current information in the track’s file @end
iTunesFileTrack ergänzt iTunesTrack um die location-Property, die eine Referenz zur zugehörigen Datei darstellt. In einer Schleife können nun diese Referenzen mit der NSFileManager Funktion fileExistsAtPath überprüft werden. Einträge, deren location ungültig ist können natürlich nicht wiedergegeben werden. Da die iTunes-Datenbank jedoch sämtliche Titel und Interpreten speichert lässt sich in der Regel einfach die entsprechende Datei dazu ermitteln und neu verknüpfen, was – wenn man endlich weiß welche Titel es sind – meist nur noch Minuten-Sache ist.
Objective-C und iTunes
Zur Vorbereitung auf ein spannendes Projekt, an dem ich in nächster Zeit beteiligt bin (mehr dazu in Kürze an dieser Stelle), habe ich gestern angefangen mich mal wieder mit Xcode, Objective-C, Cocoa und ein paar anderen Entwicklungstechnologien für Apples Produkte zu befassen. Auf dem langen Weg zum Produkt möchte ich hier ein paar “Brotkrumen” hinterlassen, euch Einblick in die Entwicklung geben und Apple-Technologien vorstellen, die das Programmieren für Mac so einzigartig machen. Keine Sorge, da ich auch “Einsteiger” bin, werden die Beispiele nicht all zu komplex und schwierig zu verstehen sein.
Als ersten Teil der Serie möchte ich kurz eine einfache Möglichkeit zur “Fernsteuerung” von Anwendungen vorstellen, dem Scripten über Apples Scripting Bridge. Über die Scripting Bridge lässt sich auf die Event Messaging Architektur von Mac OS X zugreifen, die primär dem Nachrichtenaustausch zwischen Anwendungen dient. Die meisten Apple-Programme, aber auch viele andere Programme bieten ein bestimmtes Set von Nachrichten und Datentypen an, die zum Datenaustausch und zur Steuerung genutzt werden können.
Die am leichtesten zu lernende (Skript-/Programmier-) Sprache zur Nutzung der Event Messaging Architecture ist wohl AppleScript. Sie ist an der englischen (“menschlichen”) Sprache orientiert und somit zumindest intuitiv verständlich:
tell application "iTunes" to get the name of the current track
Alles klar, oder? Für eigene Programme die den Funktionsumfang einfacher Skripte übersteigen bietet Apple mit der Scripting Bridge eine Technologie, die den ganzen Funktionsumfang des Event Messaging schnell und einfach zugänglich macht. Zur Zeit steht die Scripting Bridge für Ruby, Python und Objective-C zur Verfügung. Die nachfolgenden Beispiele sind in Objective-C implementiert, dürften aber ohne weiteres auch portiert in den anderen Sprachen nutzbar sein.
Die Scripting Bridge nutzt spezielle Proxy-Module um Apple Script nachrichten an Anwendungen zu senden. Diese Proxy-Module sind im Scripting Bridge Framework enthalten und für den Anwender transparent, lediglich das zu verwendende Interface muss spezifiziert werden. Glücklicherweise lässt sich dieses für Apple Script kompatible Anwendungen mit Hilfe der beiden Tools sdef (dem scripting definition extractor) und sdp (scripting definition processor) automatisch erstellen. Für iTunes und Objective-C sieht der Aufruf wie folgt aus:
sdef /Applications/iTunes.app | sdp -fh --basename iTunes
Der Parameter -fh spezifiziert das Format (-f), in diesem Fall “h” für Objective-C Header. Der basename Parameter gibt den Namen des zu erstellenden Interface und den Prefix für alle darin enthaltene Typen an. Der Aufruf erzeugt dem entsprechend eine iTunes.h deren Inhalt den kompletten Scripting-Umfang von iTunes umfasst.
@interface iTunesApplication : SBApplication - (SBElementArray *) browserWindows; - (SBElementArray *) encoders; - (SBElementArray *) EQPresets; - (SBElementArray *) EQWindows; - (SBElementArray *) playlistWindows; - (SBElementArray *) sources; - (SBElementArray *) visuals; - (SBElementArray *) windows; @property (copy) iTunesEncoder *currentEncoder; // the currently selected encoder (MP3, AIFF, WAV, etc.) @property (copy) iTunesEQPreset *currentEQPreset; // the currently selected equalizer preset @property (copy, readonly) iTunesPlaylist *currentPlaylist; // the playlist containing the currently targeted track @property (copy, readonly) NSString *currentStreamTitle; // the name of the current song in the playing stream (provided by streaming server) ...
Obiges Beispiel zeigt einen Abschnitt des iTunesApplication interface. Das Interface leitet sich in diesem Fall vom Typ SBApplication ab. Üblicherweise enthält eine Scripting Bridge Header-Datei nur ein einziges Interface vom Typ SBApplication, das zugleich den “Einstiegspunkt” darstellt. Nur über diesen Typ ist der Zugriff auf die Anwendung und somit deren Daten möglich. Für dieses Interface kann nun ein entsprechendes Proxy-Objekt erzeugt und einer Variable (iTunesApp) zugeordnet werden:
id iTunesApp = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
Erläuterung: Der Aufruf ist ein typischer Konstruktor-Aufruf in Objective-C. Es wird der spezielle Konstruktor aufgerufen der einen benannten Parameter applicationWithBundleIdentifier vom Typ NSString hat. Für diesen wird der Wert com.apple.iTunes übergeben. Das @ unterscheidet hierbei lediglich zwischen einem C(++)-String (ohne @) und einer NSString-Instanz (mit @). Das resultierende Objekt des Aufrufs ist (bei Erfolg) ein Proxy-Element für das Interface iTunesApplication, das hier einer dynamisch typisierten Variable zugeordnet wird. Der String com.apple.iTunes entspricht dem Application-Identifier, der zum Beispiel in der Info.plist im Application-Bundle zu finden ist (für iTunes z.B. /Applications/iTunes.app/Contents/Info.plist). Der entsprechende plist-Key lautet CFBundleIdentifier.
Über dieses Proxy-Objekt lassen sich nun Nachrichten an iTunes senden. Da Apple Script auf der System- und nicht nur auf Programmebene agiert, lässt sich auch prüfen ob eine Anwendung geöffnet ist bzw. lässt sie sich auch starten, falls nicht:
if (![iTunesApp isRunning])
{
[iTunesApp run];
}
Anmerkung: Funktionsaufrufe in Objective-C werden als Nachrichten betrachtet, die an Objekte (Instanzen) gesendet werden. In diesem Beispiel wird an die Instanz iTunesApp zunächst die Nachricht isRunning gesendet, die einen Rückgabewert vom Typ BOOL hat. Anschließend wird bei negativem Ergebnis die Nachricht run an die iTunesApp Instanz gesendet. Da es sich hierbei nicht um eine Referenz für iTunes selbst sondern um ein Scripting Bridge Proxy-Objekt handelt ist dieser Aufruf gültig, auch wenn iTunes geschlossen ist. Im Gegenteil: erst durch diesen Aufruf wird iTunes gestartet. Wurde iTunes bereits zuvor gestartet greift die Scripting Bridge natürlich auf die laufende Instanz zu.
Mit dem Proxy-Objekt lässt sich die iTunes-Instanz nun fernsteuern. So kann zum Beispiel einfach überprüft werden ob aktuell ein Titel wiedergegeben wird und falls nicht die Wiedergabe gestartet werden (das Beispiel entspricht dem Klicken des Play-Pause-Buttons bei ausgewählter Gesamtplaylist (Mediathek -> Musik):
BOOL isPlaying = ([iTunesApp playerState] == iTunesEPlSPlaying);
if (!isPlaying)
{
[iTunesApp playpause];
}
Alle weiteren möglichen Nachrichten und Datentypen sind in der iTunes.h zu finden. Viel Spaß beim ausprobieren!
Weiterführende Informationen:
- In Kürze hier
- Scripting Bridge Programming Guide
Quote’a'day
Wandern ante portas – Reisbach
Mit den Worten
Kurzweilige Premiumtour an idyllischen Wald- und Wiesensäumen entlang mit der wild-romantischen Schlucht des Mühlenbaches als Top-Highlight.
beschreibt die Gemeinde Saarwellingen den neu eröffneten Premium-Wanderweg “Mühlenbach-Schluchten-Tour”, die an der Schutzhütte des Saarwald-Vereins in Saarwellingen startet und endet. Der Weg führt als Rundweg von dort aus zum Nordschacht, durch die Mühlenbach-Schlucht und schließlich entlang Reisbach zurück in Richtung Saarwellingen.
Neben dem Rundkurs, der auf knapp 11,4 km Länge kommt führen einige weitere gut begehbare Wege durch die Wälder zwischen Reisbach und der Lebacher Str. (L142) mit denen sich der Kurs zum Einstieg oder als Wanderung “zwischendurch” abkürzen lässt – mit oder ohne Schlucht. Eine dieser Wege-Optionen bin ich heute zur Eröffnung meiner persönlichen Wandersaison 2011 abgegangen.
Gestartet in Reisbach folgt die Strecke der Wegführung des Premium-Wanderwegs in Richtung Saarwellingen bis zum ersten grünen Streckenabschnitt am Rothwäldchen. Von dort aus geht es über einen kurzen asphaltierten Abschnitt bis zur Kreuzung am Oberscheidchen. Mit knapp 20 Metern Steigung auf 500m Strecke geht es von dort zurück zum Premiumweg der entlang der Obstplantagen Latz führt – momentan einer der schönsten Abschnitte der Strecke auf der man unter blühenden Kirschbäumen wandern kann. Über einen zweiten kurzen Apshalt-Abschnitt geht es entlang der Heßbach zurück in den Wald und schließlich wieder zum Ausgangspunkt.
Der Weg ist so gekürzt rund 6,4 km lang und gut in einer Stunde wanderbar. Da die Strecke über unterschiedlichste Untergründe führt (von Asphalt bis Trampelpfade) ist gutes Schuhwerk Grundvorraussetzung. Bei sonnigem Wetter sollte man auf ausreichend Sonnenschutz achten, da der Weg sehr offen ist und nur wenig durch dichten Wald führt. Wer etwas mehr Zeit hat und dennoch nicht die ganze Wanderstrecke gehen möchte kann als Ergänzung zu dieser Variante noch die Schluchtentour einbauen, die ca. 2,9 zusätzliche Kilometer hat (einfach am Ende der zweiten grünen Stecke dem Premiumweg folgen, man kommt wieder am Startpunkt raus). Zur Schlucht bald mehr an dieser Stelle.
Zitat-Quelle und mehr Informationen zur Mühlenbach-Schluchtentour als Flyer.
One More Time A1 – Mono & Nikitaman
Eher durch Zufall in der UnserDing Kostprobe am Donnerstag gehört habe ich mir – etwas entgegen meinem sonst üblichen Musikgeschmack – gestern das neue Album “Unter Freunden” von Mono und Nikitaman zugelegt.
Bis heute mir unbekannt, produzieren Monika Jaksch (“Mono”) und Nick Tilstra (“Nikitaman”) bereits seit 2002 Musik – “Unter Freunden” ist das 4. Studioalbum des deutsch-österreichischen Paars.
Anzusiedeln ist ihre Musik im Bereich Dancehall, einer Mischung aus Reggae und Hip-Hop, oft – so auch bei Mono und Nikitaman – mit Einflüssen aus der Electronic-Szene. “Dancehall” bezieht sich dabei allerdings nicht auf die Musikrichtung Dance im speziellen sondern entstammt vielmehr der ursprünglichen Herkunft der Musik, den jamaikanischen Dancehalls – was wiederum Reggae näherlegt.
Das Duett hat dabei sowohl musikalisch als auch inhaltlich eine gute Mischung getroffen. Das Dancehall-Typische “Toasten” (proklamieren des Songs/Soundsystems im Sprechgesang) wird in den wenigen Zeilen eher überspitzt, dafür aber um so besser platziert. Sexistische, gewaltverherrlichendes oder homophobe Lyrics findet man bei Mono & Nikitaman nicht – was die klare Abgrenzung des deutschen Dancehall-Stils gegenüber dem jamaikanischen Ursprung zeigt. Das Duo legt wert auf solide Texte, die von Gesellschaftskritik über Selbstironie bis fast ins Belanglose reichen.
Zum Reinhören eignen sich meiner Meinung nach am besten “Superstar”, “Kontrast” und “Rückkehr der Clows”, die es alle drei in meine persönlichen iTunes Charts geschafft haben. Kontraste dreht sich um die Bergaufs und Bergabs im Leben und die Gegensätze im Leben, Superstar ist einer der Stimmungssongs des Albums und ein potentieller Radio-Hit.
Zu haben ist das Album natürlich bei iTunes, Amazon MP3 oder als Album bei Amazon oder in eurem Lieblings-Plattenladen.
One More Time A1 ist eine Serie von Alben-, Singles- und Interpreten-Kurzvorstellungen, benannt nach der legendären Wurlitzer “One More Time”, einer der bekanntesten Musikboxen ihrer Zeit.
