Getting an RTSP stream from an IP camera in C involves opening a network connection, sending RTSP commands, and receiving H.264/H.265 video packets. This guide walks you through the process using sockets and FFmpeg, enabling real-time playback on Windows, Linux, or embedded systems.
Quick Answers to Common Questions
Tip/Question?
Answer: Use VLC to test your RTSP URL first. Open VLC → Media → Open Network Stream → paste your URL. If it plays, your credentials and path are correct.
Tip/Question?
Answer: For better performance, consider using UDP instead of TCP by changing the Transport header to RTP/AVP;unicast;client_port=5000-5001 and binding a UDP socket.
Tip/Question?
Answer: Always free allocated memory. Call avformat_close_input(), av_frame_free(), and avcodec_free_context() before exiting your program.
Tip/Question?
Answer: Some cameras require digest authentication instead of basic. Check your camera’s manual—some reject plain Base64 credentials.
Tip/Question?
Answer: Compile with -lavformat -lavcodec -lavutil -lswscale and link against FFmpeg libraries. On Windows, add -lgdiplus if using GUI rendering.
How to Get RTSP Stream of IP Camera in C: A Complete Guide
Have you ever wanted to capture live video from an IP camera directly in your C program? Whether you’re building a surveillance system, a smart home dashboard, or just experimenting with computer vision, getting an RTSP (Real-Time Streaming Protocol) stream from an IP camera is a powerful skill. This guide will walk you through the entire process—from understanding RTSP basics to writing functional C code that connects, authenticates, and displays video frames.
You’ll learn how to:
- Establish a network connection to an RTSP server
- Send RTSP commands like SETUP, PLAY, and TEARDOWN
- Receive RTP (Real-time Transport Protocol) video packets
- Use FFmpeg to decode and render video frames
- Handle authentication and error conditions
This isn’t just theory—you’ll find practical code snippets, configuration tips, and troubleshooting advice throughout. By the end, you’ll have a working example that works with most standard IP cameras (e.g., Axis, Hikvision, Dahua).
Understanding RTSP and RTP
Before diving into code, let’s clarify what RTSP actually does. Think of RTSP as a remote control for your IP camera. It tells the camera to start streaming, stop streaming, or adjust quality. But RTSP itself doesn’t carry video data. That job belongs to RTP (Real-time Transport Protocol), which sends compressed video (usually H.264 or H.265) over UDP or TCP.
Visual guide about How to Get Rtsp Stream of Ip Camera in C
Image source: c-ssl.duitang.com
Here’s a quick breakdown:
- RTSP: Control protocol (like HTTP for media)
- RTP: Carries actual video/audio packets
- RTCP: Optional companion protocol for quality feedback
Most IP cameras support two transport modes:
- UDP: Lower latency, but packets may drop if network is congested
- TCP: More reliable, retransmits lost packets, slightly higher latency
For this tutorial, we’ll focus on TCP, as it’s easier to debug and works reliably behind firewalls.
Setting Up Your Development Environment
To follow along, you’ll need:
- A C compiler (GCC on Linux/macOS, MinGW or MSVC on Windows)
- FFmpeg development libraries installed
- An IP camera with RTSP enabled (or a test stream URL)
Install FFmpeg on Ubuntu/Debian:
sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev libswscale-dev
On macOS with Homebrew:
brew install ffmpeg
On Windows, download pre-built binaries from Gyan.dev and link against the .lib files.
Make sure your camera’s RTSP URL is accessible. Common formats include:
- rtsp://192.168.1.100:554/stream1
- rtsp://admin:password@10.0.0.5/live/ch00_0
Step 1: Initialize Sockets and Connect to Camera
The first step is establishing a TCP connection to the RTSP server. In C, this uses the Berkeley sockets API.
Include Headers and Define Constants
Add these at the top of your file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#define RTSP_PORT 554
#define BUFFER_SIZE 4096
Create Socket and Connect
Here’s a function to connect to the RTSP server:
int create_rtsp_socket(const char* ip, int port) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) { perror("Socket creation failed"); return -1; } struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); inet_pton(AF_INET, ip, &server_addr.sin_addr); if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("Connection failed"); close(sock); return -1; } return sock; }This opens a TCP socket and connects to the camera. Replace
ipwith your camera’s IP address.Step 2: Send RTSP Commands
Once connected, you must send RTSP commands in a specific format. The sequence is:
- OPTIONS
- DESCRIBE
- SETUP
- PLAY
- TEARDOWN (when done)
Send a Generic RTSP Request
Write a helper function to send and receive responses:
void send_rtsp_request(int sock, const char* request) {
ssize_t sent = send(sock, request, strlen(request), 0);
if (sent < 0) { perror("Failed to send RTSP request"); exit(1); } } char* receive_rtsp_response(int sock, int timeout_sec) { fd_set read_fds; struct timeval tv; FD_ZERO(&read_fds); FD_SET(sock, &read_fds); tv.tv_sec = timeout_sec; tv.tv_usec = 0; int ret = select(sock + 1, &read_fds, NULL, NULL, &tv); if (ret <= 0) { fprintf(stderr, "Timeout or error reading response\n"); return NULL; } char buffer[BUFFER_SIZE]; ssize_t received = recv(sock, buffer, sizeof(buffer) - 1, 0); if (received <= 0) { fprintf(stderr, "Connection closed\n"); return NULL; } buffer[received] = '\0'; return strdup(buffer); }Send OPTIONS Command
This checks what methods the server supports:
const char* options_cmd =
"OPTIONS rtsp://192.168.1.100:554/stream1 RTSP/1.0\r\n"
"CSeq: 1\r\n"
"User-Agent: MyCApp/1.0\r\n\r\n";send_rtsp_request(sock, options_cmd);
char* resp = receive_rtsp_response(sock, 5);
printf("OPTIONS Response:\n%s\n", resp);
Send DESCRIBE to Get SDP
The DESCRIBE command returns an SDP (Session Description Protocol) payload describing the stream:
const char* describe_cmd =
"DESCRIBE rtsp://192.168.1.100:554/stream1 RTSP/1.0\r\n"
"CSeq: 2\r\n"
"Accept: application/sdp\r\n"
"Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n" // Base64 of "admin:password"
"\r\n";send_rtsp_request(sock, describe_cmd);
resp = receive_rtsp_response(sock, 5);
// Parse SDP to extract codec info (e.g., H.264)
Note: Replace the base64 string with your camera’s credentials encoded in Base64. You can generate it online or using
echo -n "admin:password" | base64.Step 3: Extract RTP Port and Set Up Playback
After DESCRIBE, the server responds with an SDP body containing media attributes. Look for lines like:
a=control:rtsp://192.168.1.100:554/stream1/track1
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
a=rtpmap:96 H264/90000
Then send a SETUP command to allocate an RTP session:
const char* setup_cmd =
"SETUP rtsp://192.168.1.100:554/stream1/track1 RTSP/1.0\r\n"
"CSeq: 3\r\n"
"Transport: RTP/AVP/TCP;unicast;interleaved=0-1\r\n"
"Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n";send_rtsp_request(sock, setup_cmd);
resp = receive_rtsp_response(sock, 5);
The response includes
RTP/AVP/TCP, meaning video comes interleaved within the RTSP TCP channel (packet type 0x24).Step 4: Receive and Decode Video with FFmpeg
Now comes the fun part: reading video packets and decoding them. FFmpeg handles all the heavy lifting.
Initialize FFmpeg Components
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>AVFormatContext* fmt_ctx = NULL;
AVCodecContext* codec_ctx = NULL;
AVCodec* decoder = NULL;
AVPacket pkt;
AVFrame* frame = NULL;
int video_stream_idx = -1;
Register all codecs and formats at startup:
av_register_all();
avformat_network_init();
Open RTSP Stream via FFmpeg
Instead of raw sockets, you can let FFmpeg open the stream directly:
const char* url = "rtsp://admin:password@192.168.1.100:554/stream1";
if (avformat_open_input(&fmt_ctx, url, NULL, NULL) != 0) {
fprintf(stderr, "Could not open input stream\n");
return -1;
}if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
fprintf(stderr, "Could not find stream information\n");
return -1;
}
Find Video Stream and Open Decoder
for (int i = 0; i < fmt_ctx->nb_streams; i++) {
if (fmt_ctx->streams[i]->codecpar->codec_type