commit b0f42c9e8f06533d27b95b54bda8fe2e6b7e8b71 Author: AlexsandrSnytkin Date: Mon Oct 7 09:51:47 2024 +0700 Init diff --git a/.idea/VideoCapture.iml b/.idea/VideoCapture.iml new file mode 100644 index 0000000..0a88826 --- /dev/null +++ b/.idea/VideoCapture.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..fc6ca88 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,32 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2d336e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..741b5f0 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..4610cf8 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..4da83fb --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1727670817034 + + + + \ No newline at end of file diff --git a/MotionDetector/motion_detection b/MotionDetector/motion_detection new file mode 160000 index 0000000..2ff71b1 --- /dev/null +++ b/MotionDetector/motion_detection @@ -0,0 +1 @@ +Subproject commit 2ff71b19839d5b0dd14c43d0fd55bd1a37abee38 diff --git a/Simple_video_register/README.md b/Simple_video_register/README.md new file mode 100644 index 0000000..2da1d9b --- /dev/null +++ b/Simple_video_register/README.md @@ -0,0 +1,15 @@ +# Multi-Camera Surveillance Project + +## Overview +This project enables you to connect up to 24 cameras, choose the grid size for video feeds dynamically, and manage the camera settings through a Vue.js frontend with a Flask backend. + +### How to Run +1. Install Docker and Docker Compose. +2. Run `docker-compose up --build` in the project directory. +3. Access the frontend at `http://localhost:8080`. +4. Access the backend API documentation at `http://localhost:5000/swagger`. + +### Features +- Add and remove cameras. +- Dynamic grid size based on the number of cameras. +- Simple motion detection placeholder (to be implemented). diff --git a/Simple_video_register/backend/Dockerfile b/Simple_video_register/backend/Dockerfile new file mode 100644 index 0000000..da4395d --- /dev/null +++ b/Simple_video_register/backend/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.11-slim + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install -r requirements.txt + +COPY . . + +CMD ["gunicorn", "-b", "0.0.0.0:5000", "app.main:app"] diff --git a/Simple_video_register/backend/app/__init__.py b/Simple_video_register/backend/app/__init__.py new file mode 100644 index 0000000..1508d48 --- /dev/null +++ b/Simple_video_register/backend/app/__init__.py @@ -0,0 +1 @@ +# Empty file to initialize the module diff --git a/Simple_video_register/backend/app/__pycache__/__init__.cpython-311.pyc b/Simple_video_register/backend/app/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..b26c633 Binary files /dev/null and b/Simple_video_register/backend/app/__pycache__/__init__.cpython-311.pyc differ diff --git a/Simple_video_register/backend/app/__pycache__/__init__.cpython-38.pyc b/Simple_video_register/backend/app/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..78e8cac Binary files /dev/null and b/Simple_video_register/backend/app/__pycache__/__init__.cpython-38.pyc differ diff --git a/Simple_video_register/backend/app/__pycache__/main.cpython-311.pyc b/Simple_video_register/backend/app/__pycache__/main.cpython-311.pyc new file mode 100644 index 0000000..b912953 Binary files /dev/null and b/Simple_video_register/backend/app/__pycache__/main.cpython-311.pyc differ diff --git a/Simple_video_register/backend/app/__pycache__/main.cpython-38.pyc b/Simple_video_register/backend/app/__pycache__/main.cpython-38.pyc new file mode 100644 index 0000000..0070ae9 Binary files /dev/null and b/Simple_video_register/backend/app/__pycache__/main.cpython-38.pyc differ diff --git a/Simple_video_register/backend/app/main.py b/Simple_video_register/backend/app/main.py new file mode 100644 index 0000000..e27aa4a --- /dev/null +++ b/Simple_video_register/backend/app/main.py @@ -0,0 +1,20 @@ +from flask import Flask +from flask_restful import Api +from flask_cors import CORS +from app.routes.camera import Camera +from app.routes.detection import Detection + +app = Flask(__name__) +CORS(app) +api = Api(app) + +# Add routes +api.add_resource(Camera, '/api/camera') +api.add_resource(Detection, '/api/detection') + +@app.route('/swagger') +def swagger_ui(): + return app.send_static_file('swagger.yaml') + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/Simple_video_register/backend/app/routes/__pycache__/camera.cpython-311.pyc b/Simple_video_register/backend/app/routes/__pycache__/camera.cpython-311.pyc new file mode 100644 index 0000000..9e3fc0e Binary files /dev/null and b/Simple_video_register/backend/app/routes/__pycache__/camera.cpython-311.pyc differ diff --git a/Simple_video_register/backend/app/routes/__pycache__/camera.cpython-38.pyc b/Simple_video_register/backend/app/routes/__pycache__/camera.cpython-38.pyc new file mode 100644 index 0000000..e7efcbf Binary files /dev/null and b/Simple_video_register/backend/app/routes/__pycache__/camera.cpython-38.pyc differ diff --git a/Simple_video_register/backend/app/routes/__pycache__/detection.cpython-311.pyc b/Simple_video_register/backend/app/routes/__pycache__/detection.cpython-311.pyc new file mode 100644 index 0000000..4fca6b5 Binary files /dev/null and b/Simple_video_register/backend/app/routes/__pycache__/detection.cpython-311.pyc differ diff --git a/Simple_video_register/backend/app/routes/__pycache__/detection.cpython-38.pyc b/Simple_video_register/backend/app/routes/__pycache__/detection.cpython-38.pyc new file mode 100644 index 0000000..059ec7c Binary files /dev/null and b/Simple_video_register/backend/app/routes/__pycache__/detection.cpython-38.pyc differ diff --git a/Simple_video_register/backend/app/routes/camera.py b/Simple_video_register/backend/app/routes/camera.py new file mode 100644 index 0000000..0e8cc93 --- /dev/null +++ b/Simple_video_register/backend/app/routes/camera.py @@ -0,0 +1,25 @@ +from flask import request, jsonify +from flask_restful import Resource + +class Camera(Resource): + cameras = [] + + def post(self): + data = request.json + rtsp_url = data.get('rtsp_url') + if len(self.cameras) < 24: + self.cameras.append({'id': len(self.cameras), 'rtsp_url': rtsp_url}) + return jsonify({"message": "Camera added", "camera_id": len(self.cameras) - 1}), 200 + else: + return jsonify({"message": "Maximum number of cameras reached"}), 400 + + def delete(self): + data = request.json + camera_id = data.get('camera_id') + if 0 <= camera_id < len(self.cameras): + self.cameras.pop(camera_id) + return jsonify({"message": "Camera removed"}), 200 + return jsonify({"message": "Camera ID not found"}), 404 + + def get(self): + return jsonify({"cameras": self.cameras}) diff --git a/Simple_video_register/backend/app/routes/detection.py b/Simple_video_register/backend/app/routes/detection.py new file mode 100644 index 0000000..5813caa --- /dev/null +++ b/Simple_video_register/backend/app/routes/detection.py @@ -0,0 +1,6 @@ +from flask_restful import Resource + +class Detection(Resource): + def get(self): + # Placeholder for motion and abandoned object detection + return {"message": "Detection logic not implemented"}, 200 diff --git a/Simple_video_register/backend/app/routes/motion_detector.py b/Simple_video_register/backend/app/routes/motion_detector.py new file mode 100644 index 0000000..cb1d7b8 --- /dev/null +++ b/Simple_video_register/backend/app/routes/motion_detector.py @@ -0,0 +1,22 @@ +import cv2 + +class MotionDetector: + def __init__(self): + self.previous_frame = None + + def detect_motion(self, frame): + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + gray = cv2.GaussianBlur(gray, (21, 21), 0) + + if self.previous_frame is None: + self.previous_frame = gray + return False + + frame_diff = cv2.absdiff(self.previous_frame, gray) + thresh = cv2.threshold(frame_diff, 25, 255, cv2.THRESH_BINARY)[1] + thresh = cv2.dilate(thresh, None, iterations=2) + + contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + self.previous_frame = gray + + return len(contours) > 0 diff --git a/Simple_video_register/backend/app/video_stream.py b/Simple_video_register/backend/app/video_stream.py new file mode 100644 index 0000000..2d7003b --- /dev/null +++ b/Simple_video_register/backend/app/video_stream.py @@ -0,0 +1,12 @@ +import cv2 + +class VideoStream: + def __init__(self, rtsp_url): + self.rtsp_url = rtsp_url + self.stream = cv2.VideoCapture(rtsp_url) + + def get_frame(self): + ret, frame = self.stream.read() + if not ret: + return None + return frame diff --git a/Simple_video_register/backend/requirements.txt b/Simple_video_register/backend/requirements.txt new file mode 100644 index 0000000..3693255 --- /dev/null +++ b/Simple_video_register/backend/requirements.txt @@ -0,0 +1,8 @@ +Flask +flask-restful +opencv-python-headless +numpy +flask-cors +gunicorn +sqlalchemy +pymysql diff --git a/Simple_video_register/backend/tests/__pycache__/test_app.cpython-311-pytest-8.2.2.pyc b/Simple_video_register/backend/tests/__pycache__/test_app.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000..c38e39f Binary files /dev/null and b/Simple_video_register/backend/tests/__pycache__/test_app.cpython-311-pytest-8.2.2.pyc differ diff --git a/Simple_video_register/backend/tests/test_app.py b/Simple_video_register/backend/tests/test_app.py new file mode 100644 index 0000000..bdd137d --- /dev/null +++ b/Simple_video_register/backend/tests/test_app.py @@ -0,0 +1,60 @@ +import pytest +from app import app, db, VideoLog, MotionEvent, LeftItemEvent + + +@pytest.fixture +def client(): + app.config['TESTING'] = True + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + + with app.test_client() as client: + with app.app_context(): + db.create_all() + yield client + + with app.app_context(): + db.drop_all() + + +def test_start_stream(client): + response = client.post('/video/start_stream/camera1', json={'rtsp_url': 'rtsp://example.com/stream'}) + assert response.status_code == 200 + assert b'stream started' in response.data + + +def test_stop_stream(client): + client.post('/video/start_stream/camera1', json={'rtsp_url': 'rtsp://example.com/stream'}) + response = client.post('/video/stop_stream/camera1') + assert response.status_code == 200 + assert b'stream stopped' in response.data + + +def test_video_logs(client): + log = VideoLog(camera_id='camera1', event_type='motion', video_path='path/to/video.mp4') + db.session.add(log) + db.session.commit() + + response = client.get('/video/video_logs') + assert response.status_code == 200 + assert b'camera1' in response.data + + +def test_motion_events(client): + event = MotionEvent(camera_id='camera1', description='Motion detected', video_path='path/to/video.mp4') + db.session.add(event) + db.session.commit() + + response = client.get('/video/motion_events') + assert response.status_code == 200 + assert b'camera1' in response.data + + +def test_left_item_events(client): + event = LeftItemEvent(camera_id='camera1', item_description='Item left', video_path='path/to/video.mp4') + db.session.add(event) + db.session.commit() + + response = client.get('/video/left_item_events') + assert response.status_code == 200 + assert b'camera1' in response.data diff --git a/Simple_video_register/docker-compose-prod.yaml b/Simple_video_register/docker-compose-prod.yaml new file mode 100644 index 0000000..e65da29 --- /dev/null +++ b/Simple_video_register/docker-compose-prod.yaml @@ -0,0 +1,11 @@ +version: '3.7' + +services: + + frontend: + container_name: frontend + build: + context: ./frontend + dockerfile: Dockerfile-prod + ports: + - '80:80' \ No newline at end of file diff --git a/Simple_video_register/docker-compose.yaml b/Simple_video_register/docker-compose.yaml new file mode 100644 index 0000000..ee77cd4 --- /dev/null +++ b/Simple_video_register/docker-compose.yaml @@ -0,0 +1,17 @@ +version: '3.8' +services: + backend: + build: ./backend + ports: + - "5000:5000" + volumes: + - ./backend:/app + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + volumes: + - './frontend:/src' + - '/src/node_modules' + ports: + - "80:80" diff --git a/Simple_video_register/frontend/.dockerignore b/Simple_video_register/frontend/.dockerignore new file mode 100644 index 0000000..8824953 --- /dev/null +++ b/Simple_video_register/frontend/.dockerignore @@ -0,0 +1,3 @@ +node_modules +.git +.gitignore \ No newline at end of file diff --git a/Simple_video_register/frontend/Dockerfile b/Simple_video_register/frontend/Dockerfile new file mode 100644 index 0000000..70e2118 --- /dev/null +++ b/Simple_video_register/frontend/Dockerfile @@ -0,0 +1,16 @@ +# base image +FROM node:12.2.0-alpine + +# set working directory +WORKDIR /src + +# add `/app/node_modules/.bin` to $PATH +ENV key=/src/node_modules/.bin:$PATH + +# install and cache app dependencies +COPY package.json /src/package.json +RUN npm install +RUN npm install @vue/cli@3.7.0 -g + +# start app +CMD ["npm", "run", "serve"] \ No newline at end of file diff --git a/Simple_video_register/frontend/Dockerfile-prod b/Simple_video_register/frontend/Dockerfile-prod new file mode 100644 index 0000000..9997d1d --- /dev/null +++ b/Simple_video_register/frontend/Dockerfile-prod @@ -0,0 +1,15 @@ +# build environment +FROM node:12.2.0-alpine +WORKDIR /src +ENV key=/src/node_modules/.bin:$PATH +COPY package.json /app/package.json +RUN npm install --silent +RUN npm install @vue/cli@3.7.0 -g +COPY . /app +RUN npm run build + +# production environment +FROM nginx:1.16.0-alpine +COPY --from=build /app/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/Simple_video_register/frontend/package.json b/Simple_video_register/frontend/package.json new file mode 100644 index 0000000..09351ac --- /dev/null +++ b/Simple_video_register/frontend/package.json @@ -0,0 +1,18 @@ +{ + "name": "frontend", + "version": "1.0.0", + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build" + }, + "dependencies": { + "axios": "^0.21.1", + "core-js": "^3.6.5", + "vue": "^2.6.11" + }, + "devDependencies": { + "@vue/cli-service": "^4.5.0", + "vue-template-compiler": "^2.5.17" + } + } + \ No newline at end of file diff --git a/Simple_video_register/frontend/src/App.vue b/Simple_video_register/frontend/src/App.vue new file mode 100644 index 0000000..198599c --- /dev/null +++ b/Simple_video_register/frontend/src/App.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/Simple_video_register/frontend/src/components/CameraGrid.vue b/Simple_video_register/frontend/src/components/CameraGrid.vue new file mode 100644 index 0000000..ab94acc --- /dev/null +++ b/Simple_video_register/frontend/src/components/CameraGrid.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/Simple_video_register/frontend/src/components/CameraView.vue b/Simple_video_register/frontend/src/components/CameraView.vue new file mode 100644 index 0000000..90a62f6 --- /dev/null +++ b/Simple_video_register/frontend/src/components/CameraView.vue @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/Simple_video_register/frontend/src/components/Settings.vue b/Simple_video_register/frontend/src/components/Settings.vue new file mode 100644 index 0000000..1ba253e --- /dev/null +++ b/Simple_video_register/frontend/src/components/Settings.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/Simple_video_register/frontend/src/main.js b/Simple_video_register/frontend/src/main.js new file mode 100644 index 0000000..77f35b6 --- /dev/null +++ b/Simple_video_register/frontend/src/main.js @@ -0,0 +1,8 @@ +import Vue from 'vue'; +import App from './App.vue'; + +Vue.config.productionTip = false; + +new Vue({ + render: h => h(App), +}).$mount('#app'); diff --git a/Simple_video_register/nginx/nginx.conf b/Simple_video_register/nginx/nginx.conf new file mode 100644 index 0000000..758a646 --- /dev/null +++ b/Simple_video_register/nginx/nginx.conf @@ -0,0 +1,17 @@ +server { + + listen 80; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + error_page 500 502 503 504 /50x.html; + + location = /50x.html { + root /usr/share/nginx/html; + } + +} \ No newline at end of file diff --git a/Stream_System/.github/workflows/ci.yml b/Stream_System/.github/workflows/ci.yml new file mode 100644 index 0000000..bf89f44 --- /dev/null +++ b/Stream_System/.github/workflows/ci.yml @@ -0,0 +1,44 @@ +name: CI Pipeline + +on: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Python dependencies + run: | + cd backend + pip install -r requirements.txt + + - name: Run backend tests + run: | + cd backend + pytest + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Install frontend dependencies + run: | + cd frontend + npm install + + - name: Run frontend tests + run: | + cd frontend + npm run test diff --git a/Stream_System/backend/Dockerfile b/Stream_System/backend/Dockerfile new file mode 100644 index 0000000..083fc0c --- /dev/null +++ b/Stream_System/backend/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11-slim +WORKDIR /app +COPY . . +RUN pip install -r requirements.txt +EXPOSE 5000 +CMD ["python", "app.py"] diff --git a/Stream_System/backend/app.py b/Stream_System/backend/app.py new file mode 100644 index 0000000..2b623fc --- /dev/null +++ b/Stream_System/backend/app.py @@ -0,0 +1,45 @@ +from flask import Flask, Response, request, jsonify +from camera import Camera +from database import log_event, get_all_events +import threading + +app = Flask(__name__) + +# Хранилище камер и событий детекции +cameras = {} +motion_detected = [] + +@app.route('/add_camera', methods=['POST']) +def add_camera(): + camera_id = request.json['id'] + if camera_id not in cameras: + cameras[camera_id] = Camera(camera_id) + threading.Thread(target=cameras[camera_id].start_stream, args=(motion_detected,)).start() + return jsonify({"message": "Camera added"}), 200 + return jsonify({"message": "Camera already exists"}), 400 + +@app.route('/remove_camera', methods=['POST']) +def remove_camera(): + camera_id = request.json['id'] + if camera_id in cameras: + cameras[camera_id].stop_stream() + del cameras[camera_id] + return jsonify({"message": "Camera removed"}), 200 + return jsonify({"message": "Camera not found"}), 404 + +@app.route('/stream/') +def stream(camera_id): + if camera_id in cameras: + return Response(cameras[camera_id].get_frame(), mimetype='multipart/x-mixed-replace; boundary=frame') + return "Camera not found", 404 + +@app.route('/events', methods=['GET']) +def get_events(): + return jsonify(get_all_events()), 200 + +@app.route('/motion', methods=['GET']) +def motion(): + return jsonify(motion_detected), 200 + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/Stream_System/backend/camera.py b/Stream_System/backend/camera.py new file mode 100644 index 0000000..8d9b0e7 --- /dev/null +++ b/Stream_System/backend/camera.py @@ -0,0 +1,36 @@ +import cv2 +from motion_detection import detect_motion +from database import log_event + +class Camera: + def __init__(self, camera_id, source=0): + self.camera_id = camera_id + self.capture = cv2.VideoCapture(source) + self.is_running = True + + def start_stream(self): + background_frame = None + while self.is_running: + ret, frame = self.capture.read() + if not ret: + break + + if background_frame is None: + background_frame = frame + + moving_objects = detect_motion(frame, background_frame) + if moving_objects: + log_event(self.camera_id, moving_objects) + + def get_frame(self): + while self.is_running: + ret, frame = self.capture.read() + if ret: + _, buffer = cv2.imencode('.jpg', frame) + frame = buffer.tobytes() + yield (b'--frame\r\n' + b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n') + + def stop_stream(self): + self.is_running = False + self.capture.release() diff --git a/Stream_System/backend/database.py b/Stream_System/backend/database.py new file mode 100644 index 0000000..106167e --- /dev/null +++ b/Stream_System/backend/database.py @@ -0,0 +1,19 @@ +import sqlite3 +from datetime import datetime + +def log_event(camera_id, objects): + conn = sqlite3.connect('events.db') + c = conn.cursor() + for obj in objects: + c.execute("INSERT INTO events (camera_id, timestamp, object) VALUES (?, ?, ?)", + (camera_id, datetime.now(), str(obj))) + conn.commit() + conn.close() + +def get_all_events(): + conn = sqlite3.connect('events.db') + c = conn.cursor() + c.execute("SELECT * FROM events") + events = c.fetchall() + conn.close() + return events diff --git a/Stream_System/backend/motion_detection.py b/Stream_System/backend/motion_detection.py new file mode 100644 index 0000000..ff5eec3 --- /dev/null +++ b/Stream_System/backend/motion_detection.py @@ -0,0 +1,15 @@ +import cv2 + +def detect_motion(frame, background_frame): + diff = cv2.absdiff(background_frame, frame) + gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) + blur = cv2.GaussianBlur(gray, (5, 5), 0) + _, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY) + contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + + moving_objects = [] + for contour in contours: + if cv2.contourArea(contour) > 500: + x, y, w, h = cv2.boundingRect(contour) + moving_objects.append((x, y, w, h)) + return moving_objects diff --git a/Stream_System/backend/requirements.txt b/Stream_System/backend/requirements.txt new file mode 100644 index 0000000..5867b6d --- /dev/null +++ b/Stream_System/backend/requirements.txt @@ -0,0 +1,2 @@ +Flask +opencv-python \ No newline at end of file diff --git a/Stream_System/docker-compose.yml b/Stream_System/docker-compose.yml new file mode 100644 index 0000000..cdd5f6e --- /dev/null +++ b/Stream_System/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3' +services: + backend: + build: ./backend + ports: + - "5000:5000" + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + volumes: + - './frontend:/src' + - '/src/node_modules' + ports: + - "80:80" + db: + image: postgres + environment: + POSTGRES_USER: user + POSTGRES_PASSWORD: password + ports: + - "5432:5432" + prometheus: + image: prom/prometheus + ports: + - "9090:9090" + grafana: + image: grafana/grafana + ports: + - "3000:3000" diff --git a/Stream_System/frontend/Dockerfile b/Stream_System/frontend/Dockerfile new file mode 100644 index 0000000..2dcef51 --- /dev/null +++ b/Stream_System/frontend/Dockerfile @@ -0,0 +1,28 @@ +# FROM node:14-alpine +# WORKDIR /app +# COPY . . +# RUN npm install +# RUN npm run build +# EXPOSE 8080 +# CMD ["npm", "run", "serve"] + + +# base image +FROM node:12.2.0-alpine + +# set working directory +WORKDIR /src + +# add `/app/node_modules/.bin` to $PATH +ENV key=/src/node_modules/.bin:$PATH + +# install and cache app dependencies +COPY package.json /src/package.json +RUN npm install +RUN npm install @vue/cli@3.7.0 -g +RUN npm run build + +EXPOSE 80 + +# start app +CMD ["npm", "run", "serve"] \ No newline at end of file diff --git a/Stream_System/frontend/package.json b/Stream_System/frontend/package.json new file mode 100644 index 0000000..3debfc1 --- /dev/null +++ b/Stream_System/frontend/package.json @@ -0,0 +1,12 @@ +{ + "name": "camera-stream", + "version": "1.0.0", + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build" + }, + "dependencies": { + "vue": "^2.6.12" + } + } + \ No newline at end of file diff --git a/Stream_System/frontend/src/App.vue b/Stream_System/frontend/src/App.vue new file mode 100644 index 0000000..aad989f --- /dev/null +++ b/Stream_System/frontend/src/App.vue @@ -0,0 +1,60 @@ + + + + + + \ No newline at end of file diff --git a/Stream_System/frontend/src/components/CameraBlock.vue b/Stream_System/frontend/src/components/CameraBlock.vue new file mode 100644 index 0000000..0800e1d --- /dev/null +++ b/Stream_System/frontend/src/components/CameraBlock.vue @@ -0,0 +1,48 @@ + + + + + + \ No newline at end of file diff --git a/Stream_System/frontend/src/components/CameraControl.vue b/Stream_System/frontend/src/components/CameraControl.vue new file mode 100644 index 0000000..50b1038 --- /dev/null +++ b/Stream_System/frontend/src/components/CameraControl.vue @@ -0,0 +1,23 @@ + + + + \ No newline at end of file diff --git a/Stream_System/frontend/src/components/CameraGrid.vue b/Stream_System/frontend/src/components/CameraGrid.vue new file mode 100644 index 0000000..0e10fae --- /dev/null +++ b/Stream_System/frontend/src/components/CameraGrid.vue @@ -0,0 +1,57 @@ + + + + + + \ No newline at end of file diff --git a/Stream_System/frontend/src/components/CameraView.vue b/Stream_System/frontend/src/components/CameraView.vue new file mode 100644 index 0000000..2d8fb1f --- /dev/null +++ b/Stream_System/frontend/src/components/CameraView.vue @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/Stream_System/frontend/src/main.js b/Stream_System/frontend/src/main.js new file mode 100644 index 0000000..dcd0325 --- /dev/null +++ b/Stream_System/frontend/src/main.js @@ -0,0 +1,6 @@ +import Vue from 'vue' +import App from './App.vue' + +new Vue({ + render: h => h(App), +}).$mount('#app') diff --git a/VideoRegister b/VideoRegister new file mode 160000 index 0000000..7c0d239 --- /dev/null +++ b/VideoRegister @@ -0,0 +1 @@ +Subproject commit 7c0d239e48a11cb620fe18eb10e9750c181a6134