代码拉取完成,页面将自动刷新
#include "play_connect_handler.h"
#include "event2/event.h"
#include "event2/bufferevent.h"
#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "rtsp_proxy_client.h"
#include <sstream>
#include <QRegExp>
#include <QString>
using namespace std;
using namespace rtsp;
PlayConnectHandler *PlayConnectHandler::NewCreate(event_base *base, int socket, const char* player_host, int player_port)
{
return new PlayConnectHandler(base, socket, player_host, player_port);
}
PlayConnectHandler::PlayConnectHandler(
event_base* base,
int socket,
const char* player_host,
int player_port)
: proxy_client_(NULL)
{
this->bev_ = bufferevent_socket_new(base, socket, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(this->bev_, OnRead, OnWrite, OnEvent, this);
bufferevent_enable(this->bev_, EV_READ | EV_WRITE);
memset(this->player_host_, 0, 16);
memcpy(this->player_host_, player_host, strlen(player_host));
this->player_port_ = player_port;
data_ = new char[data_size_];
memset(this->data_, 0, data_size_);
}
int PlayConnectHandler::GetRequestChannelNumber(const char *in)
{
for(int i = 0; i < strlen(in); i++)
{
if(memcmp(in + i, "Channels/", 9) == 0 || memcmp(in + i, "channels/", 9) == 0)
{
for(int j = i + 9; j < strlen(in); j++)
{
if(memcmp(in + j, " ", 1) == 0)
{
char num[5] = {0};
memcpy(num, in + i + 9, j - i - 9);
return atoi(num);
}
}
}
if(memcmp(in + i, "tracks/", 7) == 0)
{
for(int j = i + 7; j < strlen(in); j++)
{
if(memcmp(in + j, "?", 1) == 0)
{
char num[5] = {0};
memcpy(num, in + i + 7, j - i - 7);
return atoi(num);
}
}
}
}
return 0;
}
void PlayConnectHandler::ReplacePacket(const char *in, char *out, const char *host, int port, int channel_num)
{
// 利用正则表达式进行替换
QRegExp host_port_rx("(\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+)");
QRegExp channel_rx("\\d+");
QString ctx(in);
int pos = 0;
int host_port_pos = 0;
int host_port_len = 0;
int channel_pos = 0;
int channel_len = 0;
if((pos = host_port_rx.indexIn(ctx, pos)) != -1)
{
host_port_pos = pos;
host_port_len = host_port_rx.matchedLength();
pos += host_port_len;
}
if((pos = channel_rx.indexIn(ctx, pos)) != -1)
{
channel_pos = pos;
channel_len = channel_rx.matchedLength();
}
if(host_port_pos == 0 || channel_pos == 0)
{
return;
}
stringstream ss;
ss << host << ":" << port;
int out_pos = 0;
memcpy(out + out_pos, in, host_port_pos);
out_pos += host_port_pos;
memcpy(out + out_pos, ss.str().c_str(), ss.str().size());
out_pos += ss.str().size();
memcpy(out + out_pos, in + host_port_pos + host_port_len, channel_pos - (host_port_pos + host_port_len));
out_pos += (channel_pos - (host_port_pos + host_port_len));
ss.str("");
ss << channel_num;
memcpy(out + out_pos, ss.str().c_str(), ss.str().size());
out_pos += ss.str().size();
memcpy(out + out_pos, in + channel_pos + channel_len, strlen(in) - (channel_pos + channel_len));
}
void PlayConnectHandler::OnRead(bufferevent *bev, void *ctx)
{
PlayConnectHandler* h = (PlayConnectHandler*)ctx;
char out[h->data_size_] = {0};
int read_len = bufferevent_read(h->bev_, h->data_, h->data_size_);
h->data_[read_len] = '\0';
qInfo("播放器消息: \r\n%s\r\n", h->data_);
int req_channel_num = h->GetRequestChannelNumber(h->data_);
if(req_channel_num == 0)
{
qCritical("不能获取报文请求的通道号");
return;
}
// 根据通道号查询映射表中的摄像机地址信息
CameraData *camera_info = Config::Get()->GetCameraInfoByChannel(req_channel_num);
if(!camera_info)
{
qCritical("未找到代理通道号对应的摄像机信息");
return;
}
h->ReplacePacket(h->data_, out, camera_info->host, camera_info->port, camera_info->channel_num);
memcpy(h->data_, out, h->data_size_);
// 创建网络连接代理并添加连接回调
if(!h->proxy_client_)
{
h->proxy_client_ = new RTSPProxyClient(bufferevent_get_base(bev) ,
camera_info->host,
camera_info->port,
h->player_host_);
h->proxy_client_->Connect(OnCameraConnected, h);
return;
}
// 添加RTSP方法的回调
h->proxy_client_->ExecuteMethod(h->data_, OnCameraMethodEvent, h);
}
void PlayConnectHandler::OnWrite(bufferevent *bev, void *ctx)
{
}
void PlayConnectHandler::OnEvent(bufferevent *bev, short what, void *ctx)
{
PlayConnectHandler *h = (PlayConnectHandler*)ctx;
if (what & BEV_EVENT_CONNECTED)
{
return;
}
if (what & BEV_EVENT_ERROR || what & BEV_EVENT_EOF)
{
// 播放端关闭后自动释放
qInfo("播放器(%s)关闭", h->player_host_);
delete h;
}
}
void PlayConnectHandler::OnCameraConnected(ConnectEnum type, void* arg)
{
PlayConnectHandler *h = (PlayConnectHandler*) arg;
if(type == CONNECTION)
{
h->proxy_client_->ExecuteMethod(h->data_, OnCameraMethodEvent, h);
}
}
void PlayConnectHandler::OnCameraMethodEvent(RtspMethodEnum type, char *msg, void* arg)
{
// 所有消息直接转发回播放端
PlayConnectHandler *h = (PlayConnectHandler*) arg;
bufferevent_write(h->bev_, msg, strlen(msg));
}
PlayConnectHandler::~PlayConnectHandler()
{
if(bev_)
{
bufferevent_free(bev_);
}
if(proxy_client_)
{
delete proxy_client_;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。