Pour les utilisateurs de SONOS

Discutez ici de vos souhaits d'évolutions et de vos idées pour eedomus

Re: Pour les utilisateurs de SONOS

Messagepar galaksy2001 » 20 Jan 2017 12:15

J'utilise http://www.voicerss.org/ pour le tts.
galaksy2001
 
Messages : 727
Inscription : 06 Jan 2014

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 20 Jan 2017 12:47

En effet cela parait tres bien. Meme avec la version gratuite.
(en jouant avec l'enregistrement des TTS precedent , cela devrait largement suffir)

Tu peux me donner le bout de code que tu utilise ?

Merci
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar galaksy2001 » 20 Jan 2017 13:31

Dans le fichier sonos.class.php tu vas au paragraphe :

// Google Translate API cannot handle strings > 100 characters.

Voici ensuite mon code :

Code : Tout sélectionner
$mp3[$i] = file_get_contents('http://api.voicerss.org/?key=xxxxxxxxxxxxxxxx&f=44khz_16bit_stereo&hl=fr-fr&src='.$words[$i].'&tl='.$lang);


La key corresponds au code API fourni par voicerss lorsque tu t'inscris.
galaksy2001
 
Messages : 727
Inscription : 06 Jan 2014

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 20 Jan 2017 14:26

Merci beaucoup ca marche nickel.

Je gere maintenant les MP3 personnels ( chien qui aboie par exemple) et les TTS via Voice RSS ou l'eedomus.

Thanks !
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar galaksy2001 » 20 Jan 2017 14:44

Your welcome ;)
galaksy2001
 
Messages : 727
Inscription : 06 Jan 2014

Re: Pour les utilisateurs de SONOS

Messagepar agusta68 » 23 Jan 2017 21:46

Bonjour et merci pour ce poste qui est fort intéressant même si je n'ai, pour le moment (je perd presque espoir :mrgreen: ), réussi à faire dire bonjour à ma SONOS...

J'ai le message d'erreur sur l'appli SONOS fichier introuvable et pas de dossier audio ni de MP3 de créé (donc forcement il est introuvable :evil: )

Depuis le début de ce poste SONOS GOOGLE ont essuyé beaucoup de mise a jour... quelqu'un arrive t'il a faire marcher ces TTS à ce jour?

Si oui j'aurais besoin d'aide (après mes nuits blanche à passer sur 3 ou 4 forum différent qui traite de ce sujet)
je passe par un server Synology : pouvez me dire:
-Clairement quel sont les prérequis du server PHP(case a cocher dans le paquet WEB STATION?)
-quelle sont les permission qu'a besoin le dossier web et ces sous dossier SONOS?(guest/http/admin lecture écriture)
Pouvez vous partager les dernier fichier sonos.class.php et sonos.tts.php qui fonctionne?

Actuellement le lien qui fonctionne sans captcha sous google est le suivant:
http://translate.google.com/translate_tts?q=bonjour&tl=fr&idx=0&client=eedomus

les fichiers de djmomo et clement dispo sur github sont ils à jour?

Beaucoup de demande je sais...mais j'ai vraiment besoin d'aide je suis perdu...

Promis si j'arrive a faire parler ma sonos je mettrais en forme en ptit tutos "faire parler sa SONOS pour les nuls avec un synology". :lol:
agusta68
 
Messages : 12
Inscription : 23 Jan 2017

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 23 Jan 2017 23:20

Salut

Je suis dans la meme config que toi.

As-tu dejà suivi scrupuleusement le tuto ?
https://github.com/DjMomo/sonos

On va y aller petit a petit

Tu as activé par défaut ton site Web sur le Syno ?
Tu doit avoir a la racine du syno un répertoire "web"
Dans lequel tu aura créer un répertoire "sonos" et copier les fichiers PHP. (Via un explorateur depuis ton PC , ou l'explorateur dans l'interface du syno)

créer aussi un sous-répertoire "audio" (attention jamais de majuscule)
Via l'interface du syno , et son explorateur , faut rajouter des droits sur le répertoire "audio" pour l'utilisateur "HTTP" .. J'ai mis "Controle Total" (que sur audio).
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar agusta68 » 24 Jan 2017 19:17

Bonjour effectivement c'est mieux de reprendre petit à petit car j'ai fait beaucoup de test divers et varié....tous ce mélange un peu...

