Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
275c3b5
v0.1.3-alpha
KiriChen-Wind Apr 22, 2026
5fe79ae
Add files via upload
KiriChen-Wind Apr 22, 2026
8f3ec62
更新 README.md
KiriChen-Wind Apr 22, 2026
fc854fb
更新 README.md
KiriChen-Wind Apr 22, 2026
abc4a68
Update README.md
KiriChen-Wind Apr 22, 2026
4893ad0
更新 README.md
KiriChen-Wind Apr 22, 2026
0ed5bd7
Update README.md
KiriChen-Wind Apr 23, 2026
ecd1ae5
Update README.md
KiriChen-Wind Apr 23, 2026
86e4260
Update README.md
KiriChen-Wind Apr 23, 2026
a63a432
更新 README.md
KiriChen-Wind Apr 23, 2026
39666fe
更新 README.md
KiriChen-Wind Apr 23, 2026
579fe27
更新 README.md
KiriChen-Wind Apr 23, 2026
9ac6872
更新 README.md
KiriChen-Wind Apr 23, 2026
b6c86a9
Update README.md
KiriChen-Wind Apr 23, 2026
9d8a2f5
Update README.md
KiriChen-Wind Apr 23, 2026
04f4bfc
Update README.md
KiriChen-Wind Apr 23, 2026
a7ff848
Update project files
KiriChen-Wind Apr 26, 2026
b901eb2
v0.2.1-alpha
KiriChen-Wind Apr 26, 2026
c4f8b39
v0.2.1-alpha
KiriChen-Wind Apr 26, 2026
70c1ab5
docker合并
KiriChen-Wind Apr 26, 2026
0cfa37b
Update README.md
KiriChen-Wind Apr 26, 2026
a08e3c2
v0.2.1-alpha
KiriChen-Wind Apr 26, 2026
291c078
Merge branch 'main' of https://github.com/KiriChen-Wind/MiAir
KiriChen-Wind Apr 26, 2026
fe3c480
fix deploy
KiriChen-Wind Apr 26, 2026
258e6f6
修复ip判断逻辑
KiriChen-Wind Apr 26, 2026
265ad38
我也不知道修了什么
KiriChen-Wind Apr 26, 2026
4d6c466
修复配置保存与ip判断
KiriChen-Wind Apr 26, 2026
f951ca7
修复配置持久性
KiriChen-Wind Apr 26, 2026
4946f3f
问题修复
KiriChen-Wind Apr 26, 2026
09ec6fd
Update README.md
KiriChen-Wind Apr 26, 2026
7e14556
Update README.md
KiriChen-Wind Apr 26, 2026
65efe94
Update README.md
KiriChen-Wind Apr 26, 2026
639e777
移除AirPlay非线性音量调节
KiriChen-Wind Apr 26, 2026
c6b802b
Merge branch 'main' of https://github.com/KiriChen-Wind/MiAir
KiriChen-Wind Apr 26, 2026
db62810
重新加回非线性音量调节
KiriChen-Wind Apr 26, 2026
a003194
Delete .gitignore
KiriChen-Wind May 2, 2026
9780f04
修复容器重启逻辑
KiriChen-Wind May 2, 2026
623c215
Merge branch 'main' of https://github.com/KiriChen-Wind/MiAir
KiriChen-Wind May 2, 2026
56f15f7
v0.3.1-alpha
KiriChen-Wind May 2, 2026
1025bae
v0.3.1-alpha
KiriChen-Wind May 2, 2026
b058354
v0.3.1-alpha
KiriChen-Wind May 2, 2026
d8fedc2
v0.3.1-alpha
KiriChen-Wind May 2, 2026
f87d071
v0.3.1-alpha
KiriChen-Wind May 2, 2026
ab392ad
Refactor get_lan_ip function for IP retrieval
lyj0309 May 4, 2026
c02ae26
Merge pull request #15 from lyj0309/patch-1
KiriChen-Wind May 4, 2026
d01ac3d
Create build.yml
autunn May 4, 2026
7b6373a
Update Dockerfile
autunn May 4, 2026
54e9b6b
Merge branch 'main' of https://github.com/autunn/MiAir
autunn May 4, 2026
0710fef
Update Dockerfile
autunn May 4, 2026
25f174b
v0.3.7-alpha
KiriChen-Wind May 6, 2026
fd1b3fc
Merge branch 'main' of https://github.com/KiriChen-Wind/MiAir
KiriChen-Wind May 6, 2026
eb7ad8a
v0.3.7-alpha
KiriChen-Wind May 6, 2026
1019fb6
v0.3.7-alpha
KiriChen-Wind May 6, 2026
a30b6d9
v0.3.7-alpha
KiriChen-Wind May 6, 2026
d19d3bb
v0.3.7-alpha
KiriChen-Wind May 6, 2026
e593be1
v0.3.7-alpha
KiriChen-Wind May 6, 2026
2dc269d
v0.3.7-alpha
KiriChen-Wind May 6, 2026
65d74b2
v0.3.7-alpha
KiriChen-Wind May 6, 2026
7100959
Merge pull request #16 from autunn/main
KiriChen-Wind May 6, 2026
ad80d76
Delete .github/workflows/build.yml
SyunSS May 7, 2026
b731a0d
Add files via upload
SyunSS May 7, 2026
ee64fc9
Merge pull request #21 from SyunSS/main
KiriChen-Wind May 7, 2026
987829e
Update const.py
autunn May 10, 2026
ad72dcb
Update config.py
autunn May 10, 2026
06bb983
Update config.py
autunn May 10, 2026
9f3e9ec
Merge pull request #23 from autunn/main
KiriChen-Wind May 10, 2026
06402f1
Update build.yml
SyunSS May 11, 2026
3793fb2
Add files via upload
SyunSS May 11, 2026
49b47ff
Delete .github/workflows/docker.yml
SyunSS May 11, 2026
ba93afd
Merge pull request #24 from SyunSS/main
KiriChen-Wind May 11, 2026
2c7ee8b
v0.3.7-alpha
KiriChen-Wind May 12, 2026
b86e5b5
Merge branch 'main' of https://github.com/KiriChen-Wind/MiAir
KiriChen-Wind May 12, 2026
958d4be
v0.5.3-alpha
KiriChen-Wind May 12, 2026
1a162ed
v0.5.3-alpha
KiriChen-Wind May 12, 2026
4a0bc28
v0.5.3-alpha
KiriChen-Wind May 12, 2026
04fe6b0
v0.5.4-alpha
KiriChen-Wind May 13, 2026
56e3031
Add files via upload
SyunSS May 13, 2026
9db27a3
v0.7.4-alpha
KiriChen-Wind May 24, 2026
2551c1c
v0.7.4-alpha
KiriChen-Wind May 24, 2026
eba4a4e
Add Web logo
KiriChen-Wind May 24, 2026
1bbfd3f
Merge branch 'main' of https://github.com/KiriChen-Wind/MiAir
KiriChen-Wind May 24, 2026
06d41ac
fix: AirPlay jitter buffer rewrite — NTP clock sync, timestamp-based …
KiriChen-Wind May 24, 2026
704a146
v0.8.1-alpha
KiriChen-Wind May 24, 2026
da133a2
v0.8.1-alpha
KiriChen-Wind May 24, 2026
1061442
v0.8.1-alpha
KiriChen-Wind May 24, 2026
4982724
v0.7.4-alpha
KiriChen-Wind May 24, 2026
e40e31a
Merge branch 'KiriChen-Wind:main' into main
SyunSS May 24, 2026
28c0a27
v0.8.5-alpha
KiriChen-Wind May 26, 2026
8d0c696
Merge branch 'main' of https://github.com/KiriChen-Wind/MiAir
actions-user May 27, 2026
5a69a19
Update auto-sync-fork.yml
SyunSS May 31, 2026
58a510c
Update auto-sync-fork.yml
SyunSS Jun 25, 2026
51f208b
Delete .github/workflows/auto-sync-fork.yml
SyunSS Jun 25, 2026
2985b48
修复前端路径,保证在反代下的正常使用
bangbang23333 Jun 27, 2026
0df7f72
Merge pull request #31 from bangbang23333/fix-frontend-relative-path
KiriChen-Wind Jun 28, 2026
8b2d756
Add gitignore.
HenryzhaoH Jul 4, 2026
55f7ac2
Mask Xiaomi account crenditials in settings API response.
HenryzhaoH Jul 4, 2026
b0d088b
Fix display issue for masked userid.
HenryzhaoH Jul 4, 2026
9254cd9
Mask devices payload in API return only required fields.
HenryzhaoH Jul 4, 2026
71b7783
Merge branch 'KiriChen-Wind:main' into main
SyunSS Jul 10, 2026
c259d71
Merge pull request #34 from HenryzhaoH/main
KiriChen-Wind Jul 10, 2026
0c8eb42
fix(airplay): 修复流停止后死循环重连与本地调试多网卡 IP 选取问题
nifan950624 Jul 17, 2026
87c8c11
Merge pull request #38 from nifan950624/fix/airplay-stream-stop-and-m…
KiriChen-Wind Jul 17, 2026
625f6bc
Merge branch 'KiriChen-Wind:main' into main
SyunSS Jul 17, 2026
8efee66
Fix LAN IP selection for multi-network hosts
SyunSS Aug 5, 2026
3038fbc
Merge pull request #1 from SyunSS/fix/ip-selection-multinetwork
SyunSS Aug 5, 2026
84bb79f
Merge pull request #41 from SyunSS/main
KiriChen-Wind Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# MiAir Docker 部署配置
# 复制此文件为 .env 并填入实际值

