|
| 1 | +/// Example code to stream mjpeg over a tcp socket |
| 2 | +use std::io::Write; |
| 3 | +use std::net::{SocketAddr, TcpListener}; |
| 4 | + |
| 5 | +use opencv::core::{Mat, Vector}; |
| 6 | +use opencv::imgcodecs::{imencode, IMWRITE_JPEG_QUALITY}; |
| 7 | +use opencv::videoio::{VideoCapture, VideoCaptureTrait}; |
| 8 | +use opencv::Result; |
| 9 | + |
| 10 | +const BASE_RESPONSE: &[u8] = b"HTTP/1.1 200 OK\r\nContent-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n"; |
| 11 | + |
| 12 | +fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 13 | + // Select camera |
| 14 | + let mut cam = VideoCapture::new_def(0)?; |
| 15 | + |
| 16 | + // Bind listener to a port |
| 17 | + let address: SocketAddr = "127.0.0.1:8080".parse()?; |
| 18 | + let listener = TcpListener::bind(address)?; |
| 19 | + println!("Listening for connections at {}", address.to_string()); |
| 20 | + |
| 21 | + // Accept the first incoming connection |
| 22 | + let (mut stream, addr) = listener.accept()?; |
| 23 | + println!("Client connected: {}", addr); |
| 24 | + |
| 25 | + // Write intial response |
| 26 | + stream.write_all(BASE_RESPONSE)?; |
| 27 | + |
| 28 | + // Reduce jpeg quality for streaming |
| 29 | + let encode_params = Vector::from_slice(&[IMWRITE_JPEG_QUALITY, 70]); |
| 30 | + let mut buffer = Mat::default(); |
| 31 | + let mut frame = Vector::default(); |
| 32 | + loop { |
| 33 | + // Read frame from the camera & encode it |
| 34 | + cam.read(&mut buffer)?; |
| 35 | + imencode(".jpg", &buffer, &mut frame, &encode_params)?; |
| 36 | + |
| 37 | + // Construct HTTP frame and send it to the peer |
| 38 | + let header = format!( |
| 39 | + "--frame\r\nContent-Type: image/jpeg\r\nContent-Length: {}\r\n\r\n", |
| 40 | + frame.len() |
| 41 | + ); |
| 42 | + let packet = [header.as_bytes(), frame.as_slice()].concat(); |
| 43 | + stream.write_all(&packet)?; |
| 44 | + } |
| 45 | +} |
0 commit comments