J'ai créé le fichier audio (faut il créer un sous dossier fr?)

Pour info j'arrive à lancer le script sonos.play.php depuis le syno de ce coté la on est bon le sonos ce met en play :)

j’attends la suite avec impatience je reste connecté ce soir... :mrgreen:

Merci pour ton aide en tous cas!!!
agusta68
 
Messages : 12
Inscription : 23 Jan 2017

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 24 Jan 2017 20:40

Si tu as bien mis les droits pour http , le sous repertoire FR , va se creer tous seul.

Dedans devrait apparaître les fichiers MP3

Peut etre un avec 0ko (ce qui veux dire que le tts google ne marche pas)
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 24 Jan 2017 20:50

Coté SONOS
Dans l'appli , il faut que tu rajoute dans "paramètre de la bibliothèque musicale" le lien vers ton répertoire Audio

Ça donne : Audio //Diskstation/web/sonos/audio
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 24 Jan 2017 20:57

Mon fichier de lancement ..

Verifie que tu as bien $directory (en debut et fin du fichier) , y a eu plusieurs versions qui ont circulé.

Code : Tout sélectionner
<?php
// Exemple de l'utilisation de la fonction Text-to-speech
require("sonos.class.php");
$IP_sonos_1 = "192.168.xx.xx"; // A adapter avec l'adresse IP du Sonos à contrôler
$directory = "diskstation/web/sonos";

$volume = 0;
$force_unmute = 0;

if (isset($_GET['ip'])) $IP_sonos_1 = $_GET['ip'];
if (isset($_GET['force_unmute'])) $force_unmute = $_GET['force_unmute']; // Force la désactivation de la sourdine. Optionnel
if (isset($_GET['volume'])) $volume = $_GET['volume']; // Niveau sonore. Optionnel.
$message = $_GET['message']; // Message à diffuser
echo $volume;
echo $force_unmute;
echo "message :".$message;
echo "IP:".$IP_sonos_1;
//Instanciation de la classe
$sonos_1 = new SonosPHPController($IP_sonos_1);
$sonos_1->PlayTTS($message,$directory,$volume,$force_unmute); //Lecture du message
?>



Pour les multiples "Echo" je m'en sert pour le debug
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar agusta68 » 24 Jan 2017 22:28

Re, voilà avec le dossier audio et les bon PHP j'arrive enfin à faire parler ma SONOS!! Merci comme quoi des fois il faut juste prendre un peu de recul!!
Merci je vais m'atteler à faire un petit récapitulatif pour les prochains!!
Je vais maintenant voir comment faire parler mes périphériques je ne suis malheureusement pas sur eedomus mais sur Zipabox. ... :o
agusta68
 
Messages : 12
Inscription : 23 Jan 2017

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 24 Jan 2017 22:35

Ca fonctionne avec le TTS de Google ? ou un autre ?

De mon coté , j'ai pris en charge les Playlists Spotify ( qui ne redemarre pas correctement apres un TTS)
Aussi la lecture de MP3 standard (sans passé par le TTS)
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar agusta68 » 24 Jan 2017 22:55

En faite il me semble que dans le script il y a le tts de Google et de acapela mais je ne sais pas lequel il choisit par défaut je pense Google...
Pour lire un mp3 stocké la ligne de commande à rajouter m'intéresse...
agusta68
 
Messages : 12
Inscription : 23 Jan 2017

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 24 Jan 2017 23:07

Ce n'est pas qu'une commande ...
Je regarde si le message fini par MP3 .. et dans ce cas je lance la lecture du MP3 , au lieu de passer par la phase de conversion Text en MP3.

voici le bout de code que j'utilise

Toute la fonction PlayTTS() qui corrige le bug des playlists Spotify a l'occasion

