import asyncio import json import uvicorn from fastapi import FastAPI import paho.mqtt.client as mqtt from pydantic import BaseModel from starlette.middleware.cors import CORSMiddleware class BaseResponse(BaseModel): code: int = 200 msg: str = "success" app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) class MQTTClient: def __init__(self, broker, port, topic, username, password): self.broker = broker self.port = port self.topic = topic self.username = username self.password = password # 千万不要指定client_id 不然死翘翘 self.client = mqtt.Client() self.client.username_pw_set(self.username, self.password) def push(self): self.client.publish(self.topic, payload=json.dumps({"msg": "open_led"}, ensure_ascii=False), qos=0) self.client.publish(self.topic, payload=json.dumps({"msg": "push_stream"}, ensure_ascii=False), qos=0) def close(self): self.client.publish(self.topic, payload=json.dumps({"msg": "close_stream"}, ensure_ascii=False), qos=0) self.client.publish(self.topic, payload=json.dumps({"msg": "close_led"}, ensure_ascii=False), qos=0) def start(self): self.client.connect(self.broker, self.port) user_sched = {} async def close(username, device): # 倒计时600秒 await asyncio.sleep(35) print(username + "结束推流") user_sched.pop(username) close_stream(username, device) async def task_start(username, device): print(username + "创建结束推流定时任务") task = asyncio.create_task(close(username, device)) user_sched[username] = task @app.get("/start/video/{username}/{device}") async def start(username, device): try: # 如果定时任务不存在,那么直接进行推流。当用户退出界面时,创建任务 if username not in user_sched: print(username + "开始推流") push_stream(username, device) # 如果定时任务存在,那么取消上次的任务。当用户退出界面时,创建任务 else: t = user_sched[username] # 取消任务 if t is not None: print(username + "取消定时任务") t.cancel() return BaseResponse(code=200, msg="success") except Exception as e: return BaseResponse(code=500, msg=str(e)) @app.get("/stop/video/{username}/{device}") async def stop(username, device): try: await task_start(username, device) return BaseResponse(code=200, msg="success") except Exception as e: return BaseResponse(code=500, msg=str(e)) def push_stream(username, device): MQTT = MQTTClient(broker, port, device, username, username) MQTT.start() MQTT.push() def close_stream(username, device): MQTT = MQTTClient(broker, port, device, username, username) MQTT.start() MQTT.close() if __name__ == '__main__': broker = 'mqtt.lihaink.cn' port = 1883 uvicorn.run(app, host="0.0.0.0", port=8000)