mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
for webapi startsendrtp can send raw rtp
This commit is contained in:
parent
d5b8613858
commit
61625f458f
@ -1104,7 +1104,10 @@ void installWebApi() {
|
||||
if (!src) {
|
||||
throw ApiRetException("该媒体流不存在", API::OtherFailed);
|
||||
}
|
||||
|
||||
uint8_t pt = allArgs["pt"].empty() ? 96 : allArgs["pt"].as<uint8_t>();
|
||||
bool use_ps = allArgs["use_ps"].empty() ? true : allArgs["use_ps"].as<bool>();
|
||||
bool only_audio = allArgs["only_audio"].empty() ? true : allArgs["only_audio"].as<bool>();
|
||||
|
||||
//src_port为空时,则随机本地端口
|
||||
src->startSendRtp(allArgs["dst_url"], allArgs["dst_port"], allArgs["ssrc"], allArgs["is_udp"], allArgs["src_port"], [val, headerOut, invoker](uint16_t local_port, const SockException &ex) mutable{
|
||||
if (ex) {
|
||||
@ -1113,7 +1116,7 @@ void installWebApi() {
|
||||
}
|
||||
val["local_port"] = local_port;
|
||||
invoker(200, headerOut, val.toStyledString());
|
||||
});
|
||||
},pt,use_ps,only_audio);
|
||||
});
|
||||
|
||||
api_regist("/index/api/stopSendRtp",[](API_ARGS_MAP){
|
||||
|
@ -237,13 +237,13 @@ bool MediaSource::isRecording(Recorder::type type){
|
||||
return listener->isRecording(*this, type);
|
||||
}
|
||||
|
||||
void MediaSource::startSendRtp(const string &dst_url, uint16_t dst_port, const string &ssrc, bool is_udp, uint16_t src_port, const function<void(uint16_t local_port, const SockException &ex)> &cb){
|
||||
void MediaSource::startSendRtp(const string &dst_url, uint16_t dst_port, const string &ssrc, bool is_udp, uint16_t src_port, const function<void(uint16_t local_port, const SockException &ex)> &cb,uint8_t pt, bool use_ps,bool only_audio){
|
||||
auto listener = _listener.lock();
|
||||
if (!listener) {
|
||||
cb(0, SockException(Err_other, "尚未设置事件监听器"));
|
||||
return;
|
||||
}
|
||||
return listener->startSendRtp(*this, dst_url, dst_port, ssrc, is_udp, src_port, cb);
|
||||
return listener->startSendRtp(*this, dst_url, dst_port, ssrc, is_udp, src_port, cb, use_ps, only_audio);
|
||||
}
|
||||
|
||||
bool MediaSource::stopSendRtp(const string &ssrc) {
|
||||
@ -720,12 +720,12 @@ vector<Track::Ptr> MediaSourceEventInterceptor::getMediaTracks(MediaSource &send
|
||||
return listener->getMediaTracks(sender, trackReady);
|
||||
}
|
||||
|
||||
void MediaSourceEventInterceptor::startSendRtp(MediaSource &sender, const string &dst_url, uint16_t dst_port, const string &ssrc, bool is_udp, uint16_t src_port, const function<void(uint16_t local_port, const SockException &ex)> &cb){
|
||||
void MediaSourceEventInterceptor::startSendRtp(MediaSource &sender, const string &dst_url, uint16_t dst_port, const string &ssrc, bool is_udp, uint16_t src_port, const function<void(uint16_t local_port, const SockException &ex)> &cb, uint8_t pt, bool use_ps,bool only_audio ){
|
||||
auto listener = _listener.lock();
|
||||
if (listener) {
|
||||
listener->startSendRtp(sender, dst_url, dst_port, ssrc, is_udp, src_port, cb);
|
||||
listener->startSendRtp(sender, dst_url, dst_port, ssrc, is_udp, src_port, cb, pt, use_ps, only_audio);
|
||||
} else {
|
||||
MediaSourceEvent::startSendRtp(sender, dst_url, dst_port, ssrc, is_udp, src_port, cb);
|
||||
MediaSourceEvent::startSendRtp(sender, dst_url, dst_port, ssrc, is_udp, src_port, cb, pt, use_ps, only_audio);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
// 获取所有track相关信息
|
||||
virtual std::vector<Track::Ptr> getMediaTracks(MediaSource &sender, bool trackReady = true) const { return std::vector<Track::Ptr>(); };
|
||||
// 开始发送ps-rtp
|
||||
virtual void startSendRtp(MediaSource &sender, const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb) { cb(0, toolkit::SockException(toolkit::Err_other, "not implemented"));};
|
||||
virtual void startSendRtp(MediaSource &sender, const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb, uint8_t pt=96, bool use_ps = true,bool only_audio = true) { cb(0, toolkit::SockException(toolkit::Err_other, "not implemented"));};
|
||||
// 停止发送ps-rtp
|
||||
virtual bool stopSendRtp(MediaSource &sender, const std::string &ssrc) {return false; }
|
||||
|
||||
@ -117,7 +117,7 @@ public:
|
||||
bool setupRecord(MediaSource &sender, Recorder::type type, bool start, const std::string &custom_path, size_t max_second) override;
|
||||
bool isRecording(MediaSource &sender, Recorder::type type) override;
|
||||
std::vector<Track::Ptr> getMediaTracks(MediaSource &sender, bool trackReady = true) const override;
|
||||
void startSendRtp(MediaSource &sender, const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb) override;
|
||||
void startSendRtp(MediaSource &sender, const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb, uint8_t pt=96, bool use_ps = true,bool only_audio = true) override;
|
||||
bool stopSendRtp(MediaSource &sender, const std::string &ssrc) override;
|
||||
|
||||
private:
|
||||
@ -269,7 +269,7 @@ public:
|
||||
// 获取录制状态
|
||||
bool isRecording(Recorder::type type);
|
||||
// 开始发送ps-rtp
|
||||
void startSendRtp(const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb);
|
||||
void startSendRtp(const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb , uint8_t pt = 96, bool use_ps = true,bool only_audio = true);
|
||||
// 停止发送ps-rtp
|
||||
bool stopSendRtp(const std::string &ssrc);
|
||||
|
||||
|
@ -213,9 +213,9 @@ bool MultiMediaSourceMuxer::isRecording(MediaSource &sender, Recorder::type type
|
||||
}
|
||||
}
|
||||
|
||||
void MultiMediaSourceMuxer::startSendRtp(MediaSource &, const string &dst_url, uint16_t dst_port, const string &ssrc, bool is_udp, uint16_t src_port, const function<void(uint16_t local_port, const SockException &ex)> &cb){
|
||||
void MultiMediaSourceMuxer::startSendRtp(MediaSource &, const string &dst_url, uint16_t dst_port, const string &ssrc, bool is_udp, uint16_t src_port, const function<void(uint16_t local_port, const SockException &ex)> &cb ,uint8_t pt, bool use_ps,bool only_audio){
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
RtpSender::Ptr rtp_sender = std::make_shared<RtpSender>(atoi(ssrc.data()));
|
||||
RtpSender::Ptr rtp_sender = std::make_shared<RtpSender>(atoi(ssrc.data()),pt,use_ps,only_audio);
|
||||
weak_ptr<MultiMediaSourceMuxer> weak_self = shared_from_this();
|
||||
rtp_sender->startSend(dst_url, dst_port, is_udp, src_port, [weak_self, rtp_sender, cb, ssrc](uint16_t local_port, const SockException &ex) {
|
||||
cb(local_port, ex);
|
||||
|
@ -134,7 +134,7 @@ public:
|
||||
* @param is_udp 是否为udp
|
||||
* @param cb 启动成功或失败回调
|
||||
*/
|
||||
void startSendRtp(MediaSource &sender, const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb) override;
|
||||
void startSendRtp(MediaSource &sender, const std::string &dst_url, uint16_t dst_port, const std::string &ssrc, bool is_udp, uint16_t src_port, const std::function<void(uint16_t local_port, const toolkit::SockException &ex)> &cb ,uint8_t pt = 96, bool use_ps = true,bool only_audio = true) override;
|
||||
|
||||
/**
|
||||
* 停止ps-rtp发送
|
||||
|
102
src/Rtp/RawEncoder.cpp
Normal file
102
src/Rtp/RawEncoder.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/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 "RawEncoder.h"
|
||||
#include "Extension/H264Rtp.h"
|
||||
#include "Extension/AACRtp.h"
|
||||
#include "Extension/H265Rtp.h"
|
||||
#include "Extension/CommonRtp.h"
|
||||
#include "Extension/G711Rtp.h"
|
||||
#include "Rtsp/RtspMuxer.h"
|
||||
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit{
|
||||
|
||||
RawEncoderImp::RawEncoderImp(uint32_t ssrc, uint8_t payload_type,bool sendAudio):_ssrc(ssrc),_payload_type(payload_type),_sendAudio(sendAudio) {
|
||||
|
||||
}
|
||||
|
||||
RawEncoderImp::~RawEncoderImp() {
|
||||
InfoL << this << " " << printSSRC(_ssrc);
|
||||
}
|
||||
|
||||
bool RawEncoderImp::addTrack(const Track::Ptr &track){
|
||||
if(_sendAudio && track->getTrackType() == TrackType::TrackAudio && !_rtp_encoder){// audio
|
||||
_rtp_encoder = createRtpEncoder(track);
|
||||
_rtp_encoder->setRtpRing(std::make_shared<RtpRing::RingType>());
|
||||
_rtp_encoder->getRtpRing()->setDelegate(std::make_shared<RingDelegateHelper>([this](RtpPacket::Ptr rtp, bool is_key){
|
||||
onRTP(std::move(rtp));
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!_sendAudio && track->getTrackType()==TrackType::TrackVideo && !_rtp_encoder){
|
||||
_rtp_encoder = createRtpEncoder(track);
|
||||
_rtp_encoder->setRtpRing(std::make_shared<RtpRing::RingType>());
|
||||
_rtp_encoder->getRtpRing()->setDelegate(std::make_shared<RingDelegateHelper>([this](RtpPacket::Ptr rtp, bool is_key){
|
||||
onRTP(std::move(rtp));
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void RawEncoderImp::resetTracks(){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool RawEncoderImp::inputFrame(const Frame::Ptr &frame){
|
||||
if(frame->getTrackType() == TrackType::TrackAudio && _sendAudio && _rtp_encoder){
|
||||
_rtp_encoder->inputFrame(frame);
|
||||
}
|
||||
|
||||
if(frame->getTrackType() == TrackType::TrackVideo && !_sendAudio && _rtp_encoder){
|
||||
_rtp_encoder->inputFrame(frame);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RtpCodec::Ptr RawEncoderImp::createRtpEncoder(const Track::Ptr &track){
|
||||
GET_CONFIG(uint32_t,audio_mtu,Rtp::kAudioMtuSize);
|
||||
GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize);
|
||||
auto codec_id = track->getCodecId();
|
||||
uint32_t sample_rate = 90000;
|
||||
int channels = 1;
|
||||
auto mtu = (track->getTrackType() == TrackVideo ? video_mtu : audio_mtu);
|
||||
if(track->getTrackType() == TrackType::TrackAudio){
|
||||
AudioTrack::Ptr audioTrack = std::dynamic_pointer_cast<AudioTrack>(track);
|
||||
sample_rate = audioTrack->getAudioSampleRate();
|
||||
channels = audioTrack->getAudioChannel();
|
||||
}
|
||||
switch (codec_id){
|
||||
case CodecH264 : return std::make_shared<H264RtpEncoder>(_ssrc, mtu, sample_rate, _payload_type, 0);
|
||||
case CodecH265 : return std::make_shared<H265RtpEncoder>(_ssrc, mtu, sample_rate, _payload_type, 0);
|
||||
case CodecAAC : return std::make_shared<AACRtpEncoder>(_ssrc, mtu, sample_rate, _payload_type, 0);
|
||||
case CodecL16 :
|
||||
case CodecOpus : return std::make_shared<CommonRtpEncoder>(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0);
|
||||
case CodecG711A :
|
||||
case CodecG711U : {
|
||||
if (_payload_type == Rtsp::PT_PCMA || _payload_type == Rtsp::PT_PCMU) {
|
||||
return std::make_shared<G711RtpEncoder>(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0, channels);
|
||||
}
|
||||
return std::make_shared<CommonRtpEncoder>(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0);
|
||||
}
|
||||
default : WarnL << "暂不支持该CodecId:" << codec_id; return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
#endif//defined(ENABLE_RTPPROXY)
|
59
src/Rtp/RawEncoder.h
Normal file
59
src/Rtp/RawEncoder.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/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_RAWENCODER_H
|
||||
#define ZLMEDIAKIT_RAWENCODER_H
|
||||
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
|
||||
|
||||
#include "Common/MediaSink.h"
|
||||
#include "Common/Stamp.h"
|
||||
#include "Extension/CommonRtp.h"
|
||||
|
||||
namespace mediakit{
|
||||
|
||||
class RawEncoderImp : public MediaSinkInterface{
|
||||
public:
|
||||
RawEncoderImp(uint32_t ssrc, uint8_t payload_type = 96, bool sendAudio = true);
|
||||
~RawEncoderImp() override;
|
||||
|
||||
/**
|
||||
* 添加音视频轨道
|
||||
*/
|
||||
bool addTrack(const Track::Ptr &track) override;
|
||||
|
||||
|
||||
/**
|
||||
* 重置音视频轨道
|
||||
*/
|
||||
void resetTracks() override;
|
||||
|
||||
/**
|
||||
* 输入帧数据
|
||||
*/
|
||||
bool inputFrame(const Frame::Ptr &frame) override;
|
||||
|
||||
protected:
|
||||
//rtp打包后回调
|
||||
virtual void onRTP(toolkit::Buffer::Ptr rtp) = 0;
|
||||
private:
|
||||
RtpCodec::Ptr createRtpEncoder(const Track::Ptr &track);
|
||||
|
||||
uint32_t _ssrc;
|
||||
uint8_t _payload_type;
|
||||
bool _sendAudio;
|
||||
RtpCodec::Ptr _rtp_encoder;
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
#endif //ENABLE_RTPPROXY
|
||||
#endif //ZLMEDIAKIT_RAWENCODER_H
|
@ -34,6 +34,12 @@ void RtpCachePS::onRTP(Buffer::Ptr buffer) {
|
||||
input(stamp, std::move(buffer));
|
||||
}
|
||||
|
||||
void RtpCacheRaw::onRTP(Buffer::Ptr buffer) {
|
||||
auto rtp = std::static_pointer_cast<RtpPacket>(buffer);
|
||||
auto stamp = rtp->getStampMS();
|
||||
input(stamp, std::move(buffer));
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
#endif//#if defined(ENABLE_RTPPROXY)
|
@ -14,6 +14,7 @@
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
|
||||
#include "PSEncoder.h"
|
||||
#include "RawEncoder.h"
|
||||
#include "Extension/CommonRtp.h"
|
||||
|
||||
namespace mediakit{
|
||||
@ -47,6 +48,16 @@ protected:
|
||||
void onRTP(toolkit::Buffer::Ptr rtp) override;
|
||||
};
|
||||
|
||||
|
||||
class RtpCacheRaw : public RtpCache, public RawEncoderImp{
|
||||
public:
|
||||
RtpCacheRaw(onFlushed cb, uint32_t ssrc, uint8_t payload_type = 96,bool sendAudio = true) : RtpCache(std::move(cb)), RawEncoderImp(ssrc, payload_type,sendAudio) {};
|
||||
~RtpCacheRaw() override = default;
|
||||
|
||||
protected:
|
||||
void onRTP(toolkit::Buffer::Ptr rtp) override;
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
#endif//ENABLE_RTPPROXY
|
||||
#endif //ZLMEDIAKIT_RTPCACHE_H
|
||||
|
@ -19,11 +19,15 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit{
|
||||
|
||||
RtpSender::RtpSender(uint32_t ssrc, uint8_t payload_type) {
|
||||
RtpSender::RtpSender(uint32_t ssrc, uint8_t payload_type,bool use_ps, bool only_audio) {
|
||||
_poller = EventPollerPool::Instance().getPoller();
|
||||
_interface = std::make_shared<RtpCachePS>([this](std::shared_ptr<List<Buffer::Ptr> > list) {
|
||||
onFlushRtpList(std::move(list));
|
||||
}, ssrc, payload_type);
|
||||
if (use_ps) {
|
||||
_interface = std::make_shared<RtpCachePS>(
|
||||
[this](std::shared_ptr<List<Buffer::Ptr>> list) { onFlushRtpList(std::move(list)); }, ssrc, payload_type);
|
||||
}else{
|
||||
_interface = std::make_shared<RtpCacheRaw>(
|
||||
[this](std::shared_ptr<List<Buffer::Ptr>> list) { onFlushRtpList(std::move(list)); }, ssrc, payload_type,only_audio);
|
||||
}
|
||||
}
|
||||
|
||||
RtpSender::~RtpSender() {}
|
||||
|
@ -27,8 +27,10 @@ public:
|
||||
* 构造函数,创建GB28181 RTP发送客户端
|
||||
* @param ssrc rtp的ssrc
|
||||
* @param payload_type 国标中ps-rtp的pt一般为96
|
||||
* @param use_ps 是否打包为PS然后发送
|
||||
* @param only_audio use_ps 为false 时有效,指定发送音频还是视频
|
||||
*/
|
||||
RtpSender(uint32_t ssrc, uint8_t payload_type = 96);
|
||||
RtpSender(uint32_t ssrc, uint8_t payload_type = 96,bool use_ps = true,bool only_audio = true);
|
||||
|
||||
/**
|
||||
* 开始发送ps-rtp包
|
||||
|
Loading…
Reference in New Issue
Block a user