From Fastapi Import FastAPI, File,
From Fastapi Import FastAPI, File,
import shutil
import os
from datetime import datetime
import subprocess
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
import requests
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from urllib.parse import quote
import aiofiles
app = FastAPI()
FFMPEG_PATH = "ffmpeg" # Ensure ffmpeg is in your PATH or provide the full path.
# Serve the HTML file
@app.get("/", response_class=HTMLResponse)
async def get_video_recorder():
with open("index.html", "r") as file:
return file.read()
try:
# Use aiofiles to handle the file asynchronously
async with aiofiles.open(video_path, 'wb') as out_file:
# Read the file in chunks and write it to the server
while content := await video.read(1024): # 1 KB chunks
await out_file.write(content)
if response.status_code == 200:
print(f"API response: {response.json()}")
else:
print(
f"Failed to communicate with API. Status code:
{response.status_code}, Response: {response.text}")
except requests.exceptions.RequestException as e:
print(f"Error communicating with the API: {e}")
return {"message": "Snapshot uploaded successfully", "filename":
snapshot_filename}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, ssl_keyfile="key.pem",
ssl_certfile="cert.pem")
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video Recorder</title>
<link rel="stylesheet" href="/static/style.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/
css/all.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Video Recorder</h1>
<video id="video" autoplay></video>
<div class="controls">
<button id="record-btn"><i class="fa-solid fa-play"></i></button>
<button id="pause-btn" disabled><i class="fa-solid
fa-pause"></i></button>
<button id="stop-btn" disabled><i class="fa-solid
fa-stop"></i></button>
<button id="snapshot-btn"><i class="fa-solid fa-camera"></i></button>
</div>
</div>
<script>
let mediaRecorder;
let recordedChunks = [];
const videoElement = document.getElementById('video');
const recordButton = document.getElementById('record-btn');
const pauseButton = document.getElementById('pause-btn');
const stopButton = document.getElementById('stop-btn');
const snapshotButton = document.getElementById('snapshot-btn');
function takeSnapshot() {
const canvas = document.createElement('canvas');
canvas.width = 640;
canvas.height = 480;
const ctx = canvas.getContext('2d');
ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
canvas.toBlob(blob => {
const formData = new FormData();
formData.append('snapshot', blob, 'snapshot.jpg');
fetch('/upload_snapshot', { method: 'POST', body: formData });
});
}
pauseButton.addEventListener('click', () => {
if (mediaRecorder.state === 'recording') {
mediaRecorder.pause();
pauseButton.textContent = 'Resume';
} else {
mediaRecorder.resume();
pauseButton.textContent = 'Pause';
}
});
stopButton.addEventListener('click', () => {
mediaRecorder.stop();
recordButton.disabled = false;
pauseButton.disabled = true;
stopButton.disabled = true;
});
snapshotButton.addEventListener('click', takeSnapshot);
</script>
</body>
</html>