In this tutorial, we’ll create a server that captures video from a webcam and streams it to a client over a network. The client will receive the video frames and display them in real-time.
Prerequisites
- Install the required libraries:
pip install opencv-python
2. Ensure you have a webcam connected to your machine.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
How It Works
- Server Side:
- Capture video frames from the webcam using OpenCV.
- Encode the frames into a byte stream.
- Send the encoded frames to the client over a socket.
2. Client Side:
- Receive the encoded frames from the server.
- Decode the frames and display them using OpenCV.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Step 1: Create the Camera Streaming Server
Save the following code in a file named camera_server.py:
import socket
import cv2
import pickle
import struct
# Create a TCP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to an IP address and port
server_address = ('localhost', 12345)
server_socket.bind(server_address)
# Listen for incoming connections
server_socket.listen(1)
print("Camera server is listening on port 12345...")
# Accept a connection from a client
client_socket, client_address = server_socket.accept()
print(f"Connection established with {client_address}")
# Set a timeout for the client socket (e.g., 5 seconds)
client_socket.settimeout(5.0)
# Initialize a buffer to store the incoming data
data_buffer = b""
# Size of the payload (4 bytes for the length of the frame)
payload_size = struct.calcsize("L")
try:
while True:
try:
# Receive the frame size from the client
while len(data_buffer) < payload_size:
packet = client_socket.recv(4096)
if not packet: # Client disconnected
print("Client disconnected.")
break
data_buffer += packet
if not data_buffer:
break # Exit if client disconnected
# Extract the frame size from the buffer
packed_msg_size = data_buffer[:payload_size]
data_buffer = data_buffer[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0]
# Receive the frame data from the client
while len(data_buffer) < msg_size:
packet = client_socket.recv(4096)
if not packet: # Client disconnected
print("Client disconnected.")
break
data_buffer += packet
if not data_buffer:
break # Exit if client disconnected
# Extract the frame from the buffer
frame_data = data_buffer[:msg_size]
data_buffer = data_buffer[msg_size:]
# Deserialize the frame
frame = pickle.loads(frame_data)
# Overlay text on the frame to indicate it's from the server
cv2.putText(frame, "From Server", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# Display the frame in a window
cv2.imshow("Server Camera", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except socket.timeout:
print("No data received from client. Closing connection.")
break
except KeyboardInterrupt:
print("Server stopped.")
finally:
# Release resources
cv2.destroyAllWindows()
client_socket.close()
server_socket.close()
Step 2: Create the Camera Streaming Client
Save the following code in a file named camera_client.py:
import socket
import cv2
import pickle
import struct
# Create a TCP socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to the server
server_address = ('localhost', 12345)
client_socket.connect(server_address)
# Open the webcam
cap = cv2.VideoCapture(0)
try:
while True:
# Capture a frame from the webcam
ret, frame = cap.read()
if not ret:
break
# Serialize the frame into a byte stream
data = pickle.dumps(frame)
# Pack the length of the data into a 4-byte header
message_size = struct.pack("L", len(data))
# Send the frame to the server
client_socket.sendall(message_size + data)
# Display the original frame in a window (optional)
cv2.imshow("Client Camera", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except KeyboardInterrupt:
print("Client stopped.")
finally:
# Release resources
cap.release()
client_socket.close()
cv2.destroyAllWindows()
Step 3: Run the Code
- Open two terminal windows:
- One for the server.
- One for the client.
2. Run the server:
- In the first terminal, navigate to the directory where camera_server.py is saved.
- Run the server using the following command:
python camera_server.py
- The server will start and display:
Camera server is listening on port 12345…
3. Run the client:
- In the second terminal, navigate to the directory where camera_client.py is saved.
- Run the client using the following command:
- python camera_client.py
python camera_client.py
- A window will open displaying the live camera stream from the server.
4. Stop the streaming:
- Press q in the client window to stop the stream and close the window.
How It Works
- The server captures video frames from the webcam using OpenCV.
- Each frame is serialized into a byte stream using pickle.
- The server sends the frame size (as a 4-byte header) followed by the frame data to the client.
- The client receives the frame size and data, deserializes the frame, and displays it using OpenCV.
Key Takeaways
- Sockets can be used to stream real-time data, such as video, between a server and a client.
- OpenCV is a powerful library for capturing and processing video frames.
- Serialization (using pickle) is necessary to send complex data (like images) over sockets.
'Backend Technologies' 카테고리의 다른 글
socket_003:Sending and Receiving Video over Sockets (0) | 2025.01.30 |
---|---|
socket_001: Introduction to Sockets in Python (0) | 2025.01.30 |
Connecting Docker Containers for Data Transfer_01: A Step-by-Step Tutorial (0) | 2024.12.26 |
프로토콜 버퍼_01: 프로토콜 버퍼 기초 시작하기 (4) | 2024.12.22 |
Protocol Buffers_01: Getting Started with Protobuf Basics (English Version) (3) | 2024.12.22 |