#include "RtspPusher.h" #include "RtspConnection.h" #include "Logger.h" #include "TcpSocket.h" #include "Timestamp.h" #include using namespace xop; RtspPusher::RtspPusher(xop::EventLoop *event_loop) : event_loop_(event_loop) { } RtspPusher::~RtspPusher() { this->Close(); } std::shared_ptr RtspPusher::Create(xop::EventLoop* loop) { std::shared_ptr pusher(new RtspPusher(loop)); return pusher; } void RtspPusher::AddSession(MediaSession* session) { std::lock_guard locker(mutex_); media_session_.reset(session); } void RtspPusher::RemoveSession(MediaSessionId sessionId) { std::lock_guard locker(mutex_); media_session_ = nullptr; } MediaSession::Ptr RtspPusher::LookMediaSession(MediaSessionId session_id) { return media_session_; } int RtspPusher::OpenUrl(std::string url, int msec) { std::lock_guard lock(mutex_); static xop::Timestamp timestamp; int timeout = msec; if (timeout <= 0) { timeout = 10000; } timestamp.Reset(); if (!this->ParseRtspUrl(url)) { LOG_ERROR("rtsp url(%s) was illegal.\n", url.c_str()); return -1; } if (rtsp_conn_ != nullptr) { std::shared_ptr rtspConn = rtsp_conn_; SOCKET sockfd = rtspConn->GetSocket(); task_scheduler_->AddTriggerEvent([sockfd, rtspConn]() { rtspConn->Disconnect(); }); rtsp_conn_ = nullptr; } TcpSocket tcpSocket; tcpSocket.Create(); if (!tcpSocket.Connect(rtsp_url_info_.ip, rtsp_url_info_.port, timeout)) { tcpSocket.Close(); return -1; } task_scheduler_ = event_loop_->GetTaskScheduler().get(); rtsp_conn_.reset(new RtspConnection(shared_from_this(), task_scheduler_, tcpSocket.GetSocket())); event_loop_->AddTriggerEvent([this]() { rtsp_conn_->SendOptions(RtspConnection::RTSP_PUSHER); }); timeout -= (int)timestamp.Elapsed(); if (timeout < 0) { timeout = 1000; } do { xop::Timer::Sleep(100); timeout -= 100; } while (!rtsp_conn_->IsRecord() && timeout > 0); if (!rtsp_conn_->IsRecord()) { std::shared_ptr rtspConn = rtsp_conn_; SOCKET sockfd = rtspConn->GetSocket(); task_scheduler_->AddTriggerEvent([sockfd, rtspConn]() { rtspConn->Disconnect(); }); rtsp_conn_ = nullptr; return -1; } return 0; } void RtspPusher::Close() { std::lock_guard lock(mutex_); if (rtsp_conn_ != nullptr) { std::shared_ptr rtsp_conn = rtsp_conn_; SOCKET sockfd = rtsp_conn->GetSocket(); task_scheduler_->AddTriggerEvent([sockfd, rtsp_conn]() { rtsp_conn->Disconnect(); }); rtsp_conn_ = nullptr; } } bool RtspPusher::IsConnected() { std::lock_guard lock(mutex_); if (rtsp_conn_ != nullptr) { return (!rtsp_conn_->IsClosed()); } return false; } bool RtspPusher::PushFrame(MediaChannelId channelId, AVFrame frame) { std::lock_guard locker(mutex_); if (!media_session_ || !rtsp_conn_) { return false; } return media_session_->HandleFrame(channelId, frame); }