整理优化代码

This commit is contained in:
xiongziliang
2019-06-28 17:30:13 +08:00
parent ea131d9740
commit 0b08831f5d
39 changed files with 30 additions and 30 deletions

237
src/Rtmp/FlvMuxer.cpp Normal file
View File

@@ -0,0 +1,237 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "FlvMuxer.h"
#include "Util/File.h"
#include "Rtmp/utils.h"
#define FILE_BUF_SIZE (64 * 1024)
namespace mediakit {
FlvMuxer::FlvMuxer() {
}
FlvMuxer::~FlvMuxer() {
}
void FlvMuxer::start(const EventPoller::Ptr &poller,const RtmpMediaSource::Ptr &media) {
if(!media){
throw std::runtime_error("RtmpMediaSource 无效");
}
if(!poller->isCurrentThread()){
weak_ptr<FlvMuxer> weakSelf = getSharedPtr();
//延时两秒启动录制目的是为了等待config帧收集完毕
poller->doDelayTask(2000,[weakSelf,poller,media](){
auto strongSelf = weakSelf.lock();
if(strongSelf){
strongSelf->start(poller,media);
}
return 0;
});
return;
}
onWriteFlvHeader(media);
std::weak_ptr<FlvMuxer> weakSelf = getSharedPtr();
_ring_reader = media->getRing()->attach(poller);
_ring_reader->setDetachCB([weakSelf](){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
return;
}
strongSelf->onDetach();
});
_ring_reader->setReadCB([weakSelf](const RtmpPacket::Ptr &pkt){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
return;
}
strongSelf->onWriteRtmp(pkt);
});
}
void FlvMuxer::onWriteFlvHeader(const RtmpMediaSource::Ptr &mediaSrc) {
CLEAR_ARR(_aui32FirstStamp);
//发送flv文件头
char flv_file_header[] = "FLV\x1\x5\x0\x0\x0\x9"; // have audio and have video
bool is_have_audio = false,is_have_video = false;
mediaSrc->getConfigFrame([&](const RtmpPacket::Ptr &pkt){
if(pkt->typeId == MSG_VIDEO){
is_have_video = true;
}
if(pkt->typeId == MSG_AUDIO){
is_have_audio = true;
}
});
if (is_have_audio && is_have_video) {
flv_file_header[4] = 0x05;
} else if (is_have_audio && !is_have_video) {
flv_file_header[4] = 0x04;
} else if (!is_have_audio && is_have_video) {
flv_file_header[4] = 0x01;
} else {
flv_file_header[4] = 0x00;
}
//flv header
onWrite(std::make_shared<BufferRaw>(flv_file_header, sizeof(flv_file_header) - 1));
auto size = htonl(0);
//PreviousTagSize0 Always 0
onWrite(std::make_shared<BufferRaw>((char *)&size,4));
//metadata
AMFEncoder invoke;
invoke << "onMetaData" << mediaSrc->getMetaData();
onWriteFlvTag(MSG_DATA, std::make_shared<BufferString>(invoke.data()), 0);
//config frame
mediaSrc->getConfigFrame([&](const RtmpPacket::Ptr &pkt){
onWriteRtmp(pkt);
});
}
#if defined(_WIN32)
#pragma pack(push, 1)
#endif // defined(_WIN32)
class RtmpTagHeader {
public:
uint8_t type = 0;
uint8_t data_size[3] = {0};
uint8_t timestamp[3] = {0};
uint8_t timestamp_ex = 0;
uint8_t streamid[3] = {0}; /* Always 0. */
}PACKED;
#if defined(_WIN32)
#pragma pack(pop)
#endif // defined(_WIN32)
void FlvMuxer::onWriteFlvTag(const RtmpPacket::Ptr &pkt, uint32_t ui32TimeStamp) {
onWriteFlvTag(pkt->typeId,pkt,ui32TimeStamp);
}
void FlvMuxer::onWriteFlvTag(uint8_t ui8Type, const Buffer::Ptr &buffer, uint32_t ui32TimeStamp) {
RtmpTagHeader header;
header.type = ui8Type;
set_be24(header.data_size, buffer->size());
header.timestamp_ex = (uint8_t) ((ui32TimeStamp >> 24) & 0xff);
set_be24(header.timestamp,ui32TimeStamp & 0xFFFFFF);
//tag header
onWrite(std::make_shared<BufferRaw>((char *)&header, sizeof(header)));
//tag data
onWrite(buffer);
auto size = htonl((buffer->size() + sizeof(header)));
//PreviousTagSize
onWrite(std::make_shared<BufferRaw>((char *)&size,4));
}
void FlvMuxer::onWriteRtmp(const RtmpPacket::Ptr &pkt) {
auto modifiedStamp = pkt->timeStamp;
auto &firstStamp = _aui32FirstStamp[pkt->typeId % 2];
if(!firstStamp){
firstStamp = modifiedStamp;
}
if(modifiedStamp >= firstStamp){
//计算时间戳增量
modifiedStamp -= firstStamp;
}else{
//发生回环,重新计算时间戳增量
CLEAR_ARR(_aui32FirstStamp);
modifiedStamp = 0;
}
onWriteFlvTag(pkt, modifiedStamp);
}
void FlvMuxer::stop() {
if(_ring_reader){
_ring_reader.reset();
onDetach();
}
}
///////////////////////////////////////////////////////FlvRecorder/////////////////////////////////////////////////////
void FlvRecorder::startRecord(const EventPoller::Ptr &poller,const string &vhost, const string &app, const string &stream,const string &file_path) {
startRecord(poller,dynamic_pointer_cast<RtmpMediaSource>(MediaSource::find(RTMP_SCHEMA,vhost,app,stream,false)),file_path);
}
void FlvRecorder::startRecord(const EventPoller::Ptr &poller,const RtmpMediaSource::Ptr &media, const string &file_path) {
stop();
lock_guard<recursive_mutex> lck(_file_mtx);
//开辟文件写缓存
std::shared_ptr<char> fileBuf(new char[FILE_BUF_SIZE],[](char *ptr){
if(ptr){
delete [] ptr;
}
});
//新建文件
_file.reset(File::createfile_file(file_path.data(),"wb"),[fileBuf](FILE *fp){
if(fp){
fflush(fp);
fclose(fp);
}
});
if (!_file){
throw std::runtime_error( StrPrinter << "打开文件失败:" << file_path);
}
//设置文件写缓存
setvbuf( _file.get(), fileBuf.get(),_IOFBF, FILE_BUF_SIZE);
start(poller,media);
}
void FlvRecorder::onWrite(const Buffer::Ptr &data) {
lock_guard<recursive_mutex> lck(_file_mtx);
if(_file){
fwrite(data->data(),data->size(),1,_file.get());
}
}
void FlvRecorder::onDetach() {
lock_guard<recursive_mutex> lck(_file_mtx);
_file.reset();
}
std::shared_ptr<FlvMuxer> FlvRecorder::getSharedPtr() {
return shared_from_this();
}
FlvRecorder::FlvRecorder() {
}
FlvRecorder::~FlvRecorder() {
}
}//namespace mediakit