Code : Tout sélectionner
   public function PlayTTS($message,$directory,$volume=0,$unmute=0,$lang='fr')
   {
      echo "\r\n- PlayTTS()".$message." - ".$directory." - ".$volume." - ".$unmute." - ".$lang."\r\n";
      $actual['track'] = $this->GetPositionInfo();
      $actual['volume'] = $this->GetVolume();
      $actual['mute'] = $this->GetMute();
      $actual['status'] = $this->GetTransportInfo();
      $this->Pause();
      if ($unmute == 1)
         $this->SetMute(0);
      if ($volume != 0)
         $this->SetVolume($volume);
      
      echo $actual['track'];
      echo $actual['volume'];
      echo $actual['mute'];
      echo $actual['status'];
      
   
    If ((stripos($message,".mp3")) !== false)
    {
      // Code permettant de lire le fichier MP3 si message contient ".mp3"
        $file = 'x-file-cifs://'.$directory.'/audio/'.$message;
    }
    else
    {
      // Commande permettant la traduction texte en MP3
        $file = 'x-file-cifs://'.$directory.'/'.$this->TTSToMp3($message,$lang);
   
    }
      

    // Si message = "TTS" alors utilise le MP3 genere par l'eedomus
    // MP3 a generer par l'Eedomus avant le lancement de ce script   (IP local de l'EEDOMUS)
    if ($message == "TTS") $file="http://192.168.xx.xxx/audio/_tts.wav" ;
   
   
      echo $file ;
      
      
      if ((stripos($actual['track']["TrackURI"],"radio://")) !== false)
      {
         //It's a radio
         echo "It's a radio only";
         $this->SetQueue($file);
         $this->Play();
         sleep(2);
         while ($this->GetTransportInfo() == "PLAYING") {}
         $this->Pause();
         $this->SetVolume($actual['volume']);
         $this->SetMute($actual['mute']);
         $this->SetQueue($actual['track']["TrackURI"]);
      
      }
      else
      {
      
         if (((stripos($actual['track']["TrackURI"],"x-file-cifs://")) !== false) or ((stripos($actual['track']["TrackURI"],".mp3")) !== false) or ((stripos($actual['track']["TrackURI"],"spotify")) !== false))
         {
                  
            // It's a MP3 file or playlist Spotify
            echo "It's a MP3 file or playlist Spotify";
            $TrackNumber = $this->AddURIToQueue($file);
            $this->ChangeTrack($TrackNumber);
            $this->Play();
            while (true) {
               @$ttsFile=$this->GetPositionInfo();
               if($ttsFile["TrackNumberInQueue"]!=$TrackNumber)
                  break;
               usleep(10000);
            }
            $this->Pause();
            $this->SetVolume($actual['volume']);
            $this->SetMute($actual['mute']);
            $this->ChangeTrack($actual['track']["TrackNumberInQueue"]);
            $this->SeekTime($actual['track']["RelTime"]);
            $this->RemoveTrackFromQueue($TrackNumber);
         
         }
         else
         {
         
            //It's a radio / or TV (playbar) / or nothing
            echo "It's a radio / or TV (playbar) / or nothing";
            $this->SetQueue($file);
            $this->Play();
            sleep(2);
            while ($this->GetTransportInfo() == "PLAYING") {}
            $this->Pause();
            $this->SetVolume($actual['volume']);
            $this->SetMute($actual['mute']);
            $this->SetQueue($actual['track']["TrackURI"]);
         
         }
      }
      if (strcmp($actual['status'],"PLAYING") == 0)
         $this->Play();
      return true;
   }
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 24 Jan 2017 23:11

Dis mois quand meme si tu utilise Google ou acapela

Pour moi .. aucun des deux ne fonctionnent
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar agusta68 » 24 Jan 2017 23:36

OK merci, je m'en occupe demain soir, je me lève très tôt demain...
je regarde pour savoir si c'est Google ou acapela et je test ton code aussi
Bonne soirée et merci
agusta68
 
Messages : 12
Inscription : 23 Jan 2017

Re: Pour les utilisateurs de SONOS

Messagepar fzaweb » 24 Jan 2017 23:58

Parcontre si quelqu'un sait comment Grouper/degrouper les SONOS en PHP ... Je suis preneur :)

Idem si quelqu'un a trouvé la solution pour le bug sur les playlists en mode aléatoire.
(le TTS ne fonctionne pas ... car le script ne retrouve plus le son TTS )


Merci
fzaweb
 
Messages : 37
Inscription : 29 Avr 2015

Re: Pour les utilisateurs de SONOS

Messagepar agusta68 » 25 Jan 2017 20:41

Salut,
Voila mon sonos.tts.php
Code : Tout sélectionner
<?php
// Code from https://github.com/DjMomo/sonos
// Exemple de l'utilisation de la fonction Text-to-speech
require("sonos.class.php");
$directory = "ipsyno/web/sonos";      // Indiquer ici le dossier partage contenant les scrips PHP sonos (et qui contiendra le sous-dossier audio)
$ttsengine = 'acapela';                  // Indiquer ici le moteur vocal a utiliser (google ou acapela)
$lang = 'fr';

