123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #ifndef JTJAI_MEDIA_RTSP_CLIENT_H
- #define JTJAI_MEDIA_RTSP_CLIENT_H
- #include "config.h"
- #include <string>
- #include <atomic>
- #include <memory>
- #include <chrono>
- #include <functional>
- #include <mutex>
- extern "C" {
- #include <libavformat/avformat.h>
- #include <libavcodec/avcodec.h>
- #include <libavutil/time.h>
- #include <libswscale/swscale.h>
- }
- namespace jtjai_media {
- enum class RTSPClientStatus {
- IDLE, // 空闲状态
- CONNECTING, // 连接中
- CONNECTED, // 已连接
- RECORDING, // 录制中
- FINISHED, // 完成
- ERROR_CONNECT, // 连接错误
- ERROR_RECORD, // 录制错误
- TIMEOUT, // 超时
- CANCELLED, // 已取消
- STREAM_UNAVAILABLE // 流不可用(快速失败)
- };
- struct RTSPClientStats {
- int stream_index;
- std::string rtsp_url;
- std::string output_file;
- RTSPClientStatus status;
- std::chrono::system_clock::time_point start_time;
- std::chrono::system_clock::time_point end_time;
- int64_t bytes_received;
- int64_t frames_received;
- int duration_seconds;
- std::string error_message;
-
- RTSPClientStats()
- : stream_index(-1)
- , status(RTSPClientStatus::IDLE)
- , bytes_received(0)
- , frames_received(0)
- , duration_seconds(0) {}
- };
- class RTSPClient {
- public:
- RTSPClient(int stream_index, const StreamConfig& config, const std::string& output_dir);
- ~RTSPClient();
-
- // 禁用拷贝构造和赋值
- RTSPClient(const RTSPClient&) = delete;
- RTSPClient& operator=(const RTSPClient&) = delete;
-
- // 启动录制(阻塞调用)
- bool start_recording(int duration_seconds);
-
- // 异步启动录制
- void start_recording_async(int duration_seconds,
- std::function<void(const RTSPClientStats&)> completion_callback = nullptr);
-
- // 停止录制
- void stop_recording();
-
- // 获取当前状态
- RTSPClientStatus get_status() const { return stats_.status; }
-
- // 获取统计信息
- RTSPClientStats get_stats() const;
-
- // 设置连接超时时间(秒)
- void set_connection_timeout(int timeout_seconds) { connection_timeout_ = timeout_seconds; }
-
- // 设置读取超时时间(秒)
- void set_read_timeout(int timeout_seconds) { read_timeout_ = timeout_seconds; }
-
- // 检查是否正在运行
- bool is_running() const;
- private:
- StreamConfig config_;
- std::string output_dir_;
- std::string full_output_path_;
- mutable std::mutex stats_mutex_;
- RTSPClientStats stats_;
-
- // FFmpeg相关
- AVFormatContext* input_format_ctx_;
- AVFormatContext* output_format_ctx_;
- AVStream* input_video_stream_;
- AVStream* output_video_stream_;
- AVStream* input_audio_stream_;
- AVStream* output_audio_stream_;
-
- // 控制标志
- std::atomic<bool> should_stop_;
- std::atomic<bool> is_recording_;
-
- // 超时设置
- int connection_timeout_;
- int read_timeout_;
-
- // 私有方法
- bool initialize_input();
- bool initialize_output();
- void cleanup();
- bool process_stream(int duration_seconds);
- void update_status(RTSPClientStatus status, const std::string& error_msg = "");
- void update_final_file_stats();
-
- // FFmpeg日志回调
- static void ffmpeg_log_callback(void* ptr, int level, const char* fmt, va_list vl);
-
- // 超时控制
- static int interrupt_callback(void* ctx);
- int64_t start_time_us_;
- int64_t timeout_us_;
- };
- } // namespace jtjai_media
- #endif // JTJAI_MEDIA_RTSP_CLIENT_H
|