PHP Sonos (Klasse zum Ansteuern einzelner Player)

Die aktuellste Version ist im Wiki zu finden:
http://www.ip-symcon.de/wiki/PHPSonos

Eine Version des Sonos Skriptes von hier: http://www.ip-symcon.de/forum/f7/einzelne-sonos-player-ansteuern-3541/

Diesmal als PHP Klasse, die ihr vorher in euren ‚scripts‘ Ordner kopieren müsst. Dann die IP-Adresse angeben und ihr könnt die einzelnen Befehle nutzen.


include("PHPSonos.inc.php");

$sonos = new PHPSonos("192.168.3.183"); //Sonos ZP IPAdresse

//Grundfunktionen
//$sonos->Pause();
//$sonos->Play();
//$sonos->Next();
//$sonos->Previous();
//$sonos->Rewind();
//$sonos->SetVolume(25); //0-100 in %
//$sonos->SetPlayMode("NORMAL"); //REPEAT_ALL, SHUFFLE, NORMAL
//$sonos->SetMute(false); //True = MUTE, False = KEIN MUTE

//Klassik Radio abspielen
//$sonos->SetRadio("x-rincon-mp3radio://players.creacast.com/creacast/klassik/playlist.pls");
//$sonos->Play();

//Neue MP3 abspielen
$sonos->ClearQueue(); //Playlist löschen
$sonos->AddToQueue("x-file-cifs://ipsserver/Public/test.mp3"); //Datei hinzufügen
$sonos->SetQueue("x-rincon-queue:RINCON_"."HIER DIE MAC DES PLAYERS ZB: FFEEDDCCBBAA"."01400#0"); //Playlist auswählen (Nötig, wenn Radio vorher ausgewählt war)
$sonos->Play();

//$sonos->SetTrack(1); //1-n
//$sonos->RemoveFromQueue(1); //1-n

paresy

PHPSonos.inc.rar (1.69 KB)

Hi,

man kann sich bei dem Beispiel

