1. 项目背景与核心需求
躺在床上刷手机时突然想关掉电脑上的音乐,或者半夜发现电脑还在下载文件需要远程关机——这种场景对于现代人来说再熟悉不过。传统方案要么需要额外安装远程控制软件,要么得爬起来走到电脑前操作。而用Python+FastAPI搭建一个本地控制服务,就能用手机浏览器直接完成这些操作。
这个方案的核心优势在于:
- 零成本:完全基于开源工具,无需购买任何软件
- 低延迟:本地网络通信,响应速度在毫秒级
- 高定制性:可以自由扩展各种控制功能
- 无隐私顾虑:数据不会离开本地网络
关键技术栈选择:
- FastAPI作为Web框架:比Flask更现代的异步支持,自带API文档生成
- PyAutoGUI用于GUI自动化:支持跨平台的鼠标键盘模拟
- Uvicorn作为ASGI服务器:轻量高效,适合本地服务
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与基础搭建
2.1 Python环境配置
推荐使用Python 3.8+版本,通过venv创建隔离环境:
bash复制python -m venv control_env
source control_env/bin/activate # Linux/Mac
control_env\Scripts\activate.bat # Windows
安装依赖库:
bash复制pip install fastapi uvicorn pyautogui
2.2 基础服务框架
创建main.py作为入口文件:
python复制from fastapi import FastAPI
import pyautogui
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Control Service Ready"}
启动服务:
bash复制uvicorn main:app --reload --host 0.0.0.0 --port 8000
此时访问http://电脑IP:8000应该能看到JSON响应。--host 0.0.0.0参数允许局域网访问,--reload启用开发模式的热重载。
3. 核心功能实现
3.1 关机/重启功能
添加系统控制端点:
python复制import os
import platform
@app.get("/shutdown")
def shutdown(delay: int = 0):
"""延迟关机接口"""
if platform.system() == "Windows":
os.system(f"shutdown /s /t {delay}")
else:
os.system(f"shutdown -h +{delay//60}")
return {"status": "success", "action": "shutdown"}
@app.get("/reboot")
def reboot():
"""立即重启接口"""
if platform.system() == "Windows":
os.system("shutdown /r /t 0")
else:
os.system("reboot")
return {"status": "success", "action": "reboot"}
安全提示:
实际部署时应添加认证中间件,避免被局域网内其他设备误触发
3.2 媒体控制功能
利用PyAutoGUI模拟键盘快捷键:
python复制@app.get("/media/play-pause")
def media_play_pause():
pyautogui.press('playpause')
return {"status": "success"}
@app.get("/media/next")
def media_next():
pyautogui.press('nexttrack')
return {"status": "success"}
@app.get("/media/volume-up")
def volume_up():
pyautogui.press('volumeup')
return {"status": "success"}
# 同理实现volumedown/mute等
实测发现不同音乐软件的快捷键支持程度:
- Spotify:完美支持所有媒体键
- QQ音乐:部分版本需要窗口聚焦
- 网页版网易云:需要浏览器标签页处于激活状态
3.3 鼠标键盘控制
实现基础的远程输入:
python复制@app.get("/mouse/move")
def mouse_move(x: int, y: int):
pyautogui.moveTo(x, y)
return {"status": "success"}
@app.get("/mouse/click")
def mouse_click(button: str = "left"):
pyautogui.click(button=button)
return {"status": "success"}
@app.get("/keyboard/type")
def keyboard_type(text: str):
pyautogui.write(text)
return {"status": "success"}
注意事项:
- 坐标系统基于主显示器分辨率
- 默认有0.1秒的PyAutoGUI动作间隔
- 快速连续调用可能导致操作队列堆积
4. 安全增强与优化
4.1 基础认证中间件
添加API密钥验证:
python复制from fastapi import Security, HTTPException
from fastapi.security import APIKeyHeader
API_KEY = "your_secret_key" # 实际使用应放在环境变量中
api_key_header = APIKeyHeader(name="X-API-Key")
async def get_api_key(api_key: str = Security(api_key_header)):
if api_key != API_KEY:
raise HTTPException(
status_code=401,
detail="Invalid API Key"
)
return api_key
@app.get("/secure/shutdown")
def secure_shutdown(api_key: str = Security(get_api_key)):
return shutdown()
4.2 CORS配置
允许手机浏览器访问:
python复制from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 生产环境应限制为具体域名
allow_methods=["*"],
allow_headers=["*"],
)
4.3 服务自启动配置
Windows创建计划任务:
bash复制schtasks /create /tn "RemoteControl" /tr "uvicorn main:app --host 0.0.0.0 --port 8000" /sc onlogon /ru SYSTEM
Linux使用systemd服务:
ini复制# /etc/systemd/system/remotecontrol.service
[Unit]
Description=Remote Control Service
[Service]
ExecStart=/path/to/control_env/bin/uvicorn main:app --host 0.0.0.0 --port 8000
WorkingDirectory=/path/to/project
Restart=always
User=youruser
[Install]
WantedBy=multi-user.target
5. 前端界面优化
5.1 简易控制面板
使用HTML+JavaScript创建手机友好界面:
python复制from fastapi.staticfiles import StaticFiles
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/panel", response_class=HTMLResponse)
async def control_panel():
return """
<!DOCTYPE html>
<html>
<body>
<button onclick="fetch('/media/play-pause')">播放/暂停</button>
<button onclick="fetch('/shutdown?delay=60')">60秒后关机</button>
</body>
</html>
"""
5.2 响应式设计建议
针对手机浏览器的CSS优化:
css复制button {
padding: 15px 30px;
margin: 10px;
font-size: 1.5em;
width: 90%;
}
6. 进阶功能扩展
6.1 多电脑管理
通过配置文件支持多主机:
python复制import socket
from typing import Dict
HOSTS = {
"living_room": "192.168.1.101",
"bedroom": "192.168.1.102"
}
@app.get("/hosts")
def list_hosts():
return {"available_hosts": list(HOSTS.keys())}
@app.get("/current_host")
def get_current_host():
return {"hostname": socket.gethostname(), "ip": socket.gethostbyname(socket.gethostname())}
6.2 自动化脚本集成
支持执行预定义脚本:
python复制import subprocess
SCRIPTS_DIR = "scripts"
@app.get("/script/{script_name}")
def run_script(script_name: str):
script_path = f"{SCRIPTS_DIR}/{script_name}"
if not os.path.exists(script_path):
raise HTTPException(404, "Script not found")
result = subprocess.run(
["python", script_path],
capture_output=True,
text=True
)
return {
"returncode": result.returncode,
"stdout": result.stdout,
"stderr": result.stderr
}
7. 常见问题排查
7.1 端口冲突处理
查看占用端口的进程:
bash复制netstat -ano | findstr 8000 # Windows
lsof -i :8000 # Linux/Mac
修改启动端口:
bash复制uvicorn main:app --port 8001
7.2 PyAutoGUI安全异常
当鼠标移动到左上角时会触发安全保护,解决方法:
python复制pyautogui.FAILSAFE = False # 不推荐长期使用
# 更好的方案是控制移动范围
7.3 跨平台兼容问题
不同操作系统的命令差异处理:
python复制def shutdown_system():
system = platform.system()
if system == "Windows":
os.system("shutdown /s /t 0")
elif system == "Linux":
os.system("shutdown now")
elif system == "Darwin":
os.system("osascript -e 'tell app \"System Events\" to shut down'")
else:
raise NotImplementedError(f"Unsupported system: {system}")
8. 性能优化建议
- 启用Gzip压缩:
python复制from fastapi.middleware.gzip import GZipMiddleware
app.add_middleware(GZipMiddleware)
- 异步化CPU密集型操作:
python复制@app.get("/complex-task")
async def complex_task():
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(None, cpu_intensive_function)
return {"result": result}
- 连接复用配置:
bash复制uvicorn main:app --workers 4 # 多worker模式
实际部署后发现,在树莓派4B上单个worker就能轻松处理100+ QPS的请求负载,内存占用长期保持在50MB以下。
