Desk camera

Desktop IP Camera Simulator

最近執行專案時發現現場人員會使用Web camera 來monitor 電腦螢幕,因為Web camera 有連到Server, 可以遠端監控,且有記錄和回放功能。當下覺得實在太好笑了,為何不直接把電腦畫面直接傳到Web Camera server 就好了。

了解後才發現螢幕監控記錄系統要額外花錢,現場人員等於是在不增加太多成本的方式來延用舊有系統。

個人覺得這件事沒那麼困難,於是便在下班時間寫了一個可在背景執行的程式,可以把當下電腦畫面模擬成IP camera的串流訊號。如此一來,只要把這個IP camera 加入Web camera server,就可以把電腦畫面送到Server了! 下面是 Python code 提供參考:

import cv2
import numpy as np
import pyautogui
import socket
import time
import sys
import traceback
import logging
from threading import Thread

logging.basicConfig(filename='ip_camera_simulator.log', level=logging.DEBUG, 
                    format='%(asctime)s - %(levelname)s - %(message)s')

def handle_client(client_socket):
    try:
        logging.info("New client connected")
        client_socket.sendall(b"HTTP/1.1 200 OK\r\n")
        client_socket.sendall(b"Content-Type: multipart/x-mixed-replace; boundary=frame\r\n")
        client_socket.sendall(b"\r\n")
        
        while True:
            try:
                screenshot = pyautogui.screenshot()
                frame = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
                _, jpeg = cv2.imencode('.jpg', frame)
                
                client_socket.sendall(b"--frame\r\n")
                client_socket.sendall(b"Content-Type: image/jpeg\r\n")
                client_socket.sendall(f"Content-Length: {len(jpeg)}\r\n".encode())
                client_socket.sendall(b"\r\n")
                client_socket.sendall(jpeg.tobytes())
                client_socket.sendall(b"\r\n")
                
                logging.debug("Frame sent")
                time.sleep(0.1)
            except (ConnectionResetError, BrokenPipeError) as e:
                logging.info(f"Client disconnected: {str(e)}")
                break
            except Exception as e:
                logging.error(f"Error in frame capture/send: {str(e)}")
                logging.error(traceback.format_exc())
                break
    except Exception as e:
        logging.error(f"Error handling client: {str(e)}")
        logging.error(traceback.format_exc())
    finally:
        client_socket.close()

def run_server(port=8000):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('', port))
    server_socket.listen(5)
    logging.info(f"Server running on port {port}")
    print(f"Server running on port {port}")

    while True:
        try:
            client_sock, address = server_socket.accept()
            logging.info(f"Accepted connection from {address}")
            client_thread = Thread(target=handle_client, args=(client_sock,))
            client_thread.start()
        except Exception as e:
            logging.error(f"Error accepting connection: {str(e)}")
            logging.error(traceback.format_exc())

if __name__ == '__main__':
    try:
        logging.info("Starting application")
        run_server()
    except Exception as e:
        logging.error(f"Unhandled exception: {str(e)}")
        logging.error(traceback.format_exc())
        print(f"An error occurred: {str(e)}")
        input("Press Enter to exit...")

"""
Packaging Instructions:

1. Save this script as 'desktop_ip_camera.py'

2. Install PyInstaller:
   pip install pyinstaller

3. Create a spec file:
   pyi-makespec --onefile desktop_ip_camera.py

4. Edit the generated desktop_ip_camera.spec file:
   - Add these imports at the top:
     import sys
     import os

   - In the Analysis section, add:
     pathex=[os.path.dirname(sys.executable)],

   - In the EXE section, ensure:
     console=True,

5. Build using the spec file:
   pyinstaller --clean desktop_ip_camera.spec

6. Look for the executable in the 'dist' folder.

Running and Troubleshooting:
1. Run the executable from command prompt as administrator.
2. Check the generated 'ip_camera_simulator.log' file for error messages.
3. Try accessing http://localhost:8000 in your web browser.
4. If issues persist, check your firewall and antivirus settings.
"""

Posted

in

,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *