Skip to content

Instantly share code, notes, and snippets.

@tjoen
Created January 23, 2018 17:29
Show Gist options
  • Save tjoen/b503c4366803e21c809a929b8d183f99 to your computer and use it in GitHub Desktop.
Save tjoen/b503c4366803e21c809a929b8d183f99 to your computer and use it in GitHub Desktop.
chromecast.sh script for mycroft use
from __future__ import print_function, unicode_literals
import os
import os.path
import time
from threading import Thread
from urllib import quote
import random
from SimpleHTTPServer import SimpleHTTPRequestHandler
from SocketServer import TCPServer
import json
import subprocess
from urlparse import urljoin
from bs4 import BeautifulSoup
import urllib2
import soco
import time
import pychromecast
# mounted usb on /media/Walkman that had MUSIC dir in it with mp3
mediadir = '/media/Walkman/MUSIC'
ipadres=subprocess.check_output(['hostname', '-I'] ).rstrip()
cnt = 0
action = "None"
port = 8000
zone_name = 'Living Room'
# Bands for the google search
bands = ['Beastie boys official','Nick Drake','Marvin Gaye live','James Brown', 'grey whistle test', 'Lowlands youtube', 'Prince','Bob Marley', 'Muse', 'Led Zeppelin', 'Howlin wolf', 'Kaiser chiefs', 'The Strokes', 'the doors live', 'Rolling stones','De jeugd van tegenwoordig', 'editors' , 'rockpalast', 'etta james']
bands2 = ['mycroft ai youtube', 'accoustic live youtube']
# index music files
music_files = []
print('Looking for music files')
for dirpath, dirnames, filenames in os.walk( mediadir ):
for filename in [f for f in filenames if f.endswith(('.mp3', '.MP3'))]:
dirpath = dirpath.replace('/media/Walkman/MUSIC', '/')
music_files.append(os.path.join(dirpath, filename))
cnt = cnt+1
print (str(cnt)+ ' files found')
#discover chromecast devices
chromecasts = pychromecast.get_chromecasts()
[cc.device.friendly_name for cc in chromecasts]
#print (str(chromecasts))
# check if we found a chromecast
if str(chromecasts) != "[]":
cast = next(cc for cc in chromecasts if cc.device.friendly_name )
# Wait for cast device to be ready
cast.wait()
print(cast.device)
print(cast.status)
mc = cast.media_controller
action = "streamchromecast"
else:
print ("No chromecast found!")
# exit(1)
# discover sonos devices
try:
zone_list = filter(None, list(soco.discover()))
except TypeError:
zone_list = ""
if zone_list == "":
print ("No sonos found!")
if action == "None":
print("No streaming devices found")
exit(1)
else:
sonos = zone_list[0]
print (zone_list)
print (sonos.player_name)
action = "streamsonos"
request_headers = {
"Accept-Language": "en-US,en;q=0.5",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Referer": "http://thewebsite.com",
"Connection": "keep-alive"
}
def google_image(x):
search = x.split()
search = '+'.join(map(str, search))
url = 'https://www.google.nl/search?as_st=y&tbm=isch&hl=nl&as_q=%s&as_epq=&as_oq=&as_eq=&cr=&as_sitesearch=&safe=active&tbs=iar:s' % search
request = urllib2.Request( url, headers=request_headers)
resp = urllib2.urlopen(request).read()
soup = BeautifulSoup(resp,"html.parser")
links = soup.find_all('div',attrs={"class" : "rg_meta notranslate"})
image = json.loads(links[0].text)
return image['ou']
def google_video(x):
search = x.split()
search = '+'.join(map(str, search))
url = 'https://www.google.nl/search?q=%s&tbm=vid&source=lnms&sa=X&ved=0ahUKEwijn4nG8YTYAhUBzaQKHUyRBBkQ_AUICygC&biw=1348&bih=643&dpr=1' % search
request = urllib2.Request( url, headers=request_headers)
resp = urllib2.urlopen(request).read()
soup = BeautifulSoup(resp,"html.parser")
links = soup.find_all('h3',attrs={"class" : "r"})
videos = []
for h3 in links:
for link in h3.find_all('a'):
if 'youtube' in link.get('href'):
videos.append( link )
return videos
def choosevideo(x):
vids = google_video(x)
vid = random.choice(vids)
link = subprocess.check_output(['youtube-dl', '-g', '-f18', vid.get('href') ] ).rstrip()
mc.play_media( link, 'video/mp4', vid.text )
print ('\n' ,vid.text )
def choosesong():
song = random.choice(music_files)
random_file = song
# urlencode all the path parts (but not the /'s)
random_file = os.path.join(
*[quote(part) for part in os.path.split(random_file)]
)
print('Playing random file:', random_file)
link = 'http://{}:{}{}'.format(ipadres, port, random_file)
base_url='http://{}:{}'.format(ipadres, port )
print ('Streaming from:', link)
songloc = mediadir+song
print ('Songloc:', songloc)
#should include metadata try
try:
jsondata=subprocess.check_output(['exiftool', '-json', songloc] )
randomsong = json.loads(jsondata)
artist = randomsong[0]['Artist']
title = randomsong[0]['Title']
genre = randomsong[0]['Genre']
title2 = artist+' - '+title+' ['+genre+']'
if randomsong[0].get('Picture'):
global cnt
cnt = cnt+1
picture = base_url+"/image.jpg?"+str(cnt)
f = open("/media/Walkman/MUSIC/image.jpg", "w")
subprocess.call(["exiftool", "-Picture", "-b" , songloc], stdout=f)
#/media/Walkman/MUSIC/image.jpg
time.sleep(2)
else:
picture = google_image(artist+" "+title)
#picture = base_url+"/thumb.png"
except subprocess.CalledProcessError as e:
title2 = song
picture = base_url+"/thumb.png?"+str(cnt)
if action == "streamsonos":
sonos.play_uri( link )
else:
mc.play_media(link, 'audio/mp3', title2 , picture)
print ( title2 )
def select():
if cnt > 0:
if random.randint(0, 1) == 1:
choosevideo(random.choice(bands))
else:
choosesong()
else:
choosevideo(random.choice(bands))
class HttpServer(Thread):
"""A simple HTTP Server in its own thread def __init__(self, port):"""
def __init__(self, port):
super(HttpServer, self).__init__()
self.daemon = True
handler = SimpleHTTPRequestHandler
self.httpd = TCPServer(( "", port), handler) #TCPServer(("", port), handler)
def run(self):
"""Start the server"""
print('Start HTTP server')
self.httpd.serve_forever()
def stop(self):
"""Stop the server"""
print('Stop HTTP server')
self.httpd.socket.close()
def add_random_file_from_present_folder(ipadres, port, zone_name):
"""Add a random non-py file from this folder and subfolders to soco"""
# Make a list of music files, right now it is done by collection all files
# below the current folder whose extension does not start with .py
# This will probably need to be modded for other pusposes.
random_file = choice(music_files)
# urlencode all the path parts (but not the /'s)
random_file = os.path.join(
*[quote(part) for part in os.path.split(random_file)]
)
print('\nPlaying random file:', random_file)
netpath = 'http://{}:{}/{}'.format(ipadres, port, random_file)
for zone in soco.discover():
if zone.player_name == zone_name:
break
number_in_queue = zone.add_uri_to_queue(netpath)
zone.play_from_queue(number_in_queue)
def main():
# Setup and start the http server
if cnt > 0:
os.chdir( mediadir )
server = HttpServer( port)
server.start()
select()
#choosevideo(random.choice(bands))
# When the http server is setup you can really add your files in
# any way that is desired. The source code for
# add_random_file_from_present_folder is just an example, but it may be
# helpful in figuring out how to format the urls
try:
while True:
time.sleep(5)
if action == "streamchromecast":
if mc.status.player_state == ('IDLE'):
select() #choosevideo(random.choice(bands))
if mc.status.player_state ==('UNKNOWN'):
select() #choosevideo(random.choice(bands))
if action == "streamsonos":
if sonos.get_current_transport_info()['current_transport_state'] == "STOPPED":
choosesong()
except KeyboardInterrupt:
if cnt > 0:
server.stop()
# os.chdir( "~" )
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment