iTunes im Notification Center – mit Album Cover!

Pill

Pill

Aktives Mitglied
Thread Starter
Dabei seit
21.02.2011
Beiträge
3.279
Reaktionspunkte
463
111496d1345710351-itunes-notification-center-bildschirmfoto-2012-08


Seit Erscheinen von OS X Mountain Lion und dem Notification Center sind einige Tools (viele davon basieren auf AppleScript) erschienen, die den aktuellen Titel von iTunes anzeigen. Alle scheitern aber bisher daran, das Album Cover anzuzeigen. Das hat einen einfachen Grund: Es ist nicht vorgesehen, dass beliebige Bilder angezeigt werden, sondern es wird immer das Icon des jeweiligen Programms angezeigt. Die einzige Möglichkeit das Album Cover anzuzeigen ist es also das Icon zu ändern. Das ist in AppleScript relativ einfach zu lösen, schnell taucht jedoch ein weiteres Problem auf: Ist ein Programm einmal im Notification Center registriert, wird das Programmicon nicht mehr aktualisiert. Da es keine Möglichkeit gibt per AppleScript ein Programm aus dem Notification Center zu löschen, muss dies manuell in einer SQL-Datenbank geschehen, die sich im Ordner ~/Library/Application Support/NotificationCenter/ befindet.

Wie ihr schon seht, ist das ganze keine sehr saubere Lösung, eine andere habe ich bisher allerdings nicht gefunden. Die Meldung wird übrigens über Cocoa-AppleScript abgesetzt, vielen Dank an dieser Stelle an kermitd, der das ganze hier beschrieben hat.

Kommen wir zum Eingemachten, dem Quellcode:

