from fastapi import FastAPI, File, UploadFile
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()
# Serve static files (like CSS)
app.mount("/static", StaticFiles(directory="static"), name="static")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Or specify the allowed domains
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
DESKTOP_DIR = r"\\192.168.10.215\Users\Klajdi\Desktop\New folder"
os.makedirs(DESKTOP_DIR, exist_ok=True)
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()
# Endpoint to upload video (timestamped filename)
@app.post("/upload_video")
async def upload_video(video: UploadFile = File(...)):
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") # Timestamp for
filenames
video_filename = f"video_{timestamp}.mp4" # Add timestamp to video filename
video_path = os.path.join(DESKTOP_DIR, video_filename) # Save to desktop
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)
# Ensure the file was saved correctly
if os.path.exists(video_path):
print(f"File {video_filename} saved successfully.")
else:
print(f"Error: File {video_filename} not saved.")
# Communicate with the external API if needed
encoded_file_path = quote(video_path)
api_url = f"http://192.168.88.150:5000/convert?
file_path={encoded_file_path}"
# Send the file to the external API
response = requests.get(api_url)
if response.status_code == 200:
print(f"API response: {response.json()}")
else:
print(f"API Error: {response.status_code} - {response.text}")
except Exception as e:
return {"message": f"An error occurred while uploading the video:
{str(e)}"}
return {"message": "Video uploaded successfully", "filename": video_filename}
# Endpoint to upload snapshot (timestamped filename)
@app.post("/upload_snapshot")
async def upload_snapshot(snapshot: UploadFile = File(...)):
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") # Timestamp for
filenames
snapshot_filename = f"screenshot_{timestamp}.jpg" # Add timestamp to snapshot
filename
snapshot_path = os.path.join(DESKTOP_DIR, snapshot_filename) # Save to desktop
with open(snapshot_path, "wb") as buffer:
shutil.copyfileobj(snapshot.file, buffer)
try:
from urllib.parse import quote
encoded_file_path = quote(snapshot_path)
api_url = f"http://192.168.88.150:5000/convert?
file_path={encoded_file_path}"
response = requests.get(api_url)
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');
async function setupCamera() {
try {
// Request both video and audio permissions
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 1920, height: 1080 }, // Set video resolution
to 1280x720
audio: true // Optionally request audio as well if needed
});
videoElement.srcObject = stream;
videoElement.width = 1920; // Set video element width
videoElement.height = 1080; // Set video element height
return stream;
} catch (error) {
console.error('Camera permission denied:', error);
alert('Camera permission denied. Please allow camera access.');
}
}
async function startRecording(stream) {
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = event =>
recordedChunks.push(event.data);
mediaRecorder.onstop = () => {
const blob = new Blob(recordedChunks, { type: 'video/mp4' });
const formData = new FormData();
formData.append('video', blob, 'recorded_video.mp4');
fetch('/upload_video', { method: 'POST', body: formData });
recordedChunks = [];
};
mediaRecorder.start();
}
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 });
});
}
recordButton.addEventListener('click', async () => {
const stream = await setupCamera();
await startRecording(stream);
recordButton.disabled = true;
pauseButton.disabled = false;
stopButton.disabled = false;
});
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>