78
src/Rtmp/FlvMuxer.h Normal file
View File

@@ -0,0 +1,78 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef ZLMEDIAKIT_FLVMUXER_H
#define ZLMEDIAKIT_FLVMUXER_H
#include "Rtmp/Rtmp.h"
#include "Rtmp/RtmpMediaSource.h"
#include "Network/Socket.h"
using namespace toolkit;
namespace mediakit {
class FlvMuxer{
public:
typedef std::shared_ptr<FlvMuxer> Ptr;
FlvMuxer();
virtual ~FlvMuxer();
void stop();
protected:
void start(const EventPoller::Ptr &poller,const RtmpMediaSource::Ptr &media);
virtual void onWrite(const Buffer::Ptr &data) = 0;
virtual void onDetach() = 0;
virtual std::shared_ptr<FlvMuxer> getSharedPtr() = 0;
private:
void onWriteFlvHeader(const RtmpMediaSource::Ptr &media);
void onWriteRtmp(const RtmpPacket::Ptr &pkt);
void onWriteFlvTag(const RtmpPacket::Ptr &pkt, uint32_t ui32TimeStamp);
void onWriteFlvTag(uint8_t ui8Type, const Buffer::Ptr &buffer, uint32_t ui32TimeStamp);
private:
RtmpMediaSource::RingType::RingReader::Ptr _ring_reader;
uint32_t _aui32FirstStamp[2] = {0};
};
class FlvRecorder : public FlvMuxer , public std::enable_shared_from_this<FlvRecorder>{
public:
typedef std::shared_ptr<FlvRecorder> Ptr;
FlvRecorder();
virtual ~FlvRecorder();
void startRecord(const EventPoller::Ptr &poller,const string &vhost,const string &app,const string &stream,const string &file_path);
void startRecord(const EventPoller::Ptr &poller,const RtmpMediaSource::Ptr &media,const string &file_path);
private:
virtual void onWrite(const Buffer::Ptr &data) override ;
virtual void onDetach() override;
virtual std::shared_ptr<FlvMuxer> getSharedPtr() override;
private:
std::shared_ptr<FILE> _file;
recursive_mutex _file_mtx;
};
}//namespace mediakit
#endif //ZLMEDIAKIT_FLVMUXER_H

