Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
62130f77
Commit
62130f77
authored
Nov 27, 2020
by
kingyuanyuan
Committed by
Gitee
Nov 27, 2020
Browse files
Options
Browse Files
Download
Plain Diff
!1 多路RTP 流输出
Merge pull request !1 from kingyuanyuan/branch
parents
f7433b0f
50927548
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
188 行增加
和
178 行删除
+188
-178
server/WebApi.cpp
+0
-0
src/Common/MediaSink.cpp
+0
-0
src/Common/MediaSource.cpp
+0
-0
src/Common/MediaSource.h
+0
-0
src/Common/MultiMediaSourceMuxer.cpp
+0
-0
src/Common/MultiMediaSourceMuxer.h
+0
-0
src/Rtp/RtpSender.cpp
+0
-0
src/Rtp/RtpSender.h
+86
-85
src/Rtp/RtpServer.cpp
+102
-93
没有找到文件。
server/WebApi.cpp
查看文件 @
62130f77
差异被折叠。
点击展开。
src/Common/MediaSink.cpp
查看文件 @
62130f77
差异被折叠。
点击展开。
src/Common/MediaSource.cpp
查看文件 @
62130f77
差异被折叠。
点击展开。
src/Common/MediaSource.h
查看文件 @
62130f77
差异被折叠。
点击展开。
src/Common/MultiMediaSourceMuxer.cpp
查看文件 @
62130f77
差异被折叠。
点击展开。
src/Common/MultiMediaSourceMuxer.h
查看文件 @
62130f77
差异被折叠。
点击展开。
src/Rtp/RtpSender.cpp
查看文件 @
62130f77
差异被折叠。
点击展开。
src/Rtp/RtpSender.h
查看文件 @
62130f77
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_RTPSENDER_H
#define ZLMEDIAKIT_RTPSENDER_H
#if defined(ENABLE_RTPPROXY)
#include "PSEncoder.h"
#include "Extension/CommonRtp.h"
namespace
mediakit
{
//rtp发送客户端,支持发送GB28181协议
class
RtpSender
:
public
MediaSinkInterface
,
public
std
::
enable_shared_from_this
<
RtpSender
>
{
public
:
typedef
std
::
shared_ptr
<
RtpSender
>
Ptr
;
~
RtpSender
()
override
;
/**
* 构造函数,创建GB28181 RTP发送客户端
* @param ssrc rtp的ssrc
* @param payload_type 国标中ps-rtp的pt一般为96
*/
RtpSender
(
uint32_t
ssrc
,
uint8_t
payload_type
=
96
);
/**
* 开始发送ps-rtp包
* @param dst_url 目标ip或域名
* @param dst_port 目标端口
* @param is_udp 是否采用udp方式发送rtp
* @param cb 连接目标端口是否成功的回调
*/
void
startSend
(
const
string
&
dst_url
,
uint16_t
dst_port
,
bool
is_udp
,
const
function
<
void
(
const
SockException
&
ex
)
>
&
cb
);
/**
* 输入帧数据
*/
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
/**
* 添加track,内部会调用Track的clone方法
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
* @param track
*/
virtual
void
addTrack
(
const
Track
::
Ptr
&
track
)
override
;
/**
* 添加所有Track完毕
*/
virtual
void
addTrackCompleted
()
override
;
/**
* 重置track
*/
virtual
void
resetTracks
()
override
;
private
:
//合并写输出
void
onFlushRtpList
(
std
::
shared_ptr
<
List
<
Buffer
::
Ptr
>
>
rtp_list
);
//udp/tcp连接成功回调
void
onConnect
();
//异常断开socket事件
void
onErr
(
const
SockException
&
ex
,
bool
is_connect
=
false
);
private
:
bool
_is_udp
;
bool
_is_connect
=
false
;
string
_dst_url
;
uint16_t
_dst_port
;
Socket
::
Ptr
_socket
;
EventPoller
::
Ptr
_poller
;
Timer
::
Ptr
_connect_timer
;
MediaSinkInterface
::
Ptr
_interface
;
};
}
//namespace mediakit
#endif// defined(ENABLE_RTPPROXY)
#endif //ZLMEDIAKIT_RTPSENDER_H
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_RTPSENDER_H
#define ZLMEDIAKIT_RTPSENDER_H
#if defined(ENABLE_RTPPROXY)
#include "PSEncoder.h"
#include "Extension/CommonRtp.h"
namespace
mediakit
{
//rtp发送客户端,支持发送GB28181协议
class
RtpSender
:
public
MediaSinkInterface
,
public
std
::
enable_shared_from_this
<
RtpSender
>
{
public
:
typedef
std
::
shared_ptr
<
RtpSender
>
Ptr
;
~
RtpSender
()
override
;
/**
* 构造函数,创建GB28181 RTP发送客户端
* @param ssrc rtp的ssrc
* @param payload_type 国标中ps-rtp的pt一般为96
*/
RtpSender
(
uint32_t
ssrc
,
uint8_t
payload_type
=
96
);
/**
* 开始发送ps-rtp包
* @param dst_url 目标ip或域名
* @param dst_port 目标端口
* @param is_udp 是否采用udp方式发送rtp
* @param cb 连接目标端口是否成功的回调
*/
void
startSend
(
const
string
&
dst_url
,
uint16_t
dst_port
,
bool
is_udp
,
uint16_t
src_port
,
const
function
<
void
(
const
SockException
&
ex
)
>
&
cb
);
/**
* 输入帧数据
*/
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
/**
* 添加track,内部会调用Track的clone方法
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
* @param track
*/
virtual
void
addTrack
(
const
Track
::
Ptr
&
track
)
override
;
/**
* 添加所有Track完毕
*/
virtual
void
addTrackCompleted
()
override
;
/**
* 重置track
*/
virtual
void
resetTracks
()
override
;
private
:
//合并写输出
void
onFlushRtpList
(
std
::
shared_ptr
<
List
<
Buffer
::
Ptr
>
>
rtp_list
);
//udp/tcp连接成功回调
void
onConnect
();
//异常断开socket事件
void
onErr
(
const
SockException
&
ex
,
bool
is_connect
=
false
);
private
:
bool
_is_udp
;
bool
_is_connect
=
false
;
string
_dst_url
;
uint16_t
_dst_port
;
uint16_t
_src_port
;
Socket
::
Ptr
_socket
;
EventPoller
::
Ptr
_poller
;
Timer
::
Ptr
_connect_timer
;
MediaSinkInterface
::
Ptr
_interface
;
};
}
//namespace mediakit
#endif// defined(ENABLE_RTPPROXY)
#endif //ZLMEDIAKIT_RTPSENDER_H
src/Rtp/RtpServer.cpp
查看文件 @
62130f77
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#if defined(ENABLE_RTPPROXY)
#include "RtpServer.h"
#include "RtpSelector.h"
namespace
mediakit
{
RtpServer
::
RtpServer
()
{
}
RtpServer
::~
RtpServer
()
{
if
(
_on_clearup
){
_on_clearup
();
}
}
void
RtpServer
::
start
(
uint16_t
local_port
,
const
string
&
stream_id
,
bool
enable_tcp
,
const
char
*
local_ip
)
{
//创建udp服务器
Socket
::
Ptr
udp_server
=
Socket
::
createSocket
(
nullptr
,
false
);
if
(
local_port
==
0
)
{
//随机端口,rtp端口采用偶数
Socket
::
Ptr
rtcp_server
=
Socket
::
createSocket
(
nullptr
,
false
);
auto
pair
=
std
::
make_pair
(
udp_server
,
rtcp_server
);
makeSockPair
(
pair
,
local_ip
);
//取偶数端口
udp_server
=
pair
.
first
;
}
else
if
(
!
udp_server
->
bindUdpSock
(
local_port
,
local_ip
))
{
//用户指定端口
throw
std
::
runtime_error
(
StrPrinter
<<
"bindUdpSock on "
<<
local_ip
<<
":"
<<
local_port
<<
" failed:"
<<
get_uv_errmsg
(
true
));
}
//设置udp socket读缓存
SockUtil
::
setRecvBuf
(
udp_server
->
rawFD
(),
4
*
1024
*
1024
);
TcpServer
::
Ptr
tcp_server
;
if
(
enable_tcp
)
{
//创建tcp服务器
tcp_server
=
std
::
make_shared
<
TcpServer
>
(
udp_server
->
getPoller
());
(
*
tcp_server
)[
RtpSession
::
kStreamID
]
=
stream_id
;
tcp_server
->
start
<
RtpSession
>
(
udp_server
->
get_local_port
(),
local_ip
);
}
RtpProcess
::
Ptr
process
;
if
(
!
stream_id
.
empty
())
{
//指定了流id,那么一个端口一个流(不管是否包含多个ssrc的多个流,绑定rtp源后,会筛选掉ip端口不匹配的流)
process
=
RtpSelector
::
Instance
().
getProcess
(
stream_id
,
true
);
udp_server
->
setOnRead
([
udp_server
,
process
](
const
Buffer
::
Ptr
&
buf
,
struct
sockaddr
*
addr
,
int
)
{
process
->
inputRtp
(
true
,
udp_server
,
buf
->
data
(),
buf
->
size
(),
addr
);
});
}
else
{
//未指定流id,一个端口多个流,通过ssrc来分流
auto
&
ref
=
RtpSelector
::
Instance
();
udp_server
->
setOnRead
([
&
ref
,
udp_server
](
const
Buffer
::
Ptr
&
buf
,
struct
sockaddr
*
addr
,
int
)
{
ref
.
inputRtp
(
udp_server
,
buf
->
data
(),
buf
->
size
(),
addr
);
});
}
_on_clearup
=
[
udp_server
,
process
,
stream_id
]()
{
//去除循环引用
udp_server
->
setOnRead
(
nullptr
);
if
(
process
)
{
//删除rtp处理器
RtpSelector
::
Instance
().
delProcess
(
stream_id
,
process
.
get
());
}
};
_tcp_server
=
tcp_server
;
_udp_server
=
udp_server
;
_rtp_process
=
process
;
}
void
RtpServer
::
setOnDetach
(
const
function
<
void
()
>
&
cb
){
if
(
_rtp_process
){
_rtp_process
->
setOnDetach
(
cb
);
}
}
EventPoller
::
Ptr
RtpServer
::
getPoller
()
{
return
_udp_server
->
getPoller
();
}
uint16_t
RtpServer
::
getPort
()
{
return
_udp_server
?
_udp_server
->
get_local_port
()
:
0
;
}
}
//namespace mediakit
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#if defined(ENABLE_RTPPROXY)
#include "RtpServer.h"
#include "RtpSelector.h"
namespace
mediakit
{
RtpServer
::
RtpServer
()
{
}
RtpServer
::~
RtpServer
()
{
if
(
_on_clearup
){
_on_clearup
();
}
}
void
RtpServer
::
start
(
uint16_t
local_port
,
const
string
&
stream_id
,
bool
enable_tcp
,
const
char
*
local_ip
)
{
//创建udp服务器
Socket
::
Ptr
udp_server
=
Socket
::
createSocket
(
nullptr
,
false
);
if
(
local_port
==
0
)
{
//随机端口,rtp端口采用偶数
Socket
::
Ptr
rtcp_server
=
Socket
::
createSocket
(
nullptr
,
false
);
auto
pair
=
std
::
make_pair
(
udp_server
,
rtcp_server
);
makeSockPair
(
pair
,
local_ip
);
//取偶数端口
udp_server
=
pair
.
first
;
}
else
if
(
!
udp_server
->
bindUdpSock
(
local_port
,
local_ip
))
{
//用户指定端口
throw
std
::
runtime_error
(
StrPrinter
<<
"bindUdpSock on "
<<
local_ip
<<
":"
<<
local_port
<<
" failed:"
<<
get_uv_errmsg
(
true
));
}
//设置udp socket读缓存
SockUtil
::
setRecvBuf
(
udp_server
->
rawFD
(),
4
*
1024
*
1024
);
TcpServer
::
Ptr
tcp_server
;
if
(
enable_tcp
)
{
//创建tcp服务器
tcp_server
=
std
::
make_shared
<
TcpServer
>
(
udp_server
->
getPoller
());
(
*
tcp_server
)[
RtpSession
::
kStreamID
]
=
stream_id
;
tcp_server
->
start
<
RtpSession
>
(
udp_server
->
get_local_port
(),
local_ip
);
}
RtpProcess
::
Ptr
process
;
if
(
!
stream_id
.
empty
())
{
//指定了流id,那么一个端口一个流(不管是否包含多个ssrc的多个流,绑定rtp源后,会筛选掉ip端口不匹配的流)
process
=
RtpSelector
::
Instance
().
getProcess
(
stream_id
,
true
);
//udp_server->setOnRead([udp_server, process](const Buffer::Ptr &buf, struct sockaddr *addr, int) {
// process->inputRtp(true, udp_server, buf->data(), buf->size(), addr);
//});
weak_ptr
<
Socket
>
weak_sock
=
udp_server
;
udp_server
->
setOnRead
([
weak_sock
,
process
](
const
Buffer
::
Ptr
&
buf
,
struct
sockaddr
*
addr
,
int
)
{
process
->
inputRtp
(
true
,
weak_sock
.
lock
(),
buf
->
data
(),
buf
->
size
(),
addr
);
});
}
else
{
//未指定流id,一个端口多个流,通过ssrc来分流
auto
&
ref
=
RtpSelector
::
Instance
();
//udp_server->setOnRead([&ref, udp_server](const Buffer::Ptr &buf, struct sockaddr *addr, int) {
// ref.inputRtp(udp_server, buf->data(), buf->size(), addr);
//});
weak_ptr
<
Socket
>
weak_sock
=
udp_server
;
udp_server
->
setOnRead
([
&
ref
,
weak_sock
](
const
Buffer
::
Ptr
&
buf
,
struct
sockaddr
*
addr
,
int
)
{
ref
.
inputRtp
(
weak_sock
.
lock
(),
buf
->
data
(),
buf
->
size
(),
addr
);
});
}
_on_clearup
=
[
udp_server
,
process
,
stream_id
]()
{
//去除循环引用
//udp_server->setOnRead(nullptr);
if
(
process
)
{
//删除rtp处理器
RtpSelector
::
Instance
().
delProcess
(
stream_id
,
process
.
get
());
}
};
_tcp_server
=
tcp_server
;
_udp_server
=
udp_server
;
_rtp_process
=
process
;
}
void
RtpServer
::
setOnDetach
(
const
function
<
void
()
>
&
cb
){
if
(
_rtp_process
){
_rtp_process
->
setOnDetach
(
cb
);
}
}
EventPoller
::
Ptr
RtpServer
::
getPoller
()
{
return
_udp_server
->
getPoller
();
}
uint16_t
RtpServer
::
getPort
()
{
return
_udp_server
?
_udp_server
->
get_local_port
()
:
0
;
}
}
//namespace mediakit
#endif//defined(ENABLE_RTPPROXY)
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论