$volume = 30;   // De 0 a 100 %
$force_unmute = 1;

$IP_sonos = "192.168.x.xx"; // A adapter avec l'adresse IP du Sonos a controler


if (isset($_GET['force_unmute'])) $force_unmute = $_GET['force_unmute']; // Force la desactivation de la sourdine. Optionnel
if (isset($_GET['volume'])) $volume = $_GET['volume']; // Niveau sonore. Optionnel.
$message = $_GET['message']; // Message a diffuser

// Instanciation de la classe
$sonos = new SonosPHPController($IP_sonos);
$sonos->PlayTTS($message,$directory,$volume,$force_unmute,$lang,$ttsengine); // Lecture du message
?>

Du coup je pense qu'il utilise acapela chez moi
Dernière édition par agusta68 le 25 Jan 2017 20:49, édité 1 fois.
agusta68
 
Messages : 12
Inscription : 23 Jan 2017

Re: Pour les utilisateurs de SONOS

Messagepar agusta68 » 25 Jan 2017 20:48

Et pour ceux que ça peux aider le fichier sonos.classe.php les php ensemble fonctionne chez moi...

Code : Tout sélectionner
<?php

class SonosPHPController
{
   protected $Sonos_IP;
   protected $_raw = [];

   /**
   * Constructeur
   * @param string Sonos IP adress
   * @param string Sonos port (optional)
   */
   public function __construct($Sonos_IP,$Sonos_Port = '1400')
   {
      // On assigne les param�tres aux variables d'instance.
      $this->IP = $Sonos_IP;
      $this->PORT = $Sonos_Port;
   }