# 小米账号 (手机号或邮箱)
MI_USER=

# 小米密码
MI_PASS=

# 设备 DID (可选,留空则自动搜索)
# 多个设备用逗号分隔
MI_DID=

# 局域网 IP (通常自动检测,如有需要可手动指定)
# 例如:192.168.1.1
# HOST_IP=192.168.1.1
65 changes: 65 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Build and Push MiAir Docker Image

on:
push:
branches:
- docker
- main
paths-ignore:
- '**.md'
- 'docs/**'
- '.gitignore'
- '.env.example'
- 'LICENSE'
- '*.png'
- '*.sh'
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/miair

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v4

- name: Set up QEMU (multi-arch support)
uses: docker/setup-qemu-action@v3

- uses: docker/setup-buildx-action@v3

- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- uses: docker/metadata-action@v5
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix=,format=short
type=raw,value=latest
type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/') }}

- uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BUILD_DATE=${{ github.event.head_commit.timestamp }}
VCS_REF=${{ github.sha }}
39 changes: 6 additions & 33 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,33 +1,6 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.egg-info/
dist/
build/
*.egg

# IDE
.vscode/
.idea/
*.swp
*.swo

# 配置与敏感信息
conf/config.json
conf/.mi.token
conf/*.log
conf/*.log.*

# 运行时产物
*.log
*.pcm
nul

# 系统文件
.DS_Store
Thumbs.dbf

*.exe


.env

# Python byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class
30 changes: 30 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Repository Instructions

## Project Shape
- Python package `miair` plus top-level launcher `miair.py`; installed CLI entrypoint is `miair = miair.cli:main`.
- `miair.app.MiAir` wires the app: Web UI/API starts first, then DLNA and AirPlay start only when Xiaomi account/cookie and `mi_did` are configured.
- Major protocol code lives under `miair/dlna/` and `miair/airplay/`; Web API routes and settings masking live in `miair/web/api.py`.

## Commands
- Runtime requires Python `>=3.10` per `pyproject.toml`; README says Python 3.12+ for Windows usage.
- Install editable package/deps with `python3 -m pip install -e .` before importing modules or running tests; `miair.py` auto-installs runtime deps only when launched directly.
- Start locally with `python3 miair.py` or `python3 miair.py --conf-path conf --web-port 8300 --dlna-port 8200`.
- Run the existing test script with `python3 tests/test_audio_seek.py`; this is not a pytest-configured repo and `pytest` is not declared as a dependency.
- Focused pytest-style execution may still work if pytest is installed: `python3 -m pytest tests/test_audio_seek.py -k detect_audio_format`.

## Runtime And Config
- Config is loaded from `<conf-path>/config.json`; relative `--conf-path` is normalized to an absolute path in `Config.load`.
- Env fallback names are `MI_USER`, `MI_PASS`, and `MI_DID`; `MIAIR_HOSTNAME` explicitly overrides saved `hostname`, while `HOST_IP` in `.env.example` is only a commented hint and is not read by `Config`.
- Default ports are DLNA HTTP `8200` and Web UI/API `8300`; Docker exposes both and runs with host networking.
- Secrets/cookies must stay masked in API responses; preserve `_mask_cookie`, `_unmask_cookie`, and `_mask_devices` behavior when touching settings endpoints.

## Docker And Deploy
- CI only builds/pushes Docker images on `main`, `docker`, or manual dispatch; Markdown, docs, shell scripts, `.env.example`, `.gitignore`, license, and PNG changes are ignored by the workflow.
- The checked-in `Dockerfile` copies `config-example.json` and `.env.example` into the image, seeds `/app/conf/config.json` and `/app/conf/.env` if absent, then runs `python miair.py --conf-path /app/conf`.
- `deploy.sh` is interactive and root-only; it rewrites `Dockerfile` via heredoc, builds `miair:latest`, mounts a user-selected config directory to `/app/conf`, and starts container `miair` with `--network=host` and `--restart unless-stopped`.
- `manage.sh update` downloads `main.tar.gz`, rebuilds the image, removes the existing container, then re-runs `deploy.sh`; avoid assuming it is a non-interactive update path.

## Testing Quirks
- `tests/test_audio_seek.py` imports production modules and needs runtime dependencies such as `miservice-fork`, `aiohttp`, `zeroconf`, `pycryptodome`, and `av` installed.
- ffmpeg-dependent portions of the test script are best-effort: they skip or warn when ffmpeg is unavailable; pure-Python seek tests should still run once Python deps are installed.
- The current macOS system Python in this workspace is 3.9.6, below the project requirement, so use a Python 3.10+ interpreter for meaningful verification.
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM python:3.12-slim

LABEL maintainer="MiAir"
LABEL description="DLNA/AirPlay receiver for Xiaomi AI Speaker"

RUN apt-get update && apt-get install -y --no-install-recommends \
ffmpeg \
libportaudio2 \
dnsutils \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY pyproject.toml .
RUN pip install --no-cache-dir . --root-user-action=ignore

# 这里明确把示例配置文件也拷贝进镜像的备用区
COPY config-example.json .env.example ./
COPY miair.py ./
COPY miair/ ./miair/

RUN mkdir -p /app/conf

EXPOSE 8200 8300

# 【核心修改】智能启动命令:
# 1. 检查 /app/conf/config.json 是否存在,不存在就复制一份示例文件过去
# 2. 检查 /app/conf/.env 是否存在,不存在也复制过去
# 3. 最后使用 exec 移交进程控制权并启动真正的 Python 服务
ENTRYPOINT ["/bin/sh", "-c", "if [ ! -f /app/conf/config.json ]; then cp /app/config-example.json /app/conf/config.json; fi && if [ ! -f /app/conf/.env ]; then cp /app/.env.example /app/conf/.env; fi && exec python miair.py --conf-path /app/conf"]
49 changes: 44 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,61 @@
**[XiaoMusic](https://github.com/hanxi/xiaomusic "XiaoMusic")** &ensp; **[AirPlay2 Receiver](https://github.com/openairplay/airplay2-receiver "AirPlay2 Receiver")** &ensp; **[MaCast](https://github.com/xfangfang/Macast "MaCast")**

## 快速开始

## Windows
*确保设备已安装 Python 3.12+*

前往Release页面下载最新版本\
进入项目目录,使用终端执行
```python
python miair.py
```
程序将自动安装相关依赖库,请确保网络畅通
程序将自动安装相关依赖库,请确保网络畅通\
安装完成后访问 `http://主机IP:8300` 即可打开 Web 管理界面。

## Docker (Thanks @SyunSS)

支持平台:Linux / OpenWrt / macOS

### 使用脚本部署
```bash
# 安装 Git
opkg update
opkg install git
opkg install git-http

# 克隆项目
rm -rf MiAir # 如果是更新,需要清理旧的部署目录
git clone https://github.com/KiriChen-Wind/MiAir.git
cd MiAir

# 赋予权限并运行安装脚本
chmod +x deploy.sh manage.sh
./deploy.sh
```

安装完成后访问 `http://容器宿主机IP:8300` 即可打开 Web 管理界面。
请确保容器网络为Host。\
请确保 Docker 容器重启策略设定为 Unless Stopped。\
部分情况下,修改配置后容器可能无法自动重启,请手动重启容器。


### Docker 相关命令
```bash
docker logs -f miair # 查看日志
docker stop miair # 停止
docker start miair # 启动
docker restart miair # 重启
```

## 我们
**[需要帮助&交流&测试版本发布](https://qun.qq.com/universal-share/share?ac=1&authKey=1zXhx2zxgw9GG2mkecypT9clD7q0B3W3l4K0D4fQirmpDWakz0Oy2BI3ocDrgzbh&busi_data=eyJncm91cENvZGUiOiI3NDEyNjcyOTgiLCJ0b2tlbiI6InYwbitXQTF5cE9MaUJCR0hMUk03OWV0WkFoMThxbjJRaWI4dHVlbUpGdW5OdEZBVEpXMXF0T1dQUnRmRXRzYVgiLCJ1aW4iOiIxODQxOTM4MDQwIn0%3D&data=_OrA-eASJMwYwx-Uj-BReC1Xh3zGAdkn8CQskbEsQ5S66bhqvvO6dJ-QrSlRl-Ks00l5XDw1FANE8Um0w5yB8Q&svctype=4&tempid=h5_group_info "需要帮助&交流&测试版本发布")**

### 后续 可能 添加的功能
## 后续 可能 添加的功能

- 支持 Docker 部署
- ~~支持 Docker 部署~~ ✅ 已支持
- 支持 OpenWrt 部署
- ~~支持 MacOS 部署~~
- ......


[![preview](https://raw.githubusercontent.com/KiriChen-Wind/MiAir/main/preview.png "preview")](https://raw.githubusercontent.com/KiriChen-Wind/MiAir/main/preview.png "preview")
[![preview](https://raw.githubusercontent.com/KiriChen-Wind/MiAir/main/preview.png "preview")](https://raw.githubusercontent.com/KiriChen-Wind/MiAir/main/preview.png "preview")
Loading