검색하기귀찮아서만든블로그

[python] fast api 영상 relay server 본문

개발

[python] fast api 영상 relay server

hellworld 2021. 12. 4. 09:53

[개요] 동영상을 방송으로 송출하기 위한 릴레이 서버

  • 라이브러리 : fastapi
  • client : 스트리밍 데이터를 POST 로 송신. header 에 MJPEG 이미지 구분을 위한 boundary를 제공 해야하며, MJPEG 영상 데이터를 프레임 단위로 스트림 송신해야 한다.
  • MJPEG 이미지 데이터 포맷 : --<boundary>\r\nContent-Type: image/jpeg\r\n\r\n<jpgBin>\r\n
  • 아래 코드는 테스트용 1:1 릴레이 서버 코드입니다. client 에서 수신한 영상을 브라우저로 접속한 사용자에게 전달합니다.
  • 클라이언트는 별도 개발필요
from fastapi import FastAPI 
from starlette.requests import Request
from starlette.responses import StreamingResponse

app = FastAPI()

ForwardData = bytes() # client 로 부터 수신한 MJPEG 데이터
boundary = str() # 이미지 구분용 바운더리
recving = False # 데이터 수신 상태

# client 에서 보낸 영상을 비동기로 전달하는 함수.
def getCameraStream():
    global ForwardData, recving
    while recving:
        yield (ForwardData)

# client > api 서버로 스트리밍 전송.
@app.post("/cctv")
async def cctv(requestRequest):
    global ForwardData, boundary, recving
   
    # client 에서 수신한 바운더리 값을 글로벌 변수로 저장한다.
    boundary = request.headers.get('boundary')

    # MJPEG 영상을 수신한다.
    recving = True
    async for chunk in request.stream():
        ForwardData = chunk
    recving = False

    # 영상 수신 종료.
    ForwardData=None
    return {"result""success"}

# 웹 view 용 
@app.get("/cctv")
def cctvWeb():
    #client 에서 수신한 boundary 정보와 MJPEG 영상을 스트리밍으로 송신한다.
    global boundary
    return StreamingResponse(getCameraStream(), media_type='multipart/x-mixed-replace; boundary={}'.format(boundary))