103
src/Rtmp/RtmpCodec.h Normal file
View File

@@ -0,0 +1,103 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef ZLMEDIAKIT_RTMPCODEC_H
#define ZLMEDIAKIT_RTMPCODEC_H
#include "Rtmp/Rtmp.h"
#include "Extension/Frame.h"
#include "Util/RingBuffer.h"
using namespace toolkit;
namespace mediakit{
class RtmpRingInterface {
public:
typedef RingBuffer<RtmpPacket::Ptr> RingType;
typedef std::shared_ptr<RtmpRingInterface> Ptr;
RtmpRingInterface(){}
virtual ~RtmpRingInterface(){}
/**
* 获取rtmp环形缓存
* @return
*/
virtual RingType::Ptr getRtmpRing() const = 0;
/**
* 设置rtmp环形缓存
* @param ring
*/
virtual void setRtmpRing(const RingType::Ptr &ring) = 0;
/**
* 输入rtmp包
* @param rtmp rtmp包
* @param key_pos 是否为关键帧
* @return 是否为关键帧
*/
virtual bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos) = 0;
};
class RtmpRing : public RtmpRingInterface {
public:
typedef std::shared_ptr<RtmpRing> Ptr;
RtmpRing(){
}
virtual ~RtmpRing(){}
RingType::Ptr getRtmpRing() const override {
return _rtmpRing;
}
void setRtmpRing(const RingType::Ptr &ring) override {
_rtmpRing = ring;
}
bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos) override{
if(_rtmpRing){
_rtmpRing->write(rtmp,key_pos);
}
return key_pos;
}
protected:
RingType::Ptr _rtmpRing;
};
class RtmpCodec : public RtmpRing, public FrameRingInterfaceDelegate , public CodecInfo{
public:
typedef std::shared_ptr<RtmpCodec> Ptr;
RtmpCodec(){}
virtual ~RtmpCodec(){}
};
}//namespace mediakit
#endif //ZLMEDIAKIT_RTMPCODEC_H

116
src/Rtmp/RtmpDemuxer.cpp Normal file
View File

@@ -0,0 +1,116 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "RtmpDemuxer.h"
#include "Extension/Factory.h"
namespace mediakit {
RtmpDemuxer::RtmpDemuxer(const AMFValue &val) {
try {
makeVideoTrack(val["videocodecid"]);
makeAudioTrack(val["audiocodecid"]);
val.object_for_each([&](const string &key, const AMFValue &val) {
if (key == "duration") {
_fDuration = val.as_number();
return;
}
});
}catch (std::exception &ex){
WarnL << ex.what();
}
}
int RtmpDemuxer::getTrackCount(const AMFValue &metedata) {
return (int)(metedata["videocodecid"].type() != AMF_NULL) + (int)(metedata["audiocodecid"].type() != AMF_NULL);
}
bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
switch (pkt->typeId) {
case MSG_VIDEO: {
if(!_tryedGetVideoTrack){
_tryedGetVideoTrack = true;
auto codec = AMFValue(pkt->getMediaType());
makeVideoTrack(codec);
}
if(_videoRtmpDecoder){
return _videoRtmpDecoder->inputRtmp(pkt, true);
}
return false;
}
case MSG_AUDIO: {
if(!_tryedGetAudioTrack) {
_tryedGetAudioTrack = true;
auto codec = AMFValue(pkt->getMediaType());
makeAudioTrack(codec);
}
if(_audioRtmpDecoder){
_audioRtmpDecoder->inputRtmp(pkt, false);
return false;
}
return false;
}
default:
return false;
}
}
void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
//生成Track对象
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackByAmf(videoCodec));
if (_videoTrack) {
//生成rtmpCodec对象以便解码rtmp
_videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
if (_videoRtmpDecoder) {
//设置rtmp解码器代理生成的frame写入该Track
_videoRtmpDecoder->addDelegate(_videoTrack);
} else {
//找不到相应的rtmp解码器该track无效
_videoTrack.reset();
}
}
}
void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
//生成Track对象
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackByAmf(audioCodec));
if (_audioTrack) {
//生成rtmpCodec对象以便解码rtmp
_audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
if (_audioRtmpDecoder) {
//设置rtmp解码器代理生成的frame写入该Track
_audioRtmpDecoder->addDelegate(_audioTrack);
} else {
//找不到相应的rtmp解码器该track无效
_audioTrack.reset();
}
}
}
} /* namespace mediakit */

