-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update server files and recordings directory
- Loading branch information
1 parent
1ce13b8
commit 9a8fcbc
Showing
18 changed files
with
339 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import json | ||
import logging | ||
import os | ||
import time | ||
from datetime import datetime | ||
import picamera | ||
import RPi.GPIO as GPIO | ||
from dotenv import load_dotenv | ||
import websocket | ||
import threading | ||
import io | ||
import base64 | ||
|
||
# ... [Your existing setup code goes here] ... | ||
|
||
# Initialize the camera | ||
camera = picamera.PiCamera() | ||
recording = False | ||
|
||
# Set up WebSocket | ||
ws = None | ||
|
||
def send_frame(): | ||
global ws | ||
while True: | ||
if ws: | ||
stream = io.BytesIO() | ||
camera.capture(stream, format='jpeg') | ||
stream.seek(0) | ||
frame = stream.read() | ||
frame_base64 = base64.b64encode(frame).decode('utf-8') | ||
ws.send(frame_base64) | ||
stream.close() | ||
time.sleep(0.1) # Adjust frame rate | ||
|
||
def on_open(new_ws): | ||
global ws | ||
ws = new_ws | ||
send_frame_thread = threading.Thread(target=send_frame) | ||
send_frame_thread.start() | ||
|
||
def start_websocket(): | ||
websocket.enableTrace(True) | ||
ws_app = websocket.WebSocketApp("ws://localhost:3000", on_open=on_open) | ||
ws_app.run_forever() | ||
|
||
# Start WebSocket in a separate thread | ||
websocket_thread = threading.Thread(target=start_websocket) | ||
websocket_thread.start() | ||
|
||
# Your existing GPIO and recording logic goes here | ||
# ... | ||
|
||
try: | ||
# Your existing loop logic goes here | ||
# ... | ||
except KeyboardInterrupt: | ||
# Your existing KeyboardInterrupt handling goes here | ||
# ... | ||
finally: | ||
GPIO.cleanup() | ||
if ws: | ||
ws.close() |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.video-grid { | ||
display: grid; | ||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); | ||
gap: 10px; | ||
padding: 20px; | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
document.addEventListener('DOMContentLoaded', () => { | ||
fetch('/video-list') | ||
.then(response => response.json()) | ||
.then(videos => { | ||
const container = document.querySelector('.video-grid'); | ||
videos.forEach(video => { | ||
const videoElement = document.createElement('video'); | ||
videoElement.width = 320; // set your dimensions | ||
videoElement.height = 240; | ||
videoElement.controls = true; | ||
|
||
const sourceElement = document.createElement('source'); | ||
sourceElement.src = `recordings/${video}`; | ||
sourceElement.type = 'video/mp4'; | ||
|
||
videoElement.appendChild(sourceElement); | ||
container.appendChild(videoElement); | ||
}); | ||
}) | ||
.catch(error => console.error('Error fetching video list:', error)); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,16 @@ | ||
const canvas = document.getElementById('videoCanvas'); | ||
const context = canvas.getContext('2d'); | ||
document.addEventListener('DOMContentLoaded', () => { | ||
const navItems = document.querySelectorAll('.nav-item'); | ||
|
||
const ws = new WebSocket('ws://localhost:3000'); | ||
ws.binaryType = 'blob'; | ||
navItems.forEach(item => { | ||
const navLink = item.querySelector('.nav-link'); | ||
let currentHref = window.location.href; | ||
|
||
ws.onmessage = function (event) { | ||
const blob = new Blob([event.data], { type: 'image/jpeg' }); | ||
if (currentHref.endsWith('/')) { | ||
currentHref += 'index.html'; | ||
} | ||
|
||
const url = URL.createObjectURL(blob); | ||
|
||
const image = new Image(); | ||
image.onload = function () { | ||
context.drawImage(this, 0, 0, canvas.width, canvas.height); | ||
URL.revokeObjectURL(url); | ||
}; | ||
image.src = url; | ||
}; | ||
if (navLink.href === currentHref) { | ||
navLink.classList.add('active'); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
const canvas = document.getElementById('videoCanvas'); | ||
const context = canvas.getContext('2d'); | ||
|
||
const ws = new WebSocket('ws://localhost:3000'); | ||
ws.binaryType = 'blob'; | ||
|
||
let python_connected = false; | ||
|
||
ws.onopen = function () { | ||
const clientInfo = { | ||
type: 'Browser', | ||
userAgent: navigator.userAgent | ||
}; | ||
ws.send(JSON.stringify(clientInfo)); | ||
showMessageOnCanvas("Searching for stream..."); | ||
}; | ||
|
||
ws.onmessage = function (event) { | ||
if (event.data === 'PYTHON_CONNECTED') { | ||
console.log('Python script connected'); | ||
python_connected = true; | ||
} else if (event.data === 'PYTHON_DISCONNECTED') { | ||
console.log('Python script disconnected'); | ||
python_connected = false; | ||
setTimeout(() => showMessageOnCanvas("Stream disconnected. Waiting for stream..."), 2000); | ||
} else if (python_connected) { | ||
const blob = new Blob([event.data], { type: 'image/jpeg' }); | ||
const url = URL.createObjectURL(blob); | ||
const image = new Image(); | ||
image.onload = function () { | ||
context.drawImage(this, 0, 0, canvas.width, canvas.height); | ||
URL.revokeObjectURL(url); | ||
}; | ||
image.src = url; | ||
} | ||
}; | ||
|
||
ws.onclose = function () { | ||
console.log('WebSocket connection closed'); | ||
} | ||
|
||
function showMessageOnCanvas(message) { | ||
context.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas | ||
context.font = '40px Arial'; // Set font size and style | ||
context.fillStyle = 'black'; // Set font color | ||
context.textAlign = 'center'; // Align text to center | ||
context.fillText(message, canvas.width / 2, canvas.height / 2); // Draw text on canvas | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Security Cam Webserver</title> | ||
<link rel="stylesheet" href="css/style.css"> | ||
<link rel="stylesheet" href="css/recordings.css"> | ||
<script src="./js/script.js"></script> | ||
</head> | ||
|
||
<body> | ||
<nav class="navbar"> | ||
<ul class="navbar-nav"> | ||
<li class="nav-item"><a class="nav-link" href="./index.html">Home</a></li> | ||
<li class="nav-item"><a class="nav-link" href="./recordings.html">Recordings</a></li> | ||
<li class="nav-item"><a class="nav-link" href="./settings.html">Settings</a></li> | ||
|
||
</ul> | ||
</nav> | ||
|
||
<div class="main-content"> | ||
<h1>Recordings</h1> | ||
<div class="video-grid"></div> | ||
</div> | ||
<script src="./js/playback.js"></script> | ||
</body> | ||
|
||
</html> |
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Security Cam Webserver</title> | ||
<link rel="stylesheet" href="css/style.css"> | ||
<link rel="stylesheet" href="css/settings.css"> | ||
<script src="./js/script.js"></script> | ||
</head> | ||
|
||
<body> | ||
<nav class="navbar"> | ||
<ul class="navbar-nav"> | ||
<li class="nav-item"><a class="nav-link" href="./index.html">Home</a></li> | ||
<li class="nav-item"><a class="nav-link" href="./recordings.html">Recordings</a></li> | ||
<li class="nav-item"><a class="nav-link" href="./settings.html">Settings</a></li> | ||
</ul> | ||
</nav> | ||
|
||
<div class="main-content"> | ||
<h1>Settings</h1> | ||
</div> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,80 @@ | ||
const express = require('express'); | ||
const http = require('http'); | ||
const WebSocket = require('ws'); | ||
const fs = require('fs'); | ||
const app = express(); | ||
const port = 3000; | ||
|
||
// Serve static files from the 'public' directory | ||
app.use(express.static('public')); | ||
|
||
// Create an HTTP server | ||
const server = http.createServer(app); | ||
|
||
// Create a WebSocket server | ||
const wss = new WebSocket.Server({ server }); | ||
|
||
let connectedClients = 0; | ||
let clients = {}; | ||
|
||
// Handle WebSocket connection | ||
wss.on('connection', function connection(ws) { | ||
connectedClients++; | ||
console.log('A new client connected! Total clients:', connectedClients); | ||
let clientId; | ||
|
||
ws.on('message', function incoming(data) { | ||
if (connectedClients > 1) { | ||
// Broadcast the received data (video frame) to all connected clients | ||
wss.clients.forEach(function each(client) { | ||
if (client !== ws && client.readyState === WebSocket.OPEN) { | ||
client.send(data); | ||
} | ||
}); | ||
if (!clientId) { | ||
clientId = data.toString(); | ||
clients[clientId] = ws; | ||
updateClients(); | ||
return; | ||
} | ||
|
||
// Regular message handling | ||
broadcastData(data, ws); | ||
}); | ||
|
||
ws.on('close', () => { | ||
connectedClients--; | ||
console.log('Client disconnected. Total clients:', connectedClients); | ||
delete clients[clientId]; | ||
updateClients(); | ||
}); | ||
}); | ||
|
||
// Notify all clients about Python script connection status | ||
function updateClients() { | ||
const isPythonConnected = !!clients['Python Script']; | ||
const isBrowserConnected = Object.keys(clients).some(id => id !== 'Python Script'); | ||
|
||
if (clients['Python Script']) { | ||
// Tell the Python script to start/stop sending frames based on browser connection | ||
const message = isBrowserConnected ? 'START' : 'STOP'; | ||
clients['Python Script'].send(message); | ||
} | ||
|
||
// Notify all browsers about Python script connection status | ||
Object.keys(clients).forEach(clientId => { | ||
if (clientId !== 'Python Script') { | ||
const message = isPythonConnected ? 'PYTHON_CONNECTED' : 'PYTHON_DISCONNECTED'; | ||
clients[clientId].send(message); | ||
} | ||
}); | ||
} | ||
|
||
// Broadcast data to all clients except sender | ||
function broadcastData(data, senderWs) { | ||
Object.values(clients).forEach(client => { | ||
if (client !== senderWs && client.readyState === WebSocket.OPEN) { | ||
client.send(data); | ||
} | ||
}); | ||
} | ||
|
||
// endpoint to get list of video files on server | ||
app.get('/video-list', (req, res) => { | ||
const recordingsPath = './public/recordings' | ||
fs.readdir(recordingsPath, (err, files) => { | ||
if (err) { | ||
res.status(500).send('Error reading video files'); | ||
return; | ||
} | ||
res.json(files.filter(file => file.endsWith('.mp4') || file.endsWith('.h264'))); | ||
}); | ||
}); | ||
|
||
// Start the server | ||
// start server | ||
server.listen(port, () => { | ||
console.log(`Server running on http://localhost:${port}`); | ||
}); |
Oops, something went wrong.