Ein Audio-Player besonderer Art

P

pbass

Aktives Mitglied
Thread Starter
Dabei seit
23.05.2009
Beiträge
836
Reaktionspunkte
73
Ich suche irgendeine Software, die mir folgendes Problem löst: es gibt ein Verzeichnis mit Audio-Dateien (z.B. mp3), die der Player abspelen soll, aber sowohl die Datei als auch die Startposition soll zufällig ausgewählt werden und der Abspieldauer im Bereich von ca. einer halben Sekunde bis ein paar Sekunden einstellbar sein. Kennt jemand so etwas für Mac, iPad oder iPhone?

Als Alternative gilt: die Startposition wird zufällig ausgewählt werden, aber mit dem Start der Wiedergabe wird ein Timer gestartet der stoppt sobald man auch die Wiedergabe stoppt. D.h. hier wird nicht nach einer fixen Zeit automatisch gestoppt.

Noch schöner wäre es, wenn man gar keine Datei auf der Platte liegen haben muss, sondern das ganze per Stream aus Spotify funktionieren würde. Das wäre die ultimative Lösung.

Falls sich jemand fragt, wozu das ganze? Zum Musik-Reaten-Spiel. Ja, ich weiß, es gibt einige Apps, die ungefähr das tun, aber eben ungefähr. Ich möchte sehr kurze Fragmente abspielen können, weil wir so gut sind, dass eine ganze Sekunde in der Regel schon viel zu lang ist, sprich - die Aufgabe zu einfach.

Danke!
 
Kennst Du dich mit Applescript etwas aus, bzw. hast Lust, dich einzuarbeiten? Im Zusammenspiel mit iTunes/Spotify ließe sich die Aufgabe damit sicher lösen. Über den Zugriff auf Zufallsgenerator, Shuffle-Funktion, abzuspielenden Track, Track-Dauer/Position im Track, Timer hast Du im Prinzip alle nötigen Werkzeuge zur Hand...
 
Kennst Du dich mit Applescript etwas aus, bzw. hast Lust, dich einzuarbeiten? Im Zusammenspiel mit iTunes/Spotify ließe sich die Aufgabe damit sicher lösen. Über den Zugriff auf Zufallsgenerator, Shuffle-Funktion, abzuspielenden Track, Track-Dauer/Position im Track, Timer hast Du im Prinzip alle nötigen Werkzeuge zur Hand...

Applescript wäre Plan B. Ich kenne mich damit nur etwas aus, habe aber als Softwareentwickler keine Berührungsängste. Allerdings wollte ich eine schöne und fertige Lösung mit GUI (Spiele das Muisk-Raten mit meiner Tochter; und schöne GUIs kann man in Applescript leider nicht bauen).

Ich sehe die Automatisierung von Spotify in diesem Fall aber sehr kritisch. Um auf den Punkt zu bringen - es wird nicht so einfach sein. Der Grund: das Zeitverhalten von Spotify ist nicht deterministisch. Es reicht also nicht im Applescript play abzusetzen und nach bestimmter Zeit pause, weil man nicht weiß wann spotify tatsächlich anfängt zu spielen. Die Statusabfrage liefert nur "playing" oder "pause" und kein "warte auf stream" oder etwas ähnliches. Die Lösung dieses Problems wäre, alle in Frage kommende Tracks vorher lokal abzuspeichern und sie abzuspielen, aber dann ist das nicht mehr so schön, weil z.B. spontanes Hinzufügen von Titel nicht mehr möglich ist (man muss immer davor den Stream in Echtzeit aufzeichnen, was abgesehen von Zeitaufwand nicht mit mit der Lizenz konform ist). Eine fertige Lösung wäre mir lieber :)
 
Gibt es im Applescript überhaupt irgendwelche Möglichkeiten mit Timer zu arbeiten, die genauer als auf ganze Sekunde laufen? Ich finde spontan nur "with timeout of X seconds". X kann aber laut Doku nur ganzzahlige Sekunden annehmen.
 
