from flask import Flask, render_template, Response, request
import cv2
import torch
from ultralytics import YOLO
from Utils import LIVE, MODEL, CLASSES, annotate, recorder
from Src import recognize_color, chooseOne, recognize_violation

app = Flask(__name__)

model = YOLO(MODEL)

def generate_frames(video_path):
    cap = cv2.VideoCapture(video_path)

    line_height = {'n': 0, 'x': 0, 'sum': 0, 'mean': 0}
    veh_set = torch.empty(0)

    while cap.isOpened():
        success, frame = cap.read()
        if not success:
            break

        if frame.shape[0] > 720:
            scale_factor = 720 / frame.shape[0]
            frame = cv2.resize(frame, None, fx=scale_factor, fy=scale_factor)

        result = model.track(frame, persist=True, classes=[n for n in CLASSES])[0]
        if result is not None and hasattr(result, 'boxes'):
            result = result.boxes.data
        else:
            result = torch.empty((0,))

        traffic_lights = result[result[:, -1] == 9] if len(result) > 0 else torch.empty((0,))
        vehicles = result[result[:, -1] != 9] if len(result) > 0 else torch.empty((0,))

        light_colors = recognize_color(frame, traffic_lights, print_info=False)
        chosen = chooseOne(light_colors)

        annotate(frame, traffic_lights, recognizedColor=light_colors)

        raw, pos, veh_set, violator = recognize_violation(
            frame, vehicles, traffic_lights[chosen[0]][:4] if len(traffic_lights) > 0 else [],
            line_height, veh_set, imaginary_line=True
        )

        if torch.any(violator):
            annotate(frame, violator, violationMode=True)

        _, buffer = cv2.imencode('.jpg', frame)
        frame_bytes = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')

    cap.release()

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload():
    if 'file' not in request.files:
        return "No file uploaded", 400

    file = request.files['file']
    if file.filename == '':
        return "No selected file", 400

    file_path = "static/uploaded_video.mp4"
    file.save(file_path)

    return Response(generate_frames(file_path), mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(debug=True)




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>YOLO Video Processing</title>
</head>
<body>
    <h2>Upload a Video for Object Detection</h2>
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" required>
        <button type="submit">Upload & Process</button>
    </form>
    <h2>Live Processed Video</h2>
    <img src="{{ url_for('upload') }}" width="720px">
</body>
</html>


can u please use the below code in the index,html page which is above designed 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TrafficEye - AI Traffic Violation Detection</title>
    <style>
        :root {
            --primary: #3498db;
            --secondary: #2c3e50;
            --success: #2ecc71;
            --danger: #e74c3c;
            --warning: #f39c12;
            --light: #ecf0f1;
            --dark: #2c3e50;
        }
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background-color: #f5f7fa;
            color: #333;
        }
        
        header {
            background: linear-gradient(135deg, var(--secondary), var(--primary));
            color: white;
            padding: 1.5rem 2rem;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 2rem;
        }
        
        .logo {
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 1.8rem;
            font-weight: 700;
        }
        
        .logo-icon {
            display: inline-block;
            width: 40px;
            height: 40px;
            background-color: white;
            border-radius: 50%;
            position: relative;
        }
        
        .logo-icon::before {
            content: "";
            position: absolute;
            top: 10px;
            left: 10px;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background-color: var(--primary);
        }
        
        .logo-icon::after {
            content: "";
            position: absolute;
            top: 15px;
            left: 15px;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background-color: white;
        }
        
        .subtitle {
            font-size: 1rem;
            font-weight: 400;
            opacity: 0.8;
            margin-top: 0.5rem;
        }
        
        .upload-container {
            background: white;
            border-radius: 10px;
            padding: 2rem;
            margin: 2rem 0;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
            text-align: center;
            border: 2px dashed #ddd;
            transition: all 0.3s ease;
        }
        
        .upload-container:hover {
            border-color: var(--primary);
        }
        
        .upload-container.dragging {
            background-color: rgba(52, 152, 219, 0.05);
            border-color: var(--primary);
        }
        
        .upload-icon {
            font-size: 3rem;
            color: var(--primary);
            margin-bottom: 1rem;
        }
        
        .upload-text {
            font-size: 1.2rem;
            color: #666;
            margin-bottom: 1rem;
        }
        
        .upload-btn {
            background-color: var(--primary);
            color: white;
            border: none;
            padding: 0.8rem 2rem;
            font-size: 1rem;
            border-radius: 5px;
            cursor: pointer;
            transition: all 0.3s ease;
            margin-top: 1rem;
            font-weight: 600;
        }
        
        .upload-btn:hover {
            background-color: #2980b9;
            transform: translateY(-2px);
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
        }
        
        #file-input {
            display: none;
        }
        
        .stats-container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 1.5rem;
            margin: 2rem 0;
        }
        
        .stat-card {
            background: white;
            border-radius: 10px;
            padding: 1.5rem;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
            text-align: center;
            transition: all 0.3s ease;
        }
        
        .stat-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
        }
        
        .stat-icon {
            font-size: 2rem;
            margin-bottom: 1rem;
        }
        
        .stat-value {
            font-size: 2.5rem;
            font-weight: 700;
            margin-bottom: 0.5rem;
            color: var(--secondary);
        }
        
        .stat-label {
            font-size: 1rem;
            color: #777;
        }
        
        .video-container {
            display: flex;
            flex-direction: column;
            gap: 1.5rem;
            margin: 2rem 0;
        }
        
        .video-display {
            background-color: #222;
            border-radius: 10px;
            position: relative;
            overflow: hidden;
            aspect-ratio: 16/9;
            width: 100%;
            display: none;
        }
        
        .video-display video {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }
        
        .video-display.active {
            display: block;
        }
        
        .detection-info {
            background: white;
            border-radius: 10px;
            padding: 1.5rem;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
            display: none;
        }
        
        .detection-info.active {
            display: block;
        }
        
        .detection-title {
            font-size: 1.5rem;
            margin-bottom: 1rem;
            color: var(--secondary);
            border-bottom: 2px solid #f1f1f1;
            padding-bottom: 0.5rem;
        }
        
        .detection-list {
            list-style: none;
            margin: 1rem 0;
        }
        
        .detection-item {
            display: flex;
            justify-content: space-between;
            padding: 0.8rem;
            border-bottom: 1px solid #f1f1f1;
            font-size: 1rem;
        }
        
        .detection-item:last-child {
            border-bottom: none;
        }
        
        .detection-label {
            font-weight: 600;
            color: var(--secondary);
        }
        
        .detection-value {
            color: #555;
        }
        
        .detection-red {
            color: var(--danger);
        }
        
        .detection-yellow {
            color: var(--warning);
        }
        
        .detection-green {
            color: var(--success);
        }
        
        .control-panel {
            display: flex;
            flex-wrap: wrap;
            gap: 1rem;
            margin-top: 1rem;
        }
        
        .control-btn {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.5rem;
            background-color: white;
            color: var(--secondary);
            border: 1px solid #ddd;
            padding: 0.6rem 1.2rem;
            font-size: 0.9rem;
            border-radius: 5px;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .control-btn:hover {
            background-color: #f9f9f9;
        }
        
        .control-btn.primary {
            background-color: var(--primary);
            color: white;
            border: none;
        }
        
        .control-btn.primary:hover {
            background-color: #2980b9;
        }
        
        .processing-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.7);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 1000;
            display: none;
        }
        
        .processing-overlay.active {
            display: flex;
        }
        
        .spinner {
            width: 50px;
            height: 50px;
            border: 5px solid rgba(255, 255, 255, 0.3);
            border-radius: 50%;
            border-top-color: var(--primary);
            animation: spin 1s ease-in-out infinite;
            margin-bottom: 1rem;
        }
        
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
        
        .processing-text {
            color: white;
            font-size: 1.2rem;
            font-weight: 500;
        }
        
        .progress-bar {
            width: 300px;
            height: 10px;
            background-color: rgba(255, 255, 255, 0.2);
            border-radius: 5px;
            margin-top: 1rem;
            overflow: hidden;
        }
        
        .progress-bar-inner {
            height: 100%;
            width: 0%;
            background-color: var(--primary);
            border-radius: 5px;
            transition: width 0.3s ease;
        }
        
        .dashboard {
            display: grid;
            grid-template-columns: 3fr 1fr;
            gap: 1.5rem;
            margin: 2rem 0;
        }
        
        @media (max-width: 768px) {
            .dashboard {
                grid-template-columns: 1fr;
            }
        }
        
        .violation-list {
            background: white;
            border-radius: 10px;
            padding: 1.5rem;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
            max-height: 500px;
            overflow-y: auto;
        }
        
        .violation-title {
            font-size: 1.3rem;
            margin-bottom: 1rem;
            color: var(--secondary);
            border-bottom: 2px solid #f1f1f1;
            padding-bottom: 0.5rem;
        }
        
        .violation-item {
            display: flex;
            gap: 1rem;
            padding: 1rem;
            border-bottom: 1px solid #f1f1f1;
            transition: all 0.3s ease;
            cursor: pointer;
        }
        
        .violation-item:hover {
            background-color: #f9f9f9;
        }
        
        .violation-thumbnail {
            width: 100px;
            height: 60px;
            background-color: #eee;
            border-radius: 5px;
            overflow: hidden;
        }
        
        .violation-thumbnail img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        .violation-info {
            flex: 1;
        }
        
        .violation-time {
            font-size: 0.8rem;
            color: #888;
            margin-bottom: 0.3rem;
        }
        
        .violation-type {
            font-weight: 600;
            color: var(--danger);
        }
        
        .credit {
            text-align: center;
            padding: 2rem 0;
            color: #888;
            font-size: 0.9rem;
        }
        
        .credit a {
            color: var(--primary);
            text-decoration: none;
        }
        
        .credit a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <header>
        <div class="container">
            <div class="logo">
                <span class="logo-icon"></span>
                TrafficEye
            </div>
            <div class="subtitle">AI-Powered Traffic Violation Detection System</div>
        </div>
    </header>
    
    <div class="container">
        <div class="upload-container" id="upload-area">
            <div class="upload-icon">📹</div>
            <h2 class="upload-text">Drag and drop your traffic video file here</h2>
            <p>or</p>
            <input type="file" id="file-input" accept="video/*">
            <button class="upload-btn" id="upload-btn">Choose a file</button>
        </div>
        
        <div class="stats-container">
            <div class="stat-card">
                <div class="stat-icon" style="color: var(--danger);">🚫</div>
                <div class="stat-value" id="total-violations">0</div>
                <div class="stat-label">Violations Detected</div>
            </div>
            <div class="stat-card">
                <div class="stat-icon" style="color: var(--primary);">🚗</div>
                <div class="stat-value" id="total-vehicles">0</div>
                <div class="stat-label">Vehicles Tracked</div>
            </div>
            <div class="stat-card">
                <div class="stat-icon" style="color: var(--success);">🚦</div>
                <div class="stat-value" id="traffic-lights">0</div>
                <div class="stat-label">Traffic Lights Detected</div>
            </div>
        </div>
        
        <div class="dashboard">
            <div class="video-container">
                <div class="video-display" id="video-display">
                    <video id="output-video" controls></video>
                </div>
                
                <div class="detection-info" id="detection-info">
                    <h3 class="detection-title">Detection Information</h3>
                    <ul class="detection-list">
                        <li class="detection-item">
                            <span class="detection-label">Video Duration:</span>
                            <span class="detection-value" id="video-duration">0:00</span>
                        </li>
                        <li class="detection-item">
                            <span class="detection-label">Current Traffic Light:</span>
                            <span class="detection-value" id="traffic-light-status">N/A</span>
                        </li>
                        <li class="detection-item">
                            <span class="detection-label">Vehicles in Frame:</span>
                            <span class="detection-value" id="vehicles-in-frame">0</span>
                        </li>
                        <li class="detection-item">
                            <span class="detection-label">Processing Status:</span>
                            <span class="detection-value" id="processing-status">Ready</span>
                        </li>
                    </ul>
                    
                    <div class="control-panel">
                        <button class="control-btn" id="pause-btn">
                            <span>⏸️</span> Pause
                        </button>
                        <button class="control-btn" id="frame-btn">
                            <span>⏭️</span> Next Frame
                        </button>
                        <button class="control-btn primary" id="download-btn">
                            <span>📥</span> Download Results
                        </button>
                    </div>
                </div>
            </div>
            
            <div class="violation-list" id="violation-list">
                <h3 class="violation-title">Violation Events</h3>
                <div id="violations-container">
                    <!-- Violation items will be dynamically added here -->
                    <div class="no-violations" id="no-violations" style="text-align: center; padding: 2rem 0; color: #888;">
                        No violations detected yet
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <div class="processing-overlay" id="processing-overlay">
        <div class="spinner"></div>
        <div class="processing-text">Processing Video...</div>
        <div class="progress-bar">
            <div class="progress-bar-inner" id="progress-bar"></div>
        </div>
    </div>
    
    <footer class="credit">
        <p>Powered by YOLO v8 and Computer Vision Technology</p>
    </footer>

    <script>
        // DOM Elements
        const uploadArea = document.getElementById('upload-area');
        const fileInput = document.getElementById('file-input');
        const uploadBtn = document.getElementById('upload-btn');
        const videoDisplay = document.getElementById('video-display');
        const outputVideo = document.getElementById('output-video');
        const detectionInfo = document.getElementById('detection-info');
        const processingOverlay = document.getElementById('processing-overlay');
        const progressBar = document.getElementById('progress-bar');
        const totalViolations = document.getElementById('total-violations');
        const totalVehicles = document.getElementById('total-vehicles');
        const trafficLights = document.getElementById('traffic-lights');
        const videoDuration = document.getElementById('video-duration');
        const trafficLightStatus = document.getElementById('traffic-light-status');
        const vehiclesInFrame = document.getElementById('vehicles-in-frame');
        const processingStatus = document.getElementById('processing-status');
        const pauseBtn = document.getElementById('pause-btn');
        const frameBtn = document.getElementById('frame-btn');
        const downloadBtn = document.getElementById('download-btn');
        const violationsContainer = document.getElementById('violations-container');
        const noViolations = document.getElementById('no-violations');
        
        // Event Listeners
        uploadBtn.addEventListener('click', () => {
            fileInput.click();
        });
        
        fileInput.addEventListener('change', handleFileUpload);
        
        // Drag and drop functionality
        uploadArea.addEventListener('dragover', (e) => {
            e.preventDefault();
            uploadArea.classList.add('dragging');
        });
        
        uploadArea.addEventListener('dragleave', () => {
            uploadArea.classList.remove('dragging');
        });
        
        uploadArea.addEventListener('drop', (e) => {
            e.preventDefault();
            uploadArea.classList.remove('dragging');
            
            if (e.dataTransfer.files.length) {
                fileInput.files = e.dataTransfer.files;
                handleFileUpload();
            }
        });
        
        // Simulated video processing
        function handleFileUpload() {
            if (fileInput.files.length === 0) return;
            
            const file = fileInput.files[0];
            
            // Check if it's a video file
            if (!file.type.startsWith('video/')) {
                alert('Please upload a video file.');
                return;
            }
            
            // Display the processing overlay
            processingOverlay.classList.add('active');
            
            // Create a URL for the video
            const videoURL = URL.createObjectURL(file);
            outputVideo.src = videoURL;
            
            // Simulate processing
            simulateProcessing(file.size);
        }
        
        function simulateProcessing(fileSize) {
            let progress = 0;
            const totalFrames = Math.floor(fileSize / 50000); // Rough estimate
            const detectedViolations = Math.floor(Math.random() * 5) + 1; // Random number of violations
            const detectedVehicles = Math.floor(Math.random() * 30) + 10; // Random number of vehicles
            const detectedLights = Math.floor(Math.random() * 3) + 1; // Random number of traffic lights
            
            // Update stats
            totalViolations.textContent = detectedViolations;
            totalVehicles.textContent = detectedVehicles;
            trafficLights.textContent = detectedLights;
            
            // Generate violation events
            generateViolationEvents(detectedViolations);
            
            const interval = setInterval(() => {
                progress += 1;
                progressBar.style.width = ${progress}%;
                
                if (progress >= 100) {
                    clearInterval(interval);
                    setTimeout(() => {
                        processingOverlay.classList.remove('active');
                        videoDisplay.classList.add('active');
                        detectionInfo.classList.add('active');
                        
                        // Set video metadata once loaded
                        outputVideo.onloadedmetadata = () => {
                            const minutes = Math.floor(outputVideo.duration / 60);
                            const seconds = Math.floor(outputVideo.duration % 60);
                            videoDuration.textContent = ${minutes}:${seconds.toString().padStart(2, '0')};
                        };
                        
                        // Update real-time stats during video playback
                        setupVideoPlayback();
                    }, 500);
                }
            }, 50);
        }
        
        function setupVideoPlayback() {
            const lightColors = ['🔴 Red', '🟡 Yellow', '🟢 Green'];
            let isPaused = false;
            
            // Update stats during playback
            outputVideo.addEventListener('timeupdate', () => {
                // Randomly change traffic light status
                if (Math.random() < 0.05) {
                    const randomIndex = Math.floor(Math.random() * lightColors.length);
                    trafficLightStatus.textContent = lightColors[randomIndex];
                    
                    // Add appropriate color class
                    trafficLightStatus.className = 'detection-value';
                    if (randomIndex === 0) trafficLightStatus.classList.add('detection-red');
                    if (randomIndex === 1) trafficLightStatus.classList.add('detection-yellow');
                    if (randomIndex === 2) trafficLightStatus.classList.add('detection-green');
                }
                
                // Update vehicles in frame
                const randomVehicles = Math.floor(Math.random() * 10) + 1;
                vehiclesInFrame.textContent = randomVehicles;
                
                // Update processing status
                processingStatus.textContent = isPaused ? 'Paused' : 'Analyzing';
            });
            
            // Control buttons
            pauseBtn.addEventListener('click', () => {
                if (outputVideo.paused) {
                    outputVideo.play();
                    pauseBtn.innerHTML = '<span>⏸️</span> Pause';
                    isPaused = false;
                } else {
                    outputVideo.pause();
                    pauseBtn.innerHTML = '<span>▶️</span> Play';
                    isPaused = true;
                }
            });
            
            frameBtn.addEventListener('click', () => {
                if (!outputVideo.paused) {
                    outputVideo.pause();
                    pauseBtn.innerHTML = '<span>▶️</span> Play';
                    isPaused = true;
                }
                
                outputVideo.currentTime += 1/30; // Advance by one frame (assuming 30fps)
            });
            
            downloadBtn.addEventListener('click', () => {
                alert('Results downloaded. Check your downloads folder.');
            });
        }
        
        function generateViolationEvents(count) {
            // Clear existing items
            while (violationsContainer.firstChild) {
                violationsContainer.removeChild(violationsContainer.firstChild);
            }
            
            if (count === 0) {
                violationsContainer.appendChild(noViolations);
                return;
            }
            
            // Hide the "no violations" message
            noViolations.style.display = 'none';
            
            const violationTypes = [
                'Red Light Violation',
                'Speeding',
                'Improper Lane Usage',
                'No Signal',
                'Illegal Turn'
            ];
            
            for (let i = 0; i < count; i++) {
                const randomType = violationTypes[Math.floor(Math.random() * violationTypes.length)];
                const randomMinute = Math.floor(Math.random() * 5);
                const randomSecond = Math.floor(Math.random() * 60);
                const timeStamp = ${randomMinute}:${randomSecond.toString().padStart(2, '0')};
                
                const violationItem = document.createElement('div');
                violationItem.className = 'violation-item';
                violationItem.innerHTML = 
                    <div class="violation-thumbnail">
                        <img src="/api/placeholder/100/60" alt="Violation thumbnail">
                    </div>
                    <div class="violation-info">
                        <div class="violation-time">${timeStamp}</div>
                        <div class="violation-type">${randomType}</div>
                    </div>
                ;
                
                violationItem.addEventListener('click', () => {
                    outputVideo.currentTime = randomMinute * 60 + randomSecond;
                    if (outputVideo.paused) {
                        outputVideo.play();
                        pauseBtn.innerHTML = '<span>⏸️</span> Pause';
                    }
                });
                
                violationsContainer.appendChild(violationItem);
            }
        }
    </script>
</body>
</html>

can u use this html page in index and the functionality will be same like the live video process u show in the above code