Code:
[FONT=Verdana][size=2][color=#4C4D4D]-- main.scpt[/color]
[color=#4C4D4D]-- Cocoa-AppleScript Applet[/color]
[color=#4C4D4D]--[/color]
[color=#4C4D4D]-- Copyright 2011 {Your Company}. All rights reserved.[/color]

[color=#4C4D4D]-- This is the main script for a Cocoa-AppleScript Applet.[/color]
[color=#4C4D4D]-- You can put the usual script applet handlers here.[/color]

[b]set[/b] [color=#3F7F00]dnc[/color] [b]to[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSDistributedNotificationCenter[/color]'s [color=#3F7F00]defaultCenter[/color]
[b]tell[/b] [color=#3F7F00]dnc[/color] [b]to[/b] [color=#3F7F00]addObserver_selector_name_object_[/color]([b]me[/b], "updateTrackInfo", "com.apple.iTunes.playerInfo", [color=#0000FF][i]missing value[/i][/color])

[b]global[/b] [color=#3F7F00]currentTrack[/color], [color=#3F7F00]currentTrackName[/color], [color=#3F7F00]currentTrackAlbum[/color], [color=#3F7F00]currentTrackArtist[/color][color=#7F007F]
[/color]
[b]on[/b] [color=#3F7F00]updateTrackInfo[/color]()
	[b]tell[/b] [color=#0000FF][i]application[/i][/color] "iTunes"
		[b]if[/b] [color=#6C04D4]player state[/color] [b]is[/b] [b]not[/b] [color=#4A1E7F]playing[/color] [b]then[/b]
			[b]return[/b]
		[b]end[/b] [b]if[/b]
	[b]end[/b] [b]tell[/b]
	[color=#3F7F00]fetchiTunesTrackInfo[/color]()
	[color=#3F7F00]adjustIconForAlbumArtworkOfCurrentTrack[/color]()
	[color=#3F7F00]sendMessage[/color]([color=#3F7F00]currentTrackName[/color], [color=#3F7F00]currentTrackArtist[/color], [color=#3F7F00]currentTrackAlbum[/color])
[b]end[/b] [color=#3F7F00]updateTrackInfo[/color]

[b]on[/b] [color=#3F7F00]fetchiTunesTrackInfo[/color]()
	[b]try[/b]
		[b]tell[/b] [color=#0000FF][i]application[/i][/color] "iTunes"
			[b]set[/b] [color=#3F7F00]currentTrack[/color] [b]to[/b] [b]the[/b] [color=#6C04D4]current track[/color]
			[b]set[/b] [color=#3F7F00]currentTrackName[/color] [b]to[/b] [b]the[/b] [color=#6C04D4]name[/color] [b]of[/b] [b]the[/b] [color=#3F7F00]currentTrack[/color]
			[b]set[/b] [color=#3F7F00]currentTrackAlbum[/color] [b]to[/b] [b]the[/b] [color=#6C04D4]album[/color] [b]of[/b] [b]the[/b] [color=#3F7F00]currentTrack[/color]
			[b]set[/b] [color=#3F7F00]currentTrackArtist[/color] [b]to[/b] [b]the[/b] [color=#6C04D4]artist[/color] [b]of[/b] [b]the[/b] [color=#3F7F00]currentTrack[/color]
		[b]end[/b] [b]tell[/b]
	[b]end[/b] [b]try[/b]
[b]end[/b] [color=#3F7F00]fetchiTunesTrackInfo[/color]

[b]on[/b] [color=#3F7F00]adjustIconForAlbumArtworkOfCurrentTrack[/color]()
	[b]tell[/b] [color=#0000FF][i]application[/i][/color] "iTunes"
		[color=#0016B0][b]do shell script[/b][/color] "sqlite3 ~/Library/Application\\ Support/NotificationCenter/*.db \"DELETE from app_info where bundleid is 'com.apple.ScriptEditor.id.Now-Playing'\" && killAll NotificationCenter;"
		[b]set[/b] [color=#3F7F00]thePath[/color] [b]to[/b] (([color=#0016B0][b]path to[/b][/color] [color=#4A1E7F]current application[/color]) [b]as[/b] [color=#0000FF][i]text[/i][/color])
		[b]set[/b] [color=#3F7F00]thefile[/color] [b]to[/b] ([color=#3F7F00]thePath[/color] & "Contents:Resources:Icon.png" [b]as[/b] [color=#0000FF][i]alias[/i][/color])
		
		[b]try[/b]
			[b]set[/b] [color=#3F7F00]thefilehandle[/color] [b]to[/b] [color=#0016B0][b]open for access[/b][/color] [color=#3F7F00]thefile[/color] [b]with[/b] [color=#0016B0]write permission[/color]
			[color=#0016B0][b]write[/b][/color] ([b]get[/b] [color=#6C04D4]raw data[/color] [b]of[/b] [color=#0000FF][i]artwork[/i][/color] 1 [b]of[/b] [color=#6C04D4]current track[/color]) [color=#0016B0]to[/color] [color=#3F7F00]thefilehandle[/color] [color=#0016B0]starting at[/color] 0
			[color=#0016B0][b]close access[/b][/color] [color=#3F7F00]thefilehandle[/color]
			[b]set[/b] [color=#3F7F00]theCommand[/color] [b]to[/b] "sips --resampleHeightWidth 128 128 " & [color=#6C04D4]quoted form[/color] [b]of[/b] [color=#6C04D4]POSIX path[/color] [b]of[/b] [color=#3F7F00]thefile[/color] & " -o " & [color=#6C04D4]quoted form[/color] [b]of[/b] [color=#6C04D4]POSIX path[/color] [b]of[/b] [color=#3F7F00]thefile[/color] & "; sips -s format icns " & [color=#6C04D4]quoted form[/color] [b]of[/b] [color=#6C04D4]POSIX path[/color] [b]of[/b] [color=#3F7F00]thefile[/color] & " -o '" & [color=#6C04D4]POSIX path[/color] [b]of[/b] [color=#3F7F00]thePath[/color] & "Contents/Resources/Applet.icns';"
			[color=#0016B0][b]do shell script[/b][/color] [color=#3F7F00]theCommand[/color]
			
		[b]on[/b] [b]error[/b] [color=#3F7F00]err[/color]
			[color=#0016B0][b]close access[/b][/color] [color=#3F7F00]thefilehandle[/color]
			[b]set[/b] [color=#3F7F00]cmd[/color] [b]to[/b] "rm '" & [color=#6C04D4]POSIX path[/color] [b]of[/b] [color=#3F7F00]thePath[/color] & "Contents/Resources/Applet.icns'; cp '" & [color=#6C04D4]POSIX path[/color] [b]of[/b] [color=#3F7F00]thePath[/color] & "Contents/Resources/Applet2.icns' '" & [color=#6C04D4]POSIX path[/color] [b]of[/b] [color=#3F7F00]thePath[/color] & "Contents/Resources/Applet.icns'"
			[color=#0016B0][b]do shell script[/b][/color] [color=#3F7F00]cmd[/color]
			[color=#4C4D4D]--display dialog cmd[/color]
			[color=#4C4D4D]--tell current application to quit[/color]
		[b]end[/b] [b]try[/b]
	[b]end[/b] [b]tell[/b]
	[b]tell[/b] [color=#0000FF][i]application[/i][/color] "System Events"
		[b]repeat[/b] [b]until[/b] ([color=#0000FF][b]exists[/b][/color] [color=#0000FF][i]process[/i][/color] "rm") & ([color=#0000FF][b]exists[/b][/color] [color=#0000FF][i]process[/i][/color] "cp") [b]is[/b] {[color=#4A1E7F]false[/color], [color=#4A1E7F]false[/color]}
			[color=#0016B0][b]delay[/b][/color] 0.1
		[b]end[/b] [b]repeat[/b]
	[b]end[/b] [b]tell[/b]
[b]end[/b] [color=#3F7F00]adjustIconForAlbumArtworkOfCurrentTrack[/color]

[b]on[/b] [color=#3F7F00]sendMessage[/color]([color=#3F7F00]myTitle[/color], [color=#3F7F00]mySubtitle[/color], [color=#3F7F00]myContent[/color])
	[b]tell[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSUserNotification[/color] [b]to[/b] [b]set[/b] [color=#3F7F00]thisNote[/color] [b]to[/b] [color=#3F7F00]alloc[/color]()'s [color=#3F7F00]init[/color]()
	[b]set[/b] [color=#3F7F00]thisNote[/color]'s [color=#3F7F00]title[/color] [b]to[/b] [color=#3F7F00]myTitle[/color]
	[b]set[/b] [color=#3F7F00]thisNote[/color]'s [color=#3F7F00]subtitle[/color] [b]to[/b] [color=#3F7F00]mySubtitle[/color]
	[b]set[/b] [color=#3F7F00]thisNote[/color]'s [color=#3F7F00]informativeText[/color] [b]to[/b] [color=#3F7F00]myContent[/color]
	[b]tell[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSUserNotificationCenter[/color]'s [color=#3F7F00]defaultUserNotificationCenter[/color] [b]to[/b] [color=#3F7F00]deliverNotification_[/color]([color=#3F7F00]thisNote[/color])
[b]end[/b] [color=#3F7F00]sendMessage[/color][/size][/FONT]

Da es mit dem Quellcode allein nicht getan ist, gibt es das Programm als ganzes noch hier zum Download. Bedenkt aber, dass sich das Programm noch im Alphastatus befindet. Im Moment kann ich nur garantieren, dass es bei mir funktioniert.

Natürlich bin ich gespannt auf eure Verbesserungsvorschläge und Anregungen.


Bildschirmfoto 2012-08-23 um 10.22.56.png

 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: man0l0, tuedel125, Andy.321 und 5 andere
Bekannte Bugs:

- Cover, die nicht quadratisch sind, werden nicht angezeigt (behoben)
- Bei Titeln ohne Cover wird das vorherige Cover angezeigt (behoben, das iTunes-Logo wird angezeigt)

Änderungen:

- Die Meldungen erscheinen jetzt nicht mehr erst nach 5s, sondern sofort bzw. so früh wie möglich.
- Trigger über Observer statt Schleife / Performance-Verbesserungen (s. kermitds Vorschlag)
 
Zuletzt bearbeitet:
Noch ein Hinweis: im Moment ist das Skript so eingestellt, dass die Meldung 5s nach Abspielen des Titels kommt (delay 5). Der Wert kann natürlich geändert werden, bei mir reicht ein delay 1 vollkommen aus. Das ist jedoch abhängig von der Geschwindigkeit des Rechners, ich hab das bisher nur bei mir mit SSD ausprobiert. Ich werde aber noch versuchen dafür eine bessere Lösung zu finden.

Edit: Die aktuelle Version bringt die Meldung nun sobald wie möglich
 
Zuletzt bearbeitet:
Geniale Umsetzung! Vielen Dank :)

Ein kleiner Kritikpunkt nur, bzw. eventuell eine Anregung zur Verbesserung:
Ich habe bisher die App iTunification verwendet, diese hat aber leider das erwähnte Icon Problem und schaut daher nicht gerade toll aus. Das Einzige was mir daran aber gefallen hat, war dass immer nur der aktuelle Song im Notification Center zu sehen ist und nicht eine lange Liste aller früheren. Wäre sowas auch in deinem Programm machbar?
 
Wenn du in die Systemeinstellungen->Benachrichtigungen gehst, dann kannst du auswählen von keine bis 5 Meldungen.
 
Clevere Lösung! Auch wenn es natürlich (wie Du ja auch schreibst) richtig dreckig ist, ständig das NotificationCenter abzuschießen :D

Ein erster Verbesserungsvorschlag meinerseits wäre es, kein Polling zu betreiben, sondern Dich für das Empfangen von iTunes-Notifications zu registrieren (erste beiden Zeilen). Dann muss das Skript nicht ständig in einer Schleife nachhaken , sondern wird nur aktiv, wenn iTunes auch wirklich etwas macht.

Code:
set dnc to current application's NSDistributedNotificationCenter's defaultCenter
tell dnc to addObserver_selector_name_object_(me, "updateTrackInfo", "com.apple.iTunes.playerInfo", missing value)

global currentTrack, currentTrackName, currentTrackAlbum, currentTrackArtist

on updateTrackInfo()
	fetchiTunesTrackInfo()
	adjustIconForAlbumArtworkOfCurrentTrack()
	delay 1
	sendMessage(currentTrackName, currentTrackArtist, currentTrackAlbum)
end updateTrackInfo

on fetchiTunesTrackInfo()
	try
		tell application "iTunes"
			set currentTrack to the current track
			set currentTrackName to the name of the currentTrack
			set currentTrackAlbum to the album of the currentTrack
			set currentTrackArtist to the artist of the currentTrack
		end tell
	end try
end fetchiTunesTrackInfo

on adjustIconForAlbumArtworkOfCurrentTrack()
	(*
		…
		
	*)
end adjustIconForAlbumArtworkOfCurrentTrack

on sendMessage(myTitle, mySubtitle, myContent)
	(*
		…
	*)
end sendMessage
 
  • Gefällt mir
Reaktionen: Pill
Danke, genau solche Tipps hatte ich mir erhofft!

Für das Abschießen habe ich leider noch keine Alternative gefunden, es scheint leider keine Möglichkeit zu geben die registrierten Apps im Notification Center zu aktualisieren.
 
Hallo,

sondern Dich für das Empfangen von iTunes-Notifications zu registrieren
Absolut.

Ergänzend ist noch zu sagen:

-fetchiTunesTrackInfo kann man komplett weg lassen, da die Notification vom Observer die notwendigen Titelinformationen enthält.
D.h. man spart sich zusätzlich die gesamte Event Schickerei.

Viele Grüße
 
Hallo little_pixel,

da musst du mir nochmal weiterhelfen, wie ich das in ASOC realisiere. Ich schätze mal ich muss folgendes in ASOC umsetzen (?):

Code:
- (void)updateTrackInfo:(NSNotification *)aNotification
{
/* .... */
NSDictionary *trackInfos = [[NSDictionary alloc] initWithDictionary:aNotification];
NSString *currentTrackAlbum = [trackInfos valueForKey:@"Album"];
/* ... */
}

Insbesondere wie ich das Dictionary in ASOC erstelle würde ich gerne wissen. Und falls ich komplett auf dem Holzweg sein sollte, dann brauch ich wohl noch etwas mehr Hilfe ;)
 
Hallo,

vorab, ich habe Null Ahnung von Cocoa-AppleScript. Ich bin in Cocoa/Objective-C zu Hause.

Der Teil…

Code:
me, "updateTrackInfo", "com.apple.iTunes.playerInfo"

… müßte zu "updateTrackInfo:" werden.

… und der Teil:

Code:
on updateTrackInfo()

… müßte zu "updateTrackInfo_(notification)" werden.

Dann müsstest Du Dir von "notification" die Infos abholen und weiter verarbeiten: https://developer.apple.com/library...nsnotification_Class/Reference/Reference.html

Viele Grüße

PS:
Ich habe mir damals aus Neugierde "Cocoa-AppleScript" angesehen, da die Apple Buben ja "AppleScript Studio" eingestampft haben.
Meiner Meinung nach kann man gleich das richtige "Cocoa/Objective-C" lernen, statt sich "Cocoa-AppleScript" anzutun.
Den die Ganze Trivialität von AppleScript ist damit verloren gegangen. Um "Cocoa-AppleScript" richtig schreiben zu können sind gute Kenntnisse in "Cocoa/Objective-C" notwendig. … und wer die hat, der macht sich nicht mehr den Umweg.
 
  • Gefällt mir
Reaktionen: chebfarid und Pill
Dann müsstest Du Dir von "notification" die Infos abholen und weiter verarbeiten: https://developer.apple.com/library...nsnotification_Class/Reference/Reference.html

Code:
set currentTrackName to aNotification's userInfo's objectForKey_("Name")
set currentTrackArtist to aNotification's userInfo's objectForKey_("Artist")
set currentTrackAlbum to aNotification's userInfo's objectForKey_("Album")

sollte es ja bereits tun.

Pillhier ist grundlegend beschrieben, wie Obj-C in AS umzuformulieren ist.
In Deinem Codebeispiel müsstest Du denke ich initWithDictionary:aNotification in initWithDictionary:[aNotification userInfo] ändern, dementsprechend wäre der Code in ASObjC:

Code:
on updateTrackInfo_(aNotification)
tell current application's NSDictionary to set trackInfos to alloc()'s initWithDictionary_(aNotification's userInfo)
set currentTrackAlbum to trackInfos's valueForKey_("Album")

EDIT:
Nochmal was ganz anderes – kann es sein, dass die Änderung an der NotificationCenter-Datenbank gar nicht nötig ist? Bei mir scheint do shell script "killAll NotificationCenter" bereits auszureichen, damit NC danach das neue Icon registriert.

EDIT 2:
Und eine eigentlich triviale Verbesserung ist mir noch eingefallen. Man kann property latestAlbum : "" dem Skript hinzufügen, und den Einstieg in adjustIconForAlbumArtworkOfCurrentTrack() davon abhängig machen, ob sich das Album überhaupt geändert hat. Denn nur dann muss ja das Icon aktualisiert werden:
Code:
if ((currentTrackAlbum as string) is not equal to (latestAlbum as string)) then adjustIconForAlbumArtworkOfCurrentTrack()
und dann in adjustIconForAlbumArtworkOfCurrentTrack() :
Code:
set latestAlbum to currentTrackAlbum
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Pill
Leider kann ich den ersten Beitrag nicht mehr editieren, darum hier jetzt die aktuelle Version:

Code:
[FONT=Verdana][size=2][color=#4C4D4D]-- main.scpt[/color]
[color=#4C4D4D]-- Cocoa-AppleScript Applet[/color]
[color=#4C4D4D]--[/color]
[color=#4C4D4D]-- Copyright 2011 {Your Company}. All rights reserved.[/color]

[color=#4C4D4D]-- This is the main script for a Cocoa-AppleScript Applet.[/color]
[color=#4C4D4D]-- You can put the usual script applet handlers here.[/color]
[b]set[/b] [color=#3F7F00]dnc[/color] [b]to[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSDistributedNotificationCenter[/color]'s [color=#3F7F00]defaultCenter[/color]
[b]tell[/b] [color=#3F7F00]dnc[/color] [b]to[/b] [color=#3F7F00]addObserver_selector_name_object_[/color]([b]me[/b], "updateTrackInfo:", "com.apple.iTunes.playerInfo", [color=#0000FF][i]missing value[/i][/color])

[b]global[/b] [color=#3F7F00]currentTrackName[/color], [color=#3F7F00]currentTrackAlbum[/color], [color=#3F7F00]currentTrackArtist[/color], [color=#3F7F00]currentTrackArtworkCount[/color]
[b]property[/b] [color=#3F7F00]latestAlbum[/color] : ""

[b]on[/b] [color=#3F7F00]updateTrackInfo_[/color]([color=#3F7F00]aNotification[/color])
	
	[b]tell[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSDictionary[/color] [b]to[/b] [b]set[/b] [color=#3F7F00]trackInfo[/color] [b]to[/b] [color=#3F7F00]alloc[/color]()'s [color=#3F7F00]initWithDictionary_[/color]([color=#3F7F00]aNotification[/color]'s [color=#3F7F00]userInfo[/color])
	[b]set[/b] [color=#3F7F00]playerState[/color] [b]to[/b] [color=#3F7F00]trackInfo[/color]'s [color=#3F7F00]valueForKey_[/color]("Player State") [b]as[/b] [color=#0000FF][i]string[/i][/color]
	[b]if[/b] [color=#3F7F00]playerState[/color] [b]is[/b] [b]not[/b] "playing" [b]then[/b] [b]return[/b]
	[b]set[/b] [color=#3F7F00]currentTrackAlbum[/color] [b]to[/b] [color=#3F7F00]trackInfo[/color]'s [color=#3F7F00]valueForKey_[/color]("Album")
	[b]set[/b] [color=#3F7F00]currentTrackArtist[/color] [b]to[/b] [color=#3F7F00]trackInfo[/color]'s [color=#3F7F00]valueForKey_[/color]("Artist")
	[b]set[/b] [color=#3F7F00]currentTrackName[/color] [b]to[/b] [color=#3F7F00]trackInfo[/color]'s [color=#3F7F00]valueForKey_[/color]("Name")
	[b]set[/b] [color=#3F7F00]currentTrackArtworkCount[/color] [b]to[/b] [color=#3F7F00]trackInfo[/color]'s [color=#3F7F00]valueForKey_[/color]("Artwork Count") [b]as[/b] [color=#0000FF][i]string[/i][/color]
	
	[b]if[/b] ([color=#3F7F00]currentTrackAlbum[/color] [b]as[/b] [color=#0000FF][i]string[/i][/color]) ≠ ([color=#3F7F00]latestAlbum[/color] [b]as[/b] [color=#0000FF][i]string[/i][/color]) [b]then[/b]
		[color=#3F7F00]adjustIconForAlbumArtworkOfCurrentTrack[/color]()
	[b]end[/b] [b]if[/b]
	
	[color=#3F7F00]sendMessage[/color]([color=#3F7F00]currentTrackName[/color], [color=#3F7F00]currentTrackArtist[/color], [color=#3F7F00]currentTrackAlbum[/color])
[b]end[/b] [color=#3F7F00]updateTrackInfo_[/color]

[b]on[/b] [color=#3F7F00]adjustIconForAlbumArtworkOfCurrentTrack[/color]()
	[b]set[/b] [color=#3F7F00]latestAlbum[/color] [b]to[/b] [color=#3F7F00]currentTrackAlbum[/color]
	[color=#0016B0][b]do shell script[/b][/color] "killAll NotificationCenter;"
	[b]set[/b] [color=#3F7F00]thePath[/color] [b]to[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSBundle[/color]'s [color=#3F7F00]mainBundle[/color]'s [color=#3F7F00]resourcePath[/color] [b]as[/b] [color=#0000FF][i]string[/i][/color]
	[b]set[/b] [color=#3F7F00]thefile[/color] [b]to[/b] [color=#3F7F00]thePath[/color] & "/Icon.png" [b]as[/b] [color=#0000FF][i]string[/i][/color]
	
	[b]if[/b] [color=#3F7F00]currentTrackArtworkCount[/color] ≠ "0" [b]then[/b]
		[b]tell[/b] [color=#0000FF][i]application[/i][/color] "iTunes"
			[b]set[/b] [color=#3F7F00]currentTrackArtwork[/color] [b]to[/b] [color=#6C04D4]raw data[/color] [b]of[/b] [color=#0000FF][i]artwork[/i][/color] 1 [b]of[/b] [color=#6C04D4]current track[/color]
		[b]end[/b] [b]tell[/b]
		
		[b]try[/b]
			[b]set[/b] [color=#3F7F00]thefilehandle[/color] [b]to[/b] [color=#0016B0][b]open for access[/b][/color] ([color=#3F7F00]thefile[/color]) [b]with[/b] [color=#0016B0]write permission[/color]
			[color=#0016B0][b]write[/b][/color] [color=#3F7F00]currentTrackArtwork[/color] [color=#0016B0]to[/color] [color=#3F7F00]thefilehandle[/color] [color=#0016B0]starting at[/color] 0
			[color=#0016B0][b]close access[/b][/color] [color=#3F7F00]thefilehandle[/color]
		[b]on[/b] [b]error[/b] [color=#3F7F00]err[/color]
			[color=#0016B0][b]close access[/b][/color] [color=#3F7F00]thefilehandle[/color]
		[b]end[/b] [b]try[/b]
		
		[b]set[/b] [color=#3F7F00]theCommand[/color] [b]to[/b] "sips --resampleHeightWidth 128 128 " & [color=#6C04D4]quoted form[/color] [b]of[/b] [color=#3F7F00]thefile[/color] & " -o " & [color=#6C04D4]quoted form[/color] [b]of[/b] [color=#3F7F00]thefile[/color] & "; sips -s format icns " & [color=#6C04D4]quoted form[/color] [b]of[/b] [color=#3F7F00]thefile[/color] & " -o '" & [color=#3F7F00]thePath[/color] & "/Applet.icns';"
		[color=#0016B0][b]do shell script[/b][/color] [color=#3F7F00]theCommand[/color]
	[b]else[/b]
		[b]set[/b] [color=#3F7F00]cmd[/color] [b]to[/b] "rm '" & [color=#3F7F00]thePath[/color] & "/Applet.icns'; cp '" & [color=#3F7F00]thePath[/color] & "/Applet2.icns' '" & [color=#3F7F00]thePath[/color] & "/Applet.icns'"
		[color=#0016B0][b]do shell script[/b][/color] [color=#3F7F00]cmd[/color]
	[b]end[/b] [b]if[/b]
[b]end[/b] [color=#3F7F00]adjustIconForAlbumArtworkOfCurrentTrack[/color]

[b]on[/b] [color=#3F7F00]sendMessage[/color]([color=#3F7F00]myTitle[/color], [color=#3F7F00]mySubtitle[/color], [color=#3F7F00]myContent[/color])
	[b]tell[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSUserNotification[/color] [b]to[/b] [b]set[/b] [color=#3F7F00]thisNote[/color] [b]to[/b] [color=#3F7F00]alloc[/color]()'s [color=#3F7F00]init[/color]()
	[b]set[/b] [color=#3F7F00]thisNote[/color]'s [color=#3F7F00]title[/color] [b]to[/b] [color=#3F7F00]myTitle[/color]
	[b]set[/b] [color=#3F7F00]thisNote[/color]'s [color=#3F7F00]subtitle[/color] [b]to[/b] [color=#3F7F00]mySubtitle[/color]
	[b]set[/b] [color=#3F7F00]thisNote[/color]'s [color=#3F7F00]informativeText[/color] [b]to[/b] [color=#3F7F00]myContent[/color]
	[b]tell[/b] [color=#4A1E7F]current application[/color]'s [color=#3F7F00]NSUserNotificationCenter[/color]'s [color=#3F7F00]defaultUserNotificationCenter[/color] [b]to[/b] [color=#3F7F00]deliverNotification_[/color]([color=#3F7F00]thisNote[/color])
[b]end[/b] [color=#3F7F00]sendMessage[/color][/size][/FONT]

Und der Link: http://cl.ly/2u1I2M3E2i2s

Vielen, vielen Dank nochmal an little_pixel und kermitd! So langsam wird das zu einem richtig guten Projekt!
 
Zuletzt bearbeitet:
Hallo,

den tell-Block für iTunes könntest Du auch noch aus "updateTrackInfo_" entfernen.
Der Status wird, wenn ich mich richtig erinnere, ebenfalls mit übergeben. Lasse Dir einfach mal alles Schlüssel ausgeben.

Viele Grüße
 
Mir ist noch was aufgefallen:

Hole alles aus dem iTunes tell-Block bei adjustIconForAlbumArtworkOfCurrentTrack() heraus.
Das muss nicht von iTunes druchgenudelt werden. Hole Dir einfach kurz vorher das "artwork" ab.

Viele Grüße
 
Ich habe nochmals Einen:

verwende besser "path to resource "xyz.png"

Viele Grüße
 
Hi little_pixel,

das Albumcover müsste eigentlich auch in trackInfos drinstehen, das werd ich mal so versuchen. Path to resource hat bei mir nicht funktioniert, das hat immer nur in einem normalen AppleScript geklappt, nicht in einem Cocoa-AppleScript. Ich werd mir das aber nochmal anschauen.
 
das Albumcover müsste eigentlich auch in trackInfos drinstehen
Nö. Das steht nicht drin.
Das mußt Du noch mit einem iTunes Event abholen.

Path to resource hat bei mir nicht
Alternativ mal NSBundle -pathFor…: ansehen

Viele Grüße
 
ja ich hab's jetzt mit resourcePath gemacht.
 
Super.

Viele Grüße
 
Sieht gut aus! :) Hatte mit der aktuellen Version allerdings Probleme beim schnellen Trackwechseln. Entweder das Albumcover war veraltet, oder bereits übersprungene Tracks wurden als neueste Benachrichtigung angezeigt. Außerdem wurde manchmal die Benachrichtigung nicht angezeigt (aber im NC hinterlegt). Beim schnellen Trackwechseln gab's Fehler in der Konsole:

CocoaApplet[17082]: *** -[BAGenericObject updateTrackInfo:]: No matching processes belonging to you were found (error 1)

Hab das jetzt soweit ich beurteilen kann mit folgenden Änderungen behoben (möglicherweise lässt sich das aber auch anders lösen?) :

  • Entfernung des "killall"-Skript aus adjustForAlbumArtworkOfCurrenTrack
  • Neue globale Variable latestTrackFlag, die
  • zum Einstieg in updateTrackInfo_ auf true gesetzt wird​
  • beim Einstieg in adjustIconForAlbumArtworkOfCurrentTrack auf false gesetzt wird​
  • Überprüfung am Ende von adjustIconForAlbumArtworkOfCurrentTrack, ob der Track über den wir benachrichtigt wurden nach wie vor aktuell ist. Falls ja, das "latest album" auf das currentTrackAlbum unserer Notification setzen und das "latest track" flag auf wahr setzen.
  • in updateTrackInfo nach dem Ausstieg aus adjustIconForAlbumArtworkOfCurrentTrack das Fortsetzen der Abarbeitung vom "latest track" flag abhängig machen
  • Dann NC abschießen mit folgendem 0.5s delay und weiterer Pause, falls der NotificationCenter-Prozess nicht existiert

Das in rot markierte sollten die hinzugekommenen Änderungen sein:
Code:
-- main.scpt
-- Cocoa-AppleScript Applet
--
-- Copyright 2011 {Your Company}. All rights reserved.

-- This is the main script for a Cocoa-AppleScript Applet.
-- You can put the usual script applet handlers here.

global currentTrackName, currentTrackAlbum, currentTrackArtist, currentTrackArtworkCount, [COLOR="#FF0000"]latestTrackFlag[/COLOR]
property latestAlbum : ""

set dnc to current application's NSDistributedNotificationCenter's defaultCenter
tell dnc to addObserver_selector_name_object_(me, "updateTrackInfo:", "com.apple.iTunes.playerInfo", missing value)

on updateTrackInfo_(aNotification)
	[COLOR="#FF0000"]set latestTrackFlag to true[/COLOR]
	tell current application's NSDictionary to set trackInfo to alloc()'s initWithDictionary_(aNotification's userInfo)
	set playerState to trackInfo's valueForKey_("Player State") as string
	if playerState is not "playing" then return
	set currentTrackAlbum to trackInfo's valueForKey_("Album")
	set currentTrackArtist to trackInfo's valueForKey_("Artist")
	set currentTrackName to trackInfo's valueForKey_("Name")
	set currentTrackArtworkCount to trackInfo's valueForKey_("Artwork Count") as string
	if (currentTrackAlbum as string) ≠ (latestAlbum as string) then adjustIconForAlbumArtworkOfCurrentTrack()
	[COLOR="#FF0000"]if (latestTrackFlag is false) then return
	do shell script "killAll NotificationCenter;"
	delay 0.5
	repeat while (appIsRunning("NotificationCenter") is false)
		delay 0.2
	end repeat[/COLOR]
	sendMessage(currentTrackName, currentTrackArtist, currentTrackAlbum)
	
	
	
end updateTrackInfo_

on adjustIconForAlbumArtworkOfCurrentTrack()
	[COLOR="#FF0000"]set latestTrackFlag to false[/COLOR]
	set thePath to current application's NSBundle's mainBundle's resourcePath as string
	set thefile to thePath & "/Icon.png" as string
	
	if currentTrackArtworkCount ≠ "0" then
		tell application "iTunes" to set currentTrackArtwork to raw data of artwork 1 of current track
		
		try
			set thefilehandle to open for access (thefile) with write permission
			write currentTrackArtwork to thefilehandle starting at 0
			close access thefilehandle
		on error err
			close access thefilehandle
			
			
		end try
		
		set theCommand to "sips --resampleHeightWidth 128 128 " & quoted form of thefile & " -o " & quoted form of thefile & "; sips -s format icns " & quoted form of thefile & " -o '" & thePath & "/Applet.icns';"
		do shell script theCommand
		
		
	else
		set cmd to "rm '" & thePath & "/Applet.icns'; cp '" & thePath & "/Applet2.icns' '" & thePath & "/Applet.icns'"
		do shell script cmd
		
	end if
	
	[COLOR="#FF0000"]--check to make sure that the track that triggered the notification is still the current one
	tell application "iTunes" to set actualCurrentTrack to name of current track
	if (actualCurrentTrack as string) = (currentTrackName as string) then
		set latestAlbum to currentTrackAlbum
		set latestTrackFlag to true
	end if[/COLOR]
end adjustIconForAlbumArtworkOfCurrentTrack

[COLOR="#FF0000"]on appIsRunning(appName)
	tell application "System Events" to (name of processes) contains appName
end appIsRunning[/COLOR]

on sendMessage(myTitle, mySubtitle, myContent)
	tell current application's NSUserNotification to set thisNote to alloc()'s init()
	set thisNote's title to myTitle
	set thisNote's subtitle to mySubtitle
	set thisNote's informativeText to myContent
	tell current application's NSUserNotificationCenter's defaultUserNotificationCenter to deliverNotification_(thisNote)
end sendMessage
 
Zurück
Oben Unten