File size: 4,583 Bytes
4986f6d b245237 4986f6d b245237 4986f6d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
import asyncio
import json
from multiprocessing import Process
import os
import re
import shutil
import time
import aiofiles
import cv2
from fastapi import (
APIRouter,
Depends,
HTTPException,
UploadFile,
BackgroundTasks,
status,
)
import requests
from app import supabase
from app.dependencies import get_current_user
from app.routers.image import inferenceImage
router = APIRouter(prefix="/video", tags=["Video"])
@router.post("/{artifactId}")
async def handleVideoRequest(
artifactId: str,
file: UploadFile,
background_tasks: BackgroundTasks,
threshold: float = 0.3,
_=Depends(get_current_user),
):
if re.search("^video\/", file.content_type) is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="File must be video",
)
try:
id = str(now())
os.mkdir(id)
async with aiofiles.open(os.path.join(id, "input.mp4"), "wb") as out_file:
while content := await file.read(1024):
await out_file.write(content)
background_tasks.add_task(inferenceVideo, artifactId, id, threshold)
return id + ".mp4"
except ValueError as err:
print(err)
print("Error processing video")
shutil.rmtree(id)
def now():
return round(time.time() * 1000)
async def inferenceVideo(artifactId: str, inputDir: str, threshold: float):
try:
Process(updateArtifact(artifactId, {"status": "processing"})).start()
cap = cv2.VideoCapture(
filename=os.path.join(inputDir, "input.mp4"), apiPreference=cv2.CAP_FFMPEG
)
fps = cap.get(cv2.CAP_PROP_FPS)
size = (
int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)),
)
result = cv2.VideoWriter(
filename=os.path.join(inputDir, "out.mp4"),
fourcc=cv2.VideoWriter_fourcc(*"mp4v"),
fps=fps,
frameSize=size,
)
isFirstFrame = True
thumbnail = None
while cap.isOpened():
res, frame = cap.read()
if isFirstFrame:
isFirstFrame = False
thumbnail = frame
if res == False:
break
resFram = inferenceImage(frame, threshold)
result.write(resFram)
cap.release()
result.release()
def createThumbnail(thumbnail):
thumbnail = cv2.resize(
src=thumbnail, dsize=(160, 160), interpolation=cv2.INTER_AREA
)
cv2.imwrite(os.path.join(inputDir, "thumbnail.jpg"), thumbnail)
createThumbnail(thumbnail)
async def uploadVideo():
async with aiofiles.open(os.path.join(inputDir, "out.mp4"), "rb") as f:
supabase.storage.from_("video").upload(
inputDir + ".mp4", await f.read(), {"content-type": "video/mp4"}
)
async def uploadThumbnail():
async with aiofiles.open(
os.path.join(inputDir, "thumbnail.jpg"), "rb"
) as f:
supabase.storage.from_("thumbnail").upload(
inputDir + ".jpg", await f.read(), {"content-type": "image/jpeg"}
)
try:
n = now()
_, _ = await asyncio.gather(uploadVideo(), uploadThumbnail())
print(now() - n)
except Exception as e:
print(e)
updateArtifact(
artifactId,
{
"status": "success",
"path": "https://hdfxssmjuydwfwarxnfe.supabase.co/storage/v1/object/public/video/"
+ inputDir
+ ".mp4",
"thumbnailURL": "https://hdfxssmjuydwfwarxnfe.supabase.co/storage/v1/object/public/thumbnail/"
+ inputDir
+ ".jpg",
},
)
except:
Process(
updateArtifact(
artifactId,
{
"status": "fail",
},
)
).start()
finally:
shutil.rmtree(inputDir)
def updateArtifact(artifactId: str, body):
url = "https://firebasetot.onrender.com/artifacts/" + artifactId
payload = json.dumps(body)
headers = {"Content-Type": "application/json"}
requests.request("PATCH", url, headers=headers, data=payload)
|