Allerdings wollte ich eine schöne und fertige Lösung mit GUI
Gut, das kann ich nachvollziehen. :)

das Zeitverhalten von Spotify ist nicht deterministisch. Es reicht also nicht im Applescript play abzusetzen und nach bestimmter Zeit pause, weil man nicht weiß wann spotify tatsächlich anfängt zu spielen. Die Statusabfrage liefert nur "playing" oder "pause"
Du hast die Möglichkeit die momentane Player-Position abzufragen. In Verbindung mit der Position an der er starten soll, würde ich denken, dass das reicht, um zu entscheiden, ob die gewünschte Zeitspanne schon abgespielt wurde?

Gibt es im Applescript überhaupt irgendwelche Möglichkeiten mit Timer zu arbeiten, die genauer als auf ganze Sekunde laufen? Ich finde spontan nur "with timeout of X seconds". X kann aber laut Doku nur ganzzahlige Sekunden annehmen.
Naja, Du hast den delay-Befehl, und - in die Richtung hätte ich jetzt gedacht - Du kannst einen idle-Handler benutzen, der immer wieder nach Ablauf der im Rückgabewert angegebenen Zeit aufgerufen wird (wenn du das Applescript so speicherst, dass es offen bleibt), also bspw.:

Code:
[B]use [/B][COLOR=#0433FF][FONT=Verdana][I]application[/I][/FONT][/COLOR][FONT=Verdana] "Spotify"
[/FONT][FONT=Verdana][B]use[/B] [COLOR=#4f8f00]TextEdit[/COLOR] : [COLOR=#0433ff][I]application[/I][/COLOR] "TextEdit"[/FONT]
[COLOR=#4F8F00][FONT=Verdana][COLOR=#000000][B]global[/B] [/COLOR]newDocument[/FONT][/COLOR]
[FONT=Verdana]
[/FONT]
[FONT=Verdana][B]on[/B] [COLOR=#0433ff][B]run[/B][/COLOR][/FONT]
[FONT=Verdana]    [B]tell[/B] [COLOR=#4f8f00]TextEdit[/COLOR] [B]to[/B] [B]set[/B] [COLOR=#4f8f00]newDocument[/COLOR] [B]to[/B] [COLOR=#0433ff][B]make[/B][/COLOR] [COLOR=#0433ff]new[/COLOR] [COLOR=#0433ff][I]document[/I][/COLOR][/FONT]
[FONT=Verdana][B]end[/B] [COLOR=#0433ff][B]run[/B][/COLOR][/FONT]
[FONT=Verdana]
[/FONT]
[COLOR=#0433FF][FONT=Verdana][COLOR=#000000][B]on[/B] [/COLOR][B]idle[/B][/FONT][/COLOR]
[FONT=Verdana]    [B]try[/B][/FONT]
[FONT=Verdana]        [B]set[/B] [B]the[/B] [COLOR=#0433ff][I]text[/I][/COLOR] [B]of[/B] [B]the[/B] [COLOR=#4f8f00]newDocument[/COLOR] [B]to[/B] "Current position: " & ([B]get[/B] [B]the[/B] [COLOR=#5730be]player position[/COLOR] [B]as[/B] [COLOR=#0433ff][I]text[/I][/COLOR])[/FONT]
[FONT=Verdana]    [B]on[/B] [B]error[/B][/FONT]
[COLOR=#0433FF][FONT=Verdana][B]quit[/B][/FONT][/COLOR]
[FONT=Verdana]    [B]end[/B] [B]try[/B][/FONT]
[FONT=Verdana]    [B]return[/B] 0.1[/FONT]
[B]end [/B][COLOR=#0433FF][FONT=Verdana][B]idle[/B][/FONT][/COLOR]
 
Danke für dein Beispiel und den entscheidenden Hinweis mit player position! Deinen code habe ich zwar zum Laufen nicht gebracht, da es scheinbar eine neuere Version von AppleScript verlangt (habe immer noch Snow Leopard, 10.6.8; und z.B. kein use-Befehl), aber die Idee mit der aktuellen Abspielposition aufgegriffen und mit Erfolg folgendermassen umgesetzt (noch mit vielen debug-Ausgaben):

Code:
on secToMMSS(theTime) -- convert a number of seconds to mm:ss
	set mm to "00" & (round (theTime / 60) rounding down) as string
	set ss to "00" & (theTime - (60 * mm)) as string
	return (text -2 thru -1 of mm) & ":" & (text -2 thru -1 of ss) as string
end secToMMSS

on PlaySpotifyAt(spotifyUrl, playTime)
	tell application "Spotify"
		try
			set trackLength to duration of current track
			set endPosition to (round trackLength - (3 * playTime) - 1 rounding down)
			set startPosition to random number from 0 to endPosition --with seed (time of (current date))
			log "startPosition: " & startPosition
			set startTime to secToMMSS(startPosition as integer) of me
			log "start at " & startTime & " end plays " & playTime & " seconds"
			set spotifyUrlAtPosition to (spotifyUrl & "#" & startTime)
			log "url: " & spotifyUrlAtPosition
			pause
			play track spotifyUrlAtPosition
			repeat until player state is playing
			end repeat
			
			repeat until (player position - startPosition) > playTime
				--log "current position: " & player position
			end repeat
			pause
			
			set pos to player position as text
			
			log "pos: " & pos
		on error
			log "error"
		end try
		return 0.1
	end tell
end PlaySpotifyAt


Morgen kommt der Rest, d.h. alle Tracks aus der Spotify-Playlist rauslesen (das habe ich schon aus den früheren Experimenten fertig, allerdings hat Spotify irgendetwas geändert, so dass ich es noch fixen muss), zufällige Auswahl und noch etwas Logik die aus unseren Spielregel resultiert, z.B. maximal drei Versuche, die hintereinander oder beliebig liegen können - das ist der Grund für trackLength - (3 * playTime) :)

Also leider Plan B ;-)
 
Irgendwo habe ich noch einen Fehler, denn im Ausgabefenster des AppleScirpt-Editors steht am Anfang:


Code:
tell application "Spotify"
    get duration of current track
        --> 281
    round 278.5 rounding down
        --> error number -10004
end tell

Hat jemand eine Idee, was die Ursache für error number -10004 sein könnte?
 
leider Plan B ;-)

:p

Danke für dein Beispiel und den entscheidenden Hinweis mit player position! Deinen code habe ich zwar zum Laufen nicht gebracht, da es scheinbar eine neuere Version von AppleScript verlangt

Gern. Sorry, bin davon ausgegangen, dass die ganze Welt bereits Mavericks benutzt. :eek: Die SL-Version sieht aber nicht viel anders aus.

Hat jemand eine Idee, was die Ursache für error number -10004 sein könnte?

Liegt daran, dass Du die (in den Applescript Standard Additions definierte, und damit im globalen Namensraum verfügbare) Anweisung - die zum Senden eines Apple-Events führt - an die Spotify-App richtest, die nichts damit anfangen kann. Wird dann aber automatisch an "current application" umgeleitet. Ist vom Prinzip her das gleiche, wie wenn Du schreiben würdest:
Code:
tell app "Spotify" to beep
Entweder Du gibst "me" bzw. "current application" explizit als Ziel an (entscheidend ist der innerste tell-Block), oder nimmst die Anweisung aus dem an Spotify gerichteten tell-Block raus:
Code:
tell application "Spotify" to tell me to beep 
#bzw. sinnvoller einfach:
beep

Ich würde übrigens in den Schleifen irgendeine Form von Delay einbauen, sonst führt das an den Stellen zur vollständigen CPU-Auslastung. :)
 
Zurück
Oben Unten