$sonos->SetQueue(„x-rincon-queue:RINCON_“.„HIER DIE MAC DES PLAYERS ZB: FFEEDDCCBBAA“.„01400#0“)

noch etwas Recherche und Tipparbeit einsparen, in dem man sich die Mac-Adresse vom Sonos-System geben lässt.
Ruft man folgende URL auf:
http://<Ip-Adresse ZonePlayer>:1400/status/zp
bekommt man eine XML-Antwort mit Infos zum ZonePlayer. Hierbei ist dann auch die Mac-Adresse enthalten.
Die XML-Antwort schaut z.B. so aus:

<?xml version=„1.0“ ?>
<?xml-stylesheet type=„text/xsl“ href="/xml/review.xsl"?><ZPSupportInfo><ZPInfo><ZoneName>Küche</ZoneName><ZoneIcon>x-rincon-roomicon:kitchen</ZoneIcon><LocalUID>RINCON_000E582665FE01400</LocalUID><SerialNumber>00-0E-58-26-65-FE:5</SerialNumber><SoftwareVersion>13.7-29120</SoftwareVersion><MinCompatibleVersion>12.0-00000</MinCompatibleVersion><HardwareVersion>1.1.16.4-2</HardwareVersion><IPAddress>192.168.178.91</IPAddress><MACAddress>00:0E:58:26:65:FE</MACAddress><Copyright>© 2004-2007 Sonos, Inc. All Rights Reserved.</Copyright><ExtraInfo>r8: 16.0-7</ExtraInfo><IdxTrk></IdxTrk></ZPInfo></ZPSupportInfo>

Unter LocalUID findet sich der String, den man im $sonos->SetQueue Befehl braucht.
Den String kann man z.B. über folgendes Codeschnipsel bekommen:
$url = „http://“.<ipAdresse des ZonePlayers>.":1400/status/zp";
$xml = simpleXML_load_file($url);
$result = $xml->ZPInfo->LocalUID;

HTH Johannes

Hallo,

erst einmal Danke für das Bereitstellen der PHP Klasse!

Mir fehlte jedoch das Abfragen des aktuellen Status des Sonos-Players.
Daher habe ich die Klasse etwas erweitert:



include("PHPSonos.inc.php");

$sonos = new PHPSonos("192.168.3.183"); //Sonos ZP IPAdresse

$sonos->Stop();
$volume = $sonos->GetVolume(); // gibt die Lautstärke als Integer zurück
$mute = $sonos->GetMute(); // gibt ein bool zurück: TRUE -> MUTE an, FALSE -> MUTE aus
$shuffleRepeat = $sonos->GetTransportSettings(); // gibt ein Array zurück mit den keys "shuffle" und "repeat", welche jewils bool-Werte enthalten
$status = $sonos->GetTransportInfo(); // gibt den aktuellen Status des Sonos-Players als Integer zurück, 1: PLAYING, 2: PAUSED, 3: STOPPED
$posInfo = $sonos->GetPositionInfo(); // gibt ein Array mit den Informationen zum aktuellen Titel zurück (Keys: position, duration, artist, title, album, albumArtist, albumTrackNumber)

SetValueInteger($volumeID, $volume);
SetValueBoolean($muteID, $mute);
SetValueInteger($statusID, $status);
SetValueBoolean($repeatID, $shuffleRepeat["repeat"]);
SetValueBoolean($shuffleID, $shuffleRepeat["shuffle"]);
SetValueString($titleID, $posInfo["title"]);
SetValueString($artistID, $posInfo["artist"]);
SetValueString($albumID, $posInfo["album"]);
SetValueString($positionID, $posInfo["position"] . "/" . $posInfo["duration"]);

Gruß,

André

Edit:

  • PHP-Klasse angepasst:

  • AlbumArt hinzugefügt:

[INDENT]GetPositionInfo() gibt im Array mit dem Key „albumArtURI“ den URI zum Abruf des Covers vom Sonos zurück

  • Fehler abgefangen, wenn ein Track kein Album, etc. hat
    [/INDENT]

Edit (25.07.2010):

  • Name vom Radiosender kann abgerufen werden: GetMediaInfo() gibt ein Array mit dem Key „title“ zurück, welches den Sendernamen enthält.

  • URI und Senderbeschreibung hinzugefügt: GetPositionInfo() gibt nun mit den zusätzlichen keys „URI“ und „streamContent“ die entsprechenden Informationen zurück.

  • Problem mit Sonderzeichen behoben (Text wird nun in ISO-8859-1 zurückgegeben)

PHPSonos.inc.php.zip (2.85 KB)

Hi,

euch beiden erstmal Danke für die Arbeit.
Ich komme aber mit der Einbindung nicht ganz klar bzgl.der Variablen.

Andre,erstmal Willkommen :smiley:
Wäre es möglich,als PHP-Anfänger ein Screenshoot oder eine
Erklärung der zu erstellenden Variablen zu bekommen?

Hab gerade 1h selbst probiert,aber komme nicht wirklich weiter.

Vielen Dank und Grüße
Robert

Moin…

hab das Script gerade mal ausprobiert und hab das Problem das die „Wiedergabe“ stoppt sobald ich das Script ausführe!! Woran kann das liegen!?

Im IPS wird folgendes an Fehlern angezeigt!

Notice: Undefined index: R:ALBUMARTIST in C:\IP-Symcon\scripts\PHPSonos.inc.php on line 273

Notice: Undefined index: in C:\IP-Symcon\scripts\PHPSonos.inc.php on line 273

Notice: Undefined index: UPNP:ORIGINALTRACKNUMBER in C:\IP-Symcon\scripts\PHPSonos.inc.php on line 274

Notice: Undefined index: in C:\IP-Symcon\scripts\PHPSonos.inc.php on line 274

Danke und Grüße aus Hamburg,

Peter

War schon spät…ähm ne ist spät!! Hab den FEHLER gefunden! Hab immer die STOP-Aktion mit ausgeführt!! tzzzz… :slight_smile:

@RAVENOUS:

Ich hab mir einfach Variablen angelegt und diese ins Script eingefügt!!

Siehe Screenshots!!!

Gute Nacht,

Peter

Gibt es eigentlich ne Möglichkeit auch die Cover-URL abzufragen!? Das wäre ja nochmal was!!! :slight_smile:

So langsam wird das ja richtig chique…

Es fehlt halt irgendeine Möglichkeit des Dateien / Napster browsens…

Hallo Peter,

hat super funktioniert.Er schreibt jetzt in die Variablen.Danke.
Jetzt gehts noch an die Visualisierung :smiley:

Lässt du das Script jede Sekunde laufen oder hats du ein ausgelöstes Ereignis?

Über den Status würde sich das ja ganz gut machen,aber wie bekommt er den aktuellen Status ohne das Script zeitlich laufen zu lassen?

Oder fange ich da falsch an und denk zu kompliziert?

Gruß Robert

@PeterChrisben:
Deine Fehlermeldungen sollten in meiner angepassten Datei nicht mehr vorkommen. Ich hatte nicht abgefangen, was passiert, wenn ein Track kein Album, keinen Album-Artist, etc. besitzt.

Außerdem habe ich den URI für das Cover hinzugefügt. Hier wird in etwa folgender String zurückgegeben:

http://<sonos-ip>:1400/getaa?u=x-file-cifs://<pfad-zur-mp3-datei>....

Ich bin mir nur noch nicht ganz sicher, wie ich damit am besten weitermache. Zur Zeit habe ich es so gelöst, dass ich ein Medien-Objekt erstellt habe, welches auf die Datei „C:\IP-Symcon\media\AlbumArt.jpg“ zeigt. Außerdem speichere ich in einer String-Variable die URI zum Cover. Beim Ausführen meines Scripts zum Aktualisieren, überprüfe ich zunächst, ob sich das Cover geändert hat. Wenn ja, dann lade ich dies mit der Funktion changeAlbumArt.

Leider gibt es u.a. noch Probleme, wenn kein Cover vorhanden ist.

Habt ihr da noch Verbesserungsvorschläge?


function changeAlbumArt ($albumArtURI, $localFile, $mediaID) {

	$readHandle = fopen($albumArtURI, "r");
	$writeHandle = fopen($localFile, "w");

	while (!feof($readHandle)) {
		fputs($writeHandle, fgets($readHandle, 4096), 4096);
	}

	fclose($writeHandle);
	fclose($readHandle);
	
	IPS_SendMediaEvent($mediaID);

}

if (strcmp(GetValueString($albumArtUriID), $posInfo["albumArtURI"]) != 0) {
	changeAlbumArt($posInfo["albumArtURI"], "C:\\IP-Symcon\\media\\AlbumArt.jpg", $albumArtMedia);
	SetValueString($albumArtUriID, $posInfo["albumArtURI"]);
}

Hi andre,

die neue Sonos Klasse ist ja super.
Gibt es auch die Möglichkeit im Radio-Modus des Players den Sendernamen, die kurze Programmbeschreibung, die URI des Senders und vielleicht weiter Infos abfragen?

Gruß
Schorsch

@ andre: Erstmal 100 Dank für deinen schnellen Support! Ist echt Spitze!!
Ich benutze die Cover URL direkt für mein Dashboard! Einfach die URL als Link für ein Bild nehmen!!! Funktioniert wunderbar!

Ich hab zuvor auch mit einem Textparser gearbeitet und Sonosweb, aber das kann ich mir jetzt sparen! Danke nochmals.

Ich habe die Daten für den Radio-Modus in der Klasse hinzugefügt. Schau dir dazu mal meinen Edit-Kommentar an.

Gruß,
André

P.S.: Ich habe mich bei der Umsetzung nur an die Spezifikation gehalten. Falls jemand noch weitere Ergänzungen selber umsetzen möchte, kann dies mit Hilfe der folgenden Spezifikation relativ einfach geschehen:

http://www.upnp.org/specs/av/UPnP-av-AVTransport-v1-Service.pdf

Hallo,

ich habe auch einen kleinen Beitrag zu der Sonos Klasse:

  • GetPositionInfo gibt nun auch den aktuellen Track zurück
  • GetMediaInfo gibt nun auch die Anzahl der Tracks in der Liste zurück (Achtung im Radiomodus kommt bei mir immer 8)
  • SetRadio muss nun auch einen Titel bekommen (IPS Radio ist zwar nett. Aber trifft es nicht immer :wink: )

SetRadio Beispiel:

$sonos->SetRadio("x-rincon-mp3radio://players.creacast.com/creacast/klassik/playlist.pls", "Klassik Radio");

Das Ganze hab ich zur Vorbereitung meines Scripts gemacht.
Das Script soll IPS Nachrichten über die Sonos Anlage abspielen.

cu…

PHPSonos_McFly.inc.zip (2.93 KB)

Also mittlerweile komm ich ein wenig durch den Tüdel…

Welche Variablen muss ich jetzt z.B. bei der ersten Version von Paresy manuell anlegen ? Muss ich eine Dummy Instanz anlegen ?

Bei Andre sehen die Befehle plötzlich ganz anders aus ? Wo ist hier z.B. Sinn bzw. Zusammenhang zwischen $volume und $volumeID ?

Bekomm das irgendwie net umgesetzt… :frowning:

Die Befehle sehen bei mir anders aus, da diese Befehle Werte vom Sonos abrufen und nicht nur welche setzen. Grundsätzlich ist es in meinem Beispiel so, dass ich erst die Werte abrufe und z.B. in $volume speichere und diese dann einer IPS-Variable mit der ID $volumeID zuweise. Die restlichen Befehle verhalten sich dann analog.

Ich hoffe dir damit weiter geholfen zu haben.

Gruß,
André

Vielleicht hast du mal ein paar Screenshots wie das ganze in deinem Objektbaum aussieht ? Steh gerade irgendwie auf dem Schlauch… thx.

Ich habe dir hier einen Screenshot von meinem Objektbaum hinzugefügt.

screenshot_sonos.png

Hallo Andre,
ich habe gerade erst den Thread für die Sonos klasse gefunden und versuche sie bei mir einzubinden. Ich möchte einen Radiostream ( Bayern3) auf meinem Sonos System abspielen, bekomme es aber nicht hin. Kenne mich mit php nur wenig aus. Kanst Du mir DeinenBeitrag zu Sonos radio genauer erklären?
Viele Grüße,
Ralph

Hallo alle zusammen,

ich habe heute die Klasse zum ansteuern der Sonosplayer heruntergeladen und eingebaut. Läuft super!

Besten Dank dafür

@Ralph


$sonos->SetRadio("x-rincon-mp3radio://streams.br-online.de/bayern3_2.asx", "Bayern 3");

Bis dann

Martin

Ist ja ein Wahnsinnsaufwand das für 4 Zonen alles zusammenzubasteln.

Habt ihr das alles manuell gemacht ? Oder gibts ein Skript was die ganzen Variablen etc einrichtet ?