   protected function Upnp($url,$SOAP_service,$SOAP_action,$SOAP_arguments = '',$XML_filter = '')
   {
      $POST_xml = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">';
      $POST_xml .= '<s:Body>';
      $POST_xml .= '<u:'.$SOAP_action.' xmlns:u="'.$SOAP_service.'">';
      $POST_xml .= $SOAP_arguments;
      $POST_xml .= '</u:'.$SOAP_action.'>';
      $POST_xml .= '</s:Body>';
      $POST_xml .= '</s:Envelope>';

      $POST_url = $this->IP.":".$this->PORT.$url;

      $ch = curl_init();
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
      curl_setopt($ch, CURLOPT_URL, $POST_url);
      curl_setopt($ch, CURLOPT_HEADER, 0);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_TIMEOUT, 30);
      curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml", "SOAPAction: ".$SOAP_service."#".$SOAP_action));
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $POST_xml);
      $r = curl_exec($ch);
      curl_close($ch);

      if ($XML_filter != '')
         return $this->Filter($r,$XML_filter);
      else
         return $r;
   }

   protected function Filter($subject,$pattern)
   {
      preg_match('/\<'.$pattern.'\>(.+)\<\/'.$pattern.'\>/',$subject,$matches); ///'/\<'.$pattern.'\>(.+)\<\/'.$pattern.'\>/'
      return $matches[1];
   }

   /**
   * Play
   */
   public function Play()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'Play';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID><Speed>1</Speed>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Pause
   */
   public function Pause()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'Pause';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Stop
   */
   public function Stop()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'Stop';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Next
   */
   public function Next()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'Next';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Previous
   */
   public function Previous()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'Previous';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Seek to position xx:xx:xx or track number x
   * @param string 'REL_TIME' for time position (xx:xx:xx) or 'TRACK_NR' for track in actual queue
   * @param string
   */
   public function Seek($type,$position)
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'Seek';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID><Unit>'.$type.'</Unit><Target>'.$position.'</Target>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Seek to time xx:xx:xx
   */
   public function SeekTime($time)
   {
      return $this->Seek("REL_TIME",$time);
   }

   /**
   * Change to track number
   */
   public function ChangeTrack($number)
   {
      return $this->Seek("TRACK_NR",$number);
   }

   /**
   * Restart actual track
   */
   public function RestartTrack()
   {
      return $this->Seek("REL_TIME","00:00:00");
   }

   /**
   * Restart actual queue
   */
   public function RestartQueue()
   {
      return $this->Seek("TRACK_NR","1");
   }

   /**
   * Get volume value (0-100)
   */
   public function GetVolume()
   {
      $url = '/MediaRenderer/RenderingControl/Control';
      $action = 'GetVolume';
      $service = 'urn:schemas-upnp-org:service:RenderingControl:1';
      $args = '<InstanceID>0</InstanceID><Channel>Master</Channel>';
      $filter = 'CurrentVolume';
      return $this->Upnp($url,$service,$action,$args,$filter);
   }

   /**
   * Set volume value (0-100)
   */
   public function SetVolume($volume)
   {
      $url = '/MediaRenderer/RenderingControl/Control';
      $action = 'SetVolume';
      $service = 'urn:schemas-upnp-org:service:RenderingControl:1';
      $args = '<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>'.$volume.'</DesiredVolume>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Get mute status
   */
   public function GetMute()
   {
      $url = '/MediaRenderer/RenderingControl/Control';
      $action = 'GetMute';
      $service = 'urn:schemas-upnp-org:service:RenderingControl:1';
      $args = '<InstanceID>0</InstanceID><Channel>Master</Channel>';
      $filter = 'CurrentMute';
      return $this->Upnp($url,$service,$action,$args,$filter);
   }

   /**
   * Set mute
   * @param integer mute active=1
   */
   public function SetMute($mute = 0)
   {
      $url = '/MediaRenderer/RenderingControl/Control';
      $action = 'SetMute';
      $service = 'urn:schemas-upnp-org:service:RenderingControl:1';
      $args = '<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredMute>'.$mute.'</DesiredMute>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Get Transport Info : get status about player
   */
   public function GetTransportInfo()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'GetTransportInfo';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      $filter = 'CurrentTransportState';
      return $this->Upnp($url,$service,$action,$args,$filter);
   }

   /**
   * Get Media Info : get informations about media
   */
   public function GetMediaInfo()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'GetMediaInfo';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      $filter = 'CurrentURI';
      return $this->Upnp($url,$service,$action,$args,$filter);
   }

   /**
   * Get Position Info : get some informations about track
   */
   public function GetPositionInfo()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'GetPositionInfo';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      $xml = $this->Upnp($url,$service,$action,$args);

      $data["TrackNumberInQueue"] = $this->Filter($xml,"Track");
      $data["TrackURI"] = $this->Filter($xml,"TrackURI");
      $data["TrackDuration"] = $this->Filter($xml,"TrackDuration");
      $data["RelTime"] = $this->Filter($xml,"RelTime");
      $TrackMetaData = $this->Filter($xml,"TrackMetaData");

      $xml = substr($xml, stripos($TrackMetaData, '&lt;'));
      $xml = substr($xml, 0, strrpos($xml, '&gt;') + 4);
      $xml = str_replace(array("&lt;", "&gt;", "&quot;", "&amp;", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $xml);

      $data["Title"] = $this->Filter($xml,"dc:title");   // Track Title
      $data["AlbumArtist"] = $this->Filter($xml,"r:albumArtist");      // Album Artist
      $data["Album"] = $this->Filter($xml,"upnp:album");      // Album Title
      $data["TitleArtist"] = $this->Filter($xml,"dc:creator");   // Track Artist

      return $data;
   }

   /**
   * Add URI to Queue
   * @param string track/radio URI
   * @param bool added next (=1) or end queue (=0)
   */
   public function AddURIToQueue($URI,$next=0)
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'AddURIToQueue';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $next = (int)$next;
      $args = '<InstanceID>0</InstanceID><EnqueuedURI>'.$URI.'</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>'.$next.'</EnqueueAsNext>';
      $filter = 'FirstTrackNumberEnqueued';
      return $this->Upnp($url,$service,$action,$args,$filter);
   }

   /**
   * Remove a track from Queue
   *
   */
   public function RemoveTrackFromQueue($tracknumber)
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'RemoveTrackFromQueue';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID><ObjectID>Q:0/'.$tracknumber.'</ObjectID>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Clear Queue
   *
   */
   public function RemoveAllTracksFromQueue()
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'RemoveAllTracksFromQueue';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Set Queue
   * @param string URI of new track
   */
   public function SetQueue($URI)
   {
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'SetAVTransportURI';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID><CurrentURI>'.$URI.'</CurrentURI><CurrentURIMetaData></CurrentURIMetaData>';
      return $this->Upnp($url,$service,$action,$args);
   }

   /**
   * Refresh music library
   *
   */
   public function RefreshShareIndex()
   {
      $url = '/MediaServer/ContentDirectory/Control';
      $action = 'RefreshShareIndex';
      $service = 'urn:schemas-upnp-org:service:ContentDirectory:1';
      return $this->Upnp($url,$service,$action,$args);
   }

   /******************************************************************************
   * Get Transport Settings : get PlayMode about player
   ******************************************************************************/
   public function GetPlayMode()   {
      
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'GetTransportSettings';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID>';
      $filter = 'PlayMode';
      return $this->Upnp($url,$service,$action,$args,$filter);
   }

   /******************************************************************************
   * Set Transport Settings : set PlayMode about player
   ******************************************************************************/
   public function SetPlayMode($playmode="NORMAL")   {
      
      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'SetPlayMode';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $args = '<InstanceID>0</InstanceID><NewPlayMode>'.$playmode.'</NewPlayMode>';
      return $this->Upnp($url,$service,$action,$args);
   }
   
   /**
   * Split string in several strings
   *
   */
   protected function CutString($string,$intmax)
   {
      $i = 0;
      while (strlen($string) > $intmax)
      {
         $string_cut = substr($string, 0, $intmax);
         $last_space = strrpos($string_cut, "+");
         $strings[$i] = substr($string, 0, $last_space);
         $string = substr($string, $last_space, strlen($string));
         $i++;
      }
      $strings[$i] = $string;
      return $strings;
   }


   
   
   /**
   * Download TTS file from Google
   *
   */
   protected function GetTtsFileFromGoogle($file,$words,$lang)
   {
      // Google Translate API cannot handle strings > 100 characters
      $words = $this->CutString($words,100);

      ini_set('user_agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0');
      $mp3 = "";
      for ($i = 0; $i < count($words); $i++)
         $mp3[$i] = file_get_contents('http://translate.google.com/translate_tts?q='.$words[$i].'&tl='.$lang.'&client=eedomus');

      file_put_contents($file, $mp3);
      
      return $file;
   }
   
   
   /**
   * Download TTS file from Acapala
   * Initial code from https://github.com/skmp/acapela-tts-zeroconf-proxy
   */
   protected function GetTtsFileFromAcapela($file,$words,$lang)
        {
                // Acapela demo TTS API cannot handle strings > 300 characters
                $words = substr($words, 0, 300);

                // Get PHP Session from cookies
                $ch = curl_init('http://www.acapela-group.com/?lang=fr');
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_HEADER, 1);
                $result = curl_exec($ch);
                preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $result, $matches);
                $cookies = array();
                foreach($matches[1] as $item) {
                    parse_str($item, $cookie);
                    $cookies = array_merge($cookies, $cookie);
                }               
                //var_dump($cookies);
                //echo $cookies['PHPSESSID'];
               
                // Get sound
                $url = 'http://www.acapela-group.com/demo-tts/DemoHTML5Form_V2.php';
                $data =
                        array(
                        'MySelectedVoice' => 'Manon',
                        'MyTextForTTS' => urldecode($words),
                        'agreeterms' => 'on',
                        'SendToVaaS' =>'');
                        // use key 'http' even if you send the request to https://...
                        $options = array(
                            'http' => array(
                                'header'  => "Cookie: PHPSESSID=".$cookies['PHPSESSID']."\r\n",
                                'method'  => 'POST',
                                'content' => http_build_query($data),
                            ),
                        );
                $context  = stream_context_create($options);
                $result = file_get_contents($url, false, $context);
                $hookp = "var myPhpVar = '";
                $temp = substr(strstr($result,$hookp),strlen($hookp));
                $rv = substr($temp,0,strpos($temp,"'"));

                file_put_contents($file, file_get_contents($rv));

                return $file;
        }
   
   
   
   /**
   * Convert Words (text) to Speech (MP3)
   *
   */
   protected function TTSToMp3($words,$lang,$ttsengine)
   {
      // Directory
      $folder = "audio/".$lang;

      // Replace the non-alphanumeric characters
      // The spaces in the sentence are replaced with the Plus symbol
      $words = urlencode($words);

      // Name of the MP3 file generated using the MD5 hash
      $file = md5($words);

      // If folder doesn't exists, create it
      if (!file_exists($folder))
         mkdir($folder, 0755, true);

      // Save the MP3 file in this folder with the .mp3 extension
      $file = $folder."/TTS-".$file.".mp3";

      // If the MP3 file exists, do not create a new request
      if (!file_exists($file))
      {   
         if($ttsengine == 'google'){
            $file = $this->GetTtsFileFromGoogle($file,$words,$lang);
         }
         elseif($ttsengine == 'acapela'){
            $file = $this->GetTtsFileFromAcapela($file,$words,$lang);
         }

      }
      return $file;
   }

   /**
   * Say song name via TTS message
   * @param string message
   * @param string radio name display on sonos controller
   * @param int volume
   * @param string language
   */
   public function SongNameTTS($directory,$volume=0,$unmute=0,$lang='fr')
   {
      $ThisSong = "Cette chanson s'appelle ";
      $By = " de ";

      $actual['track'] = $this->GetPositionInfo();

      $SongName = $actual['track']['Title'];
      $Artist = $actual['track']['TitleArtist'];

      $message = $ThisSong . $SongName . $By . $Artist ;

      $this->PlayTTS($message,$directory,$volume,$unmute,$lang);

      return true;
   }

   /**
   * Play a TTS message
   * @param string message
   * @param string radio name display on sonos controller
   * @param int volume
   * @param string language
   */
   public function PlayTTS($message,$directory,$volume=0,$unmute=0,$lang='fr',$ttsengine='google')
   {
      $actual['track'] = $this->GetPositionInfo();
      $actual['volume'] = $this->GetVolume();
      $actual['mute'] = $this->GetMute();
      $actual['status'] = $this->GetTransportInfo();
      $this->Pause();

      if ($unmute == 1)
         $this->SetMute(0);
      if ($volume != 0)
         $this->SetVolume($volume);

      $file = 'x-file-cifs://'.$directory.'/'.$this->TTSToMp3($message,$lang,$ttsengine);

      if (((stripos($actual['track']["TrackURI"],"x-file-cifs://")) !== false) or ((stripos($actual['track']["TrackURI"],".mp3")) !== false))
      {
         // It's a MP3 file
         $TrackNumber = $this->AddURIToQueue($file);
         $this->ChangeTrack($TrackNumber);
         $this->Play();
         while (true) {
            @$ttsFile=$this->GetPositionInfo();
            if($ttsFile["TrackNumberInQueue"]!=$TrackNumber)
               break;
            usleep(10000);
         }
         $this->Pause();
         $this->SetVolume($actual['volume']);
         $this->SetMute($actual['mute']);
         $this->ChangeTrack($actual['track']["TrackNumberInQueue"]);
         $this->SeekTime($actual['track']["RelTime"]);
         $this->RemoveTrackFromQueue($TrackNumber);
      }
      else
      {
         //It's a radio / or TV (playbar) / or nothing
         $this->SetQueue($file);
         $this->Play();
         sleep(2);
         while ($this->GetTransportInfo() == "PLAYING") {}
         $this->Pause();
         $this->SetVolume($actual['volume']);
         $this->SetMute($actual['mute']);
         $this->SetQueue($actual['track']["TrackURI"]);
      }

      if (strcmp($actual['status'],"PLAYING") == 0)
         $this->Play();
      return true;
   }

   public function AddSpotifyToQueue($spotify_id, $next = false) {
      $rand = mt_rand(10000000, 99999999);

      $meta = '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
            <item id="'.$rand.'spotify%3atrack%3a'.$spotify_id.'" restricted="true">
               <dc:title></dc:title>
               <upnp:class>object.item.audioItem.musicTrack</upnp:class>
               <desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2311_X_#Svc2311-0-Token</desc>
            </item>
         </DIDL-Lite>';

      $meta = htmlentities($meta);

      $url = '/MediaRenderer/AVTransport/Control';
      $action = 'AddURIToQueue';
      $service = 'urn:schemas-upnp-org:service:AVTransport:1';
      $next = (int)$next;

      $args = "
         <InstanceID>0</InstanceID>
         <EnqueuedURI>x-sonos-spotify:spotify%3atrack%3a{$spotify_id}</EnqueuedURI>
         <EnqueuedURIMetaData>{$meta}</EnqueuedURIMetaData>
         <DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued>
         <EnqueueAsNext>{$next}</EnqueueAsNext>
      ";

      $filter = 'FirstTrackNumberEnqueued';

      return $this->Upnp($url, $service, $action, $args, $filter);
   }

   public function device_info() {
      $xml = $this->_device_info_raw('/xml/device_description.xml');

      $out = [
         'friendlyName' => (string)$xml->device->friendlyName,
         'modelNumber' => (string)$xml->device->modelNumber,
         'modelName' => (string)$xml->device->modelName,
         'softwareVersion' => (string)$xml->device->softwareVersion,
         'hardwareVersion' => (string)$xml->device->hardwareVersion,
         'roomName' => (string)$xml->device->roomName,
      ];

      return $out;
   }

   public function get_coordinator() {
      $topology = $this->_device_info_raw('/status/topology');

      $myself = null;
      $coordinators = [];

      // Loop players, build map of coordinators and find myself
      foreach ($topology->ZonePlayers->ZonePlayer as $player) {
         $player_data = $player->attributes();

         $ip = parse_url((string)$player_data->location)['host'];

         if ($ip == $this->IP) {
            $myself = $player_data;
         }

         if ((string)$player_data->coordinator == 'true') {
            $coordinators[(string)$player_data->group] = $ip;
         }
      }

      $coordinator = $coordinators[(string)$myself->group];

      return new static($coordinator);
   }

   protected function _device_info_raw($url) {
      $url = "http://{$this->IP}:{$this->PORT}{$url}";

      if (!isset($this->_raw[$url])) {
         $ch = curl_init();
         curl_setopt($ch, CURLOPT_URL, $url);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
         $data = curl_exec($ch);
         curl_close($ch);

         $this->_raw[$url] = simplexml_load_string($data);
      }

      return $this->_raw[$url];
   }

   public static function detect($ip = '239.255.255.250', $port = 1900) {
      $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
      socket_set_option($sock, getprotobyname('ip'), IP_MULTICAST_TTL, 2);

      $data = <<<DATA
M-SEARCH * HTTP/1.1
HOST: {$ip}:reservedSSDPport
MAN: ssdp:discover
MX: 1
ST: urn:schemas-upnp-org:device:ZonePlayer:1
DATA;

      socket_sendto($sock, $data, strlen($data), null, $ip, $port);

      // All passed by ref
      $read = [$sock];
      $write = $except = [];
      $name = $port = null;
      $tmp = '';

      // Read buffer
      $buff = '';

      // Loop until there's nothing more to read
      while (socket_select($read, $write, $except, 1) && $read) {
         socket_recvfrom($sock, $tmp, 2048, null, $name, $port);

         $buff .= $tmp;
      }

      // Parse buffer into devices
      $data = static::_parse_detection_replies($buff);

      // Make an array of myselfs
      $devices = [];
      $unique = [];

      foreach ($data as $datum) {
         if(in_array($datum['usn'],$unique)) {
            continue;
         }
         $url = parse_url($datum['location']);

         $devices[] = new static($url['host'], $url['port']);
         $unique[] = $datum['usn'];
      }

      return $devices;
   }

   protected static function _parse_detection_replies($replies) {
      $out = [];

      // Loop each reply
      foreach (explode("\r\n\r\n", $replies) as $reply) {
         if ( ! $reply) {
            continue;
         }

         // New array entry
         $arr =& $out[];

         // Loop each line
         foreach (explode("\r\n", $reply) as $line) {
            // End of header name
            if (($colon = strpos($line, ':')) !== false) {
               $name = strtolower(substr($line, 0, $colon));
               $val = trim(substr($line, $colon + 1));

               $arr[$name] = $val;
            }
         }
      }

      return $out;
   }

   public static function get_room_coordinator($room_name) {
      // Detect devices. Sometimes takes a few goes.
      do {
         $devices = static::detect();

         if (!$devices) {
            sleep(1);
         }
      } while (!$devices);

      foreach ($devices as $device) {
         if ($device->device_info()['roomName'] == $room_name) {
            return $device->get_coordinator();
         }
      }

      return false;
   }
}


A noter que j'ai modifier la 395 ligne ci dessous dans le code par rapport au PHP d'origine
Code : Tout sélectionner
$mp3[$i] = file_get_contents('http://translate.google.com/translate_tts?q='.$words[$i].'&tl='.$lang.'&client=eedomus')


et voila
agusta68
 
Messages : 12
Inscription : 23 Jan 2017

PrécédentSuivant

Retour vers Suggestions

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 38 invité(s)