SkeyePlayer播放rtsp代码
时间: 2023-08-23 12:04:47 浏览: 47
你可以使用FFmpeg库来播放RTSP视频流。以下是一个示例代码:
```c++
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <opencv2/opencv.hpp>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
int main(int argc, char* argv[]) {
std::string url = "rtsp://your-rtsp-stream-url";
// Initialize FFmpeg
av_register_all();
avcodec_register_all();
// Open the RTSP stream
AVFormatContext* format_ctx = nullptr;
if (avformat_open_input(&format_ctx, url.c_str(), nullptr, nullptr) != 0) {
std::cerr << "Failed to open RTSP stream" << std::endl;
return 1;
}
// Retrieve stream information
if (avformat_find_stream_info(format_ctx, nullptr) < 0) {
std::cerr << "Failed to retrieve stream information" << std::endl;
return 1;
}
// Find the first video stream
int video_stream_index = -1;
for (unsigned int i = 0; i < format_ctx->nb_streams; i++) {
if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_index = i;
break;
}
}
if (video_stream_index == -1) {
std::cerr << "Failed to find video stream" << std::endl;
return 1;
}
// Retrieve the codec context for the video stream
AVCodecContext* codec_ctx = avcodec_alloc_context3(nullptr);
if (!codec_ctx) {
std::cerr << "Failed to allocate codec context" << std::endl;
return 1;
}
avcodec_parameters_to_context(codec_ctx, format_ctx->streams[video_stream_index]->codecpar);
AVCodec* codec = avcodec_find_decoder(codec_ctx->codec_id);
if (!codec) {
std::cerr << "Failed to find codec" << std::endl;
return 1;
}
if (avcodec_open2(codec_ctx, codec, nullptr) != 0) {
std::cerr << "Failed to open codec" << std::endl;
return 1;
}
// Create a window to display the video frames
cv::namedWindow("RTSP stream", cv::WINDOW_NORMAL);
// Loop through the video frames
bool done = false;
AVPacket packet;
while (!done) {
if (av_read_frame(format_ctx, &packet) < 0) {
break;
}
if (packet.stream_index == video_stream_index) {
AVFrame* frame = av_frame_alloc();
if (!frame) {
std::cerr << "Failed to allocate frame" << std::endl;
done = true;
break;
}
int response = avcodec_send_packet(codec_ctx, &packet);
if (response < 0) {
std::cerr << "Error sending packet to decoder" << std::endl;
done = true;
break;
}
while (response >= 0) {
response = avcodec_receive_frame(codec_ctx, frame);
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
break;
}
else if (response < 0) {
std::cerr << "Error during decoding" << std::endl;
done = true;
break;
}
// Convert the frame from its native format to BGR
AVFrame* frame_bgr = av_frame_alloc();
if (!frame_bgr) {
std::cerr << "Failed to allocate frame" << std::endl;
done = true;
break;
}
cv::Mat img(frame->height, frame->width, CV_8UC3);
struct SwsContext* sws_ctx = sws_getContext(frame->width, frame->height, (AVPixelFormat)frame->format,
frame->width, frame->height, AV_PIX_FMT_BGR24, 0, nullptr, nullptr, nullptr);
if (!sws_ctx) {
std::cerr << "Failed to create scale context" << std::endl;
done = true;
break;
}
av_image_fill_arrays(frame_bgr->data, frame_bgr->linesize, img.data, AV_PIX_FMT_BGR24, frame->width, frame->height, 1);
sws_scale(sws_ctx, (const uint8_t* const*)frame->data, frame->linesize, 0, frame->height, frame_bgr->data, frame_bgr->linesize);
sws_freeContext(sws_ctx);
av_frame_free(&frame);
// Display the frame
cv::imshow("RTSP stream", img);
cv::waitKey(1);
av_frame_free(&frame_bgr);
}
}
av_packet_unref(&packet);
}
// Clean up
avcodec_free_context(&codec_ctx);
avformat_close_input(&format_ctx);
cv::destroyAllWindows();
return 0;
}
```
该代码使用OpenCV和FFmpeg库读取RTSP视频流,并将每个帧转换为OpenCV中的BGR格式,以便轻松显示和处理。