用ffmpeg打开RTSP流,并依次传输不同的RTSP流,并在接收端分开接收并保存在本地,C代码
时间: 2024-12-18 08:15:44 浏览: 57
在C语言中,你可以使用FFmpeg库来处理RTSP流。以下是一个简单的示例,展示了如何使用FFmpeg打开RTSP流,同时接收并保存多个流到本地文件:
```c
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
// 函数原型声明
int open_rtsp(const char *url, AVFormatContext **fmt_ctx);
void save_stream_to_file(AVStream *stream, const char *filename);
int main() {
// 创建一个AVFormatContext结构体指针
AVFormatContext *fmt_ctx = NULL;
// 这里假设你有一个包含多个RTSP地址的数组
const char *rtsp_urls[] = {"rtsp://example.com/stream1", "rtsp://example.com/stream2", "rtsp://example.com/stream3"};
int num_streams = sizeof(rtsp_urls) / sizeof(rtsp_urls[0]);
for (int i = 0; i < num_streams; i++) {
if (open_rtsp(rtsp_urls[i], &fmt_ctx)) {
printf("Failed to open RTSP stream %d\n", i + 1);
continue;
}
// 遍历所有视频流
for (int j = 0; j < fmt_ctx->nb_streams; j++) {
AVStream *stream = fmt_ctx->streams[j];
if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
char filename[128]; // 文件名格式化字符串
snprintf(filename, sizeof(filename), "output%d_%s.mp4", i + 1, stream-> codec->name); // 根据流编号和编码器命名文件
save_stream_to_file(stream, filename);
avformat_close_input(&fmt_ctx);
break; // 只保存第一个视频流
}
}
}
return 0;
}
// 打开RTSP流函数
int open_rtsp(const char *url, AVFormatContext **fmt_ctx) {
*fmt_ctx = NULL;
if (!avformat_open_input(fmt_ctx, url, NULL, NULL)) {
fprintf(stderr, "Error opening RTSP stream: %s\n", url);
return -1;
}
if (!avformat_find_stream_info(*fmt_ctx, NULL)) {
fprintf(stderr, "Error finding stream info: %s\n", url);
return -1;
}
return 0;
}
// 将流保存到文件函数
void save_stream_to_file(AVStream *stream, const char *filename) {
FILE *out = fopen(filename, "wb");
if (!out) {
perror("Failed to open output file");
return;
}
AVCodecContext *codec_ctx = stream->codec;
AVIOContext *pb = avio_alloc_context(out);
AVPacket pkt;
while (1) {
av_read_frame(stream->pb, &pkt);
if (pkt.stream_index == stream->index && pkt.data) {
avcodec_send_packet(codec_ctx, &pkt);
while (avcodec_receive_packet(codec_ctx, &pkt) >= 0) {
av_interleaved_write_frame(pb, &pkt);
}
}
av_free_packet(&pkt);
if (pkt.stream_index != stream->index || !pkt.data)
break;
}
fclose(out);
}
```
注意:这个示例假设你已经包含了FFmpeg库并且正确安装了它。在实际项目中,你可能需要处理更多的错误情况,并使用线程安全的方式来并发处理多个流。
阅读全文
相关推荐




