84
src/Rtmp/RtmpDemuxer.h Normal file
View File

@@ -0,0 +1,84 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef SRC_RTMP_RTMPDEMUXER_H_
#define SRC_RTMP_RTMPDEMUXER_H_
#include <functional>
#include <unordered_map>
#include "Rtmp/amf.h"
#include "Rtmp/Rtmp.h"
#include "Player/PlayerBase.h"
#include "Util/TimeTicker.h"
#include "RtmpCodec.h"
using namespace toolkit;
namespace mediakit {
class RtmpDemuxer : public Demuxer{
public:
typedef std::shared_ptr<RtmpDemuxer> Ptr;
/**
* 等效于RtmpDemuxer(AMFValue(AMF_NULL))
*/
RtmpDemuxer(){}
/**
* 构造rtmp解复用器
* @param val rtmp的metedata可以传入null类型
* 这样就会在inputRtmp时异步探测媒体编码格式
*/
RtmpDemuxer(const AMFValue &val);
virtual ~RtmpDemuxer(){};
/**
*
* 获取rtmp track 数
* @param metedata rtmp的metedata
* @return
*/
static int getTrackCount(const AMFValue &metedata);
/**
* 开始解复用
* @param pkt rtmp包
* @return true 代表是i帧
*/
bool inputRtmp(const RtmpPacket::Ptr &pkt);
private:
void makeVideoTrack(const AMFValue &val);
void makeAudioTrack(const AMFValue &val);
private:
bool _tryedGetVideoTrack = false;
bool _tryedGetAudioTrack = false;
RtmpCodec::Ptr _audioRtmpDecoder;
RtmpCodec::Ptr _videoRtmpDecoder;
};
} /* namespace mediakit */
#endif /* SRC_RTMP_RTMPDEMUXER_H_ */

View File

@@ -34,7 +34,7 @@
#include <unordered_map>
#include "amf.h"
#include "Rtmp.h"
#include "RtmpMuxer/RtmpDemuxer.h"
#include "RtmpDemuxer.h"
#include "Common/config.h"
#include "Common/MediaSource.h"
#include "Util/util.h"

View File

@@ -0,0 +1,64 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef ZLMEDIAKIT_RTMPMEDIASOURCEMUXER_H
#define ZLMEDIAKIT_RTMPMEDIASOURCEMUXER_H
#include "RtmpMuxer.h"
#include "Rtmp/RtmpMediaSource.h"
namespace mediakit {
class RtmpMediaSourceMuxer : public RtmpMuxer {
public:
typedef std::shared_ptr<RtmpMediaSourceMuxer> Ptr;
RtmpMediaSourceMuxer(const string &vhost,
const string &strApp,
const string &strId,
const TitleMete::Ptr &title = nullptr) : RtmpMuxer(title){
_mediaSouce = std::make_shared<RtmpMediaSource>(vhost,strApp,strId);
getRtmpRing()->setDelegate(_mediaSouce);
}
virtual ~RtmpMediaSourceMuxer(){}
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
_mediaSouce->setListener(listener);
}
int readerCount() const{
return _mediaSouce->readerCount();
}
private:
void onAllTrackReady() override {
_mediaSouce->onGetMetaData(getMetedata());
}
private:
RtmpMediaSource::Ptr _mediaSouce;
};
}//namespace mediakit
#endif //ZLMEDIAKIT_RTMPMEDIASOURCEMUXER_H

