UDP Stream from IP Camera

Hello All,

I am very new to network programming and was starting to experiment with UDP connections using rust. I am initially attempting to connect to an IP camera on my network to see if I can read a single packet from it.

From reading the documentation it looks like I need to first create a socket and bind it to a local port on my PC. Then I should be able to connect to the remote IP camera and read some data from it. If this is correct, I have attempted to do this below but keep getting an error during the connect stage. I think the issue is that the remote address is in the wrong format but I am not sure what the correct format should be.

I keep getting errors similar to "
"Could not connect to remote address: Custom { kind: InvalidInput, error: "invalid port value" }""

Normally I would stream from the IP camera using VLC with stream address "rtsp://user:password@192.168.0.11:554/11" and this works perfect but I suspect Rust is expecting a more basic IP address but I am not sure how I can convey this along with the login information. I don't think I need to mention the rtsp protocol (but could be wrong), since if I can get a stream of packets, I should be able to parse the payload from the packet afterwards.

Is this connection type possible in rust or is the code below too simple/naive to achieve it?

Thanks.

use std::io::prelude::*;
use std::net::UdpSocket;

fn main() {
    let mut socket = UdpSocket::bind("127.0.0.1:34254").expect("Could not bind to local port");
    
    socket.connect("rtsp://user:password@192.168.0.11:554/11").expect("Could not connect to remote address");
    
    let mut buffer = [0; 1024];
    
    match socket.recv(&mut buffer) {
        Ok(received) => println!("received {} bytes {:?}", received, &buffer[..received]),
        Err(e) => println!("recv function failed: {:?}", e),
    } 
}

The UdpSocket doesn't know anything about the rtsp protocol nor does it know anything about how to authenticate with that username and password on that protocol. The kind of address it accepts looks like this: 192.168.0.11:554.

To use the rtsp protocol from Rust, you would need a library that knows how to talk in this protocol. I did a search and it seems there are a few options.

Thanks Alice.

I felt that UdpSocket wouldn't know anything about protocols but my intention was just to grab a packet of data and parse it myself based off the rtp header and protocol definition. Perhaps this is not possible.

I had a quick look on crates.io previously and the top hit "rtsp" is just an empty placeholder with no content but I'll revisit the other crates to see if they are of any use.

Just grabbing a packet of data is not that simple. You first need to ask the camera to send you one, and this presumably involves that username and password, although I am not familiar with the details.

Also note that unlike TCP, UDP does not have a concept of a connection. All it knows is to send messages and to listen for messages sent to you. Messages may be lost or duplicated by the network, and there's no connection setup step inherent in UDP. The rtsp protocol has probably added a connection concept on top of UDP, but UDP itself does not define such a concept.

RTSP has a set of directives like https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol#Protocol_directives

Once client sends SETUP the server keeps sending the RTP over UDP packets until TEARDOWN is sent.

May be you can exchange this messages with predefined format with any simple lib like curl or custom one and once reply for SETUP is received, bind and listen to the negotiated port as in below code

UdpSocket::bind("127.0.0.1:34254")

Hope this helps!

I would second @sampleref's suggestion.

To get something working quickly, cURL is a very good option. It has very good rust bindings, and allows you to manage the sockets yourself by setting options on its handles. This allows you to put your RTSP code in a module, and change it out later if you want to write your own.

And if you want to write your own, their implementation of an RTSP client is a good starting point in my opinion (if you can read C). It's pretty clean, and is under a permissive license (so you can take inspiration without being bound to terms of distribution).