Homeassistant设置小米音响自动播放本地音乐

一、安装HACS:

步骤略,自行解决,网上安装方式很多。

二、安装小米集成

在HACS中安装Xiaomi Miot Auto9(小米集成)

三、构建随机播放py程序

3.1 利用ssh进入系统,在homeassistant文件夹新建www文件夹,在www文件夹里面新建music用于存放要播放的音乐。

3.2 在music文件夹新建文件musicServerForXioai.py,然后将下面代码复制进去。

3.3 修改代码中存音乐的目录,将music这个文件夹绝对路径填入。

# coding=utf-8

# http随机音乐播放器
# 给小爱音箱用于播放nas的音乐

import os, random, urllib, posixpath, shutil, subprocess
from http.server import HTTPServer, BaseHTTPRequestHandler

# 端口号
port = 8080

# 存音乐的目录,实际存放music的地方,后面有介绍。
fileDir = '/www/music/'

# 实时转码需要依赖ffmpeg的路径 如果为空就不转码
ffmpeg = '/usr/bin/ffmpeg'

fileList = None
fileIndex = 0

def updateFileList():
    global fileList
    global fileIndex
    try:
        os.chdir(fileDir)
    except Exception as e:
        print(e)
        print('ERROR: 请检查目录是否存在或是否有权限访问')
        exit()
    fileIndex = 0
    fileList = list(filter(lambda x: x.lower().split('.')[-1] in ['flac','mp3','wav','aac','m4a'], os.listdir('.')))
    fileList.sort(key=lambda x: os.path.getmtime(x))
    fileList.reverse()
    print(str(len(fileList)) + ' files')

# 在类的顶部添加一个计数器变量
playlist_request_count = 0

class meHandler(BaseHTTPRequestHandler):
    def translate_path(self, path):
        path = path.split('?',1)[0]
        path = path.split('#',1)[0]
        trailing_slash = path.rstrip().endswith('/')
        try:
            path = urllib.parse.unquote(path, errors='surrogatepass')
        except UnicodeDecodeError:
            path = urllib.parse.unquote(path)
        path = posixpath.normpath(path)
        words = path.split('/')
        words = filter(None, words)
        path = fileDir
        for word in words:
            if os.path.dirname(word) or word in (os.curdir, os.pardir):
                continue
            path = os.path.join(path, word)
        if trailing_slash:
            path += '/'
        return path

    def return302(self, filename):
        self.send_response(302)
        self.send_header('Location', '/' + urllib.parse.quote(filename))
        self.end_headers()

    def do_GET(self):
        global fileList
        global fileIndex
        global playlist_request_count

        print(self.path)
        if self.path == '/':
            self.return302(fileList[fileIndex])
            fileIndex += 1
            if fileIndex >= len(fileList):
                fileIndex = 0
        elif self.path == '/random':
            updateFileList()
            random.shuffle(fileList)
            self.return302(fileList[0])
            fileIndex = 1
        elif self.path == '/first':
            updateFileList()
            self.return302(fileList[0])
            fileIndex = 1
        elif self.path == '/playlist':
            playlist_request_count += 0
            if playlist_request_count <= 10:
                updateFileList()
                random.shuffle(fileList)  # 在生成播放列表前随机打乱音乐文件列表
                self.send_response(200)
                self.send_header("Content-type", "application/vnd.apple.mpegurl")
                self.send_header("Cache-Control", "no-cache")
                self.end_headers()

                m3u8_content = "#EXTM3U\n"
                m3u8_content += "#EXT-X-VERSION:3\n"
                m3u8_content += "#EXT-X-ALLOW-CACHE:NO\n"
                m3u8_content += "#EXT-X-TARGETDURATION:3\n"

                # 使用打乱后的音乐文件列表生成播放列表
                for i, file_name in enumerate(fileList):
                    if os.path.isfile(file_name):
                        m3u8_content += f"#EXTINF:3.000,\n{urllib.parse.quote(file_name)}\n"

                m3u8_content += "#EXT-X-ENDLIST\n"

                self.wfile.write(m3u8_content.encode())
            else:
                self.send_response(500)
                self.send_header("Content-type", "text/plain")
                self.end_headers()
                self.wfile.write("Too many playlist requests".encode())
        else:
            path = self.translate_path(self.path)
            print(path)
            if os.path.isfile(path):
                self.send_response(200)
                if ffmpeg and path.lower().split('.')[-1] not in ['wav']:
                    self.send_header("Content-type", 'audio/wav')
                    self.send_header("Accept-Ranges", "none")  # Ensure that the server doesn't support byte ranges
                    self.end_headers()
                    pipe = subprocess.Popen([ffmpeg, '-i', path, '-f', 'wav', '-'], stdout=subprocess.PIPE, bufsize=10 ** 8)
                    try:
                        shutil.copyfileobj(pipe.stdout, self.wfile)
                    finally:
                        self.wfile.flush()
                        pipe.terminate()
                else:
                    self.send_header("Content-type", 'audio/mpeg')
                    self.send_header("Accept-Ranges", "none")  # Ensure that the server doesn't support byte ranges
                    with open(path, 'rb') as f:
                        self.send_header("Content-Length", str(os.fstat(f.fileno())[6]))
                        self.end_headers()
                        shutil.copyfileobj(f, self.wfile)
            else:
                self.send_response(404)
                self.end_headers()

if os.system("nslookup op.lan"):
    print('ERROR: 请将op.lan指向本机ip,否则小爱音箱可能无法访问')
updateFileList()
HTTPServer(("", port), meHandler).serve_forever()

四、启动py

4.1 创建的Shell脚本,代码如下。

#!/bin/bash
##进入music文件夹
cd ****/www/music

##启动py程序
./musicServerForXioai.py

4.2 要执行Shell脚本,首先需要给予文件执行权限,可以使用命令chmod +x script.sh来设置,script.sh为创建的文件名。

4.3 之后,可以通过./script.sh或者sh script.sh来运行脚本,然后开启以及后台运行以及开机启动。

五、测试播放列表

浏览器访问 http://你的IP地址:8080/playlist,你会得到一个,3u8的文件,反复测试多次,每次下载的播放列表歌曲顺序都不一样

六、在homeassistant中设置场景自动化

测试步骤:开发者工具–服务–play media-选择实体-ID为链接地址,选择播放

添加自动化步骤:配置–自动化与场景–创建自动化–添加动作–填写相关内容,如下图。

目标:选择小米音响

内容ID:就是homeassistant的ip地址加上/playlist

内容类型:必须是music

图片[1]-Homeassistant设置小米音响自动播放本地音乐-YZJIA
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
交流 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容