YouTube auf Sonos wiedergeben

Begonnen von jojoja, 09 September 2016, 14:37:55

Vorheriges Thema - Nächstes Thema

jojoja

Manchmal möchte man doch den Audio-Teil eines Youtube-Videos über Sonos laufen lassen.
In diesem Beispiel wird erst das Video per youtube-dl heruntergeladen und per avconv in mp3 konvertiert. Ich lasse das Ganze auf einem Raspberry Pi 2 laufen, bis die Wiedergabe beginnt kann natürlich etwas Zeit vergehen, bei meiner 50Mbit/s Leitungen braucht ein 5 Minuten Video ca. 90 Sekunden. Fhem wird in dieser Zeit nicht blockiert.

Benötigt wird dafür:
youtube-dl: https://rg3.github.io/youtube-dl/download.html
avconv:  https://wiki.ubuntuusers.de/avconv/

und ein einfaches Shell-Skript, die Dateien werden einfach im Ordner der Sprachdurchsagen abgelegt.
if [ -e /<targetSpeakDir>/youtubeDownloadForSonos.wav ]
then
        rm /<targetSpeakDir>/youtubeDownloadForSonos.wav
fi

if [ -e /<targetSpeakDir>/youtubeDownloadForSonos.mp4 ]
then
        rm /<targetSpeakDir>/youtubeDownloadForSonos.mp4
fi

perl /opt/fhem/fhem.pl 7072 "set Sonos_YoutubeDummy downloading"
/usr/local/bin/youtube-dl -o /<targetSpeakDir>/youtubeDownloadForSonos.mp4 -f best --quiet --extract-audio --audio-format mp3 $2
perl /opt/fhem/fhem.pl 7072 "set Sonos_YoutubeDummy succeeded"
perl /opt/fhem/fhem.pl 7072 "set $1 PlayURITemp <targetSpeakURL>/youtubeDownloadForSonos.mp3"

Habe ich abgelegt auf /opt/fhem/youtubeAudio/youtube.sh
Dabei müssen targetSpeakDir und targetSpeakURL aus dem Sonos Device entnommen werden. Diese sind unterschiedlich! (siehe http://www.fhemwiki.de/wiki/SONOS#Attribute_von_SONOS)
Was es mit den Befehlen für den YoutubeDummy auf sich hat erklärt sich weiter unten.

Dazu noch eine Funktion in die myUtils:
sub playYoutubeSonos($$){
my ($room, $link) = @_;
$room = makeDeviceParameter($room,"Sonos_");
fhem("\"/opt/fhem/youtubeAudio/youtube.sh $room $link\"");
}

sub makeDeviceParameter($$){
my ($device,$prefix) = @_;
if(index($device, $prefix) == -1){
$device = $prefix.$device;
}
return $device;
}

playYoutubeSonos ruft so das Shell-Skript auf, makeDeviceParameter sorgt dafür, dass man statt z.B. Sonos_Schlafzimmer auch einfach nur Schlafzimmer übergeben kann. Beispiel eines Aufrufs:
playYoutubeSonos("Schlafzimmer","https://www.youtube.com/watch?v=QH2-TGUlwu4")

Und so ist das Ganze schon erledigt, ein Aufruf der Funktion lädt herunter, konvertiert und spielt danach ab.

Die Integration in Fhem habe ich wiefolgt gestaltet:
define Sonos_YoutubeDummy dummy
attr Sonos_YoutubeDummy alias YouTube -> Sonos
attr Sonos_YoutubeDummy devStateIcon downloading:edit_settings succeeded:message_ok
attr Sonos_YoutubeDummy readingList room,link,state
attr Sonos_YoutubeDummy setList room:Schlafzimmer,Wohnzimmer link:textField
attr Sonos_YoutubeDummy webCmd room:link

define Sonos_YoutubeDownloadStart notify Sonos_YoutubeDummy:link:.* {\
playYoutubeSonos(ReadingsVal("Sonos_YoutubeDummy","room",""),ReadingsVal("Sonos_YoutubeDummy","link",""))\
}


Eventuell müssen Pfade angepasst werden. Falls der Fehler youtube-dl: not found im Log erscheint, kann man den Pfad herausfinden über: whereis youtube-dl

Vielleicht kann ja jemand etwas damit anfangen, für Kritik und Verbesserung bin ich gerne offen! Ich lasse mich nun abends vom Herrn Erik Range berieseln :D
Gruß Johannes

edit: shell-Skript mit if-Conditions erweitert, falls die Datei schon gelöscht wurde kommt somit keine Fehlermeldung
FHEM 6.0 @ IntelNUC6CAYH;  Unifi USG, Switch, AP AC Pro; HM-MOD-UART;  Sonos Play 1 & 3, One, Beam; Philips Hue