87
src/Rtmp/RtmpMuxer.cpp Normal file
View File

@@ -0,0 +1,87 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "RtmpMuxer.h"
#include "Extension/Factory.h"
namespace mediakit {
RtmpMuxer::RtmpMuxer(const TitleMete::Ptr &title) {
if(!title){
_metedata = std::make_shared<TitleMete>()->getMetedata();
}else{
_metedata = title->getMetedata();
}
_rtmpRing = std::make_shared<RtmpRingInterface::RingType>();
}
void RtmpMuxer::onTrackReady(const Track::Ptr &track) {
//生成rtmp编码器
//克隆该Track防止循环引用
auto encoder = Factory::getRtmpCodecByTrack(track->clone());
if (!encoder) {
return;
}
//根据track生产metedata
Metedata::Ptr metedate;
switch (track->getTrackType()){
case TrackVideo:{
metedate = std::make_shared<VideoMete>(dynamic_pointer_cast<VideoTrack>(track));
}
break;
case TrackAudio:{
metedate = std::make_shared<AudioMete>(dynamic_pointer_cast<AudioTrack>(track));
}
break;
default:
return;;
}
//添加其metedata
metedate->getMetedata().object_for_each([&](const std::string &key, const AMFValue &value){
_metedata.set(key,value);
});
//设置Track的代理这样输入frame至Track时最终数据将输出到RtmpEncoder中
track->addDelegate(encoder);
//Rtmp编码器共用同一个环形缓存
encoder->setRtmpRing(_rtmpRing);
}
const AMFValue &RtmpMuxer::getMetedata() const {
if(!isAllTrackReady()){
//尚未就绪
static AMFValue s_amf;
return s_amf;
}
return _metedata;
}
RtmpRingInterface::RingType::Ptr RtmpMuxer::getRtmpRing() const {
return _rtmpRing;
}
}/* namespace mediakit */

73
src/Rtmp/RtmpMuxer.h Normal file
View File

@@ -0,0 +1,73 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef ZLMEDIAKIT_RTMPMUXER_H
#define ZLMEDIAKIT_RTMPMUXER_H
#include "Rtmp/Rtmp.h"
#include "Extension/Frame.h"
#include "Common/MediaSink.h"
#include "RtmpCodec.h"
namespace mediakit{
class RtmpMuxer : public MediaSink{
public:
typedef std::shared_ptr<RtmpMuxer> Ptr;
/**
* 构造函数
*/
RtmpMuxer(const TitleMete::Ptr &title);
virtual ~RtmpMuxer(){}
/**
* 获取完整的SDP字符串
* @return SDP字符串
*/
const AMFValue &getMetedata() const ;
/**
* 获取rtmp环形缓存
* @return
*/
RtmpRingInterface::RingType::Ptr getRtmpRing() const;
protected:
/**
* 某track已经准备好其ready()状态返回true
* 此时代表可以获取其例如sps pps等相关信息了
* @param track
*/
void onTrackReady(const Track::Ptr & track) override ;
private:
RtmpRingInterface::RingType::Ptr _rtmpRing;
AMFValue _metedata;
};
} /* namespace mediakit */
#endif //ZLMEDIAKIT_RTMPMUXER_H

View File

@@ -32,7 +32,7 @@
#include "Common/config.h"
#include "RtmpPlayer.h"
#include "RtmpMediaSource.h"
#include "RtmpMuxer/RtmpDemuxer.h"
#include "RtmpDemuxer.h"
#include "Poller/Timer.h"
#include "Util/TimeTicker.h"
using namespace toolkit;

View File

@@ -37,9 +37,9 @@
#include "amf.h"
#include "Rtmp.h"
#include "RtmpMediaSource.h"
#include "RtmpMuxer/RtmpDemuxer.h"
#include "RtmpDemuxer.h"
#include "MediaFile/MediaRecorder.h"
#include "RtspMuxer/RtspMediaSourceMuxer.h"
#include "Rtsp/RtspMediaSourceMuxer.h"
using namespace std;
using namespace toolkit;