mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-23 03:10:04 +08:00
整理MediaSink
This commit is contained in:
parent
c1ab73f758
commit
c55f26fba7
@ -111,21 +111,16 @@ void MediaSink::inputFrame(const Frame::Ptr &frame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaSink::isAllTrackReady() const {
|
vector<Track::Ptr> MediaSink::getTracks(bool trackReady) const{
|
||||||
return _allTrackReady;
|
vector<Track::Ptr> ret;
|
||||||
}
|
|
||||||
|
|
||||||
Track::Ptr MediaSink::getTrack(TrackType type,bool trackReady) const {
|
|
||||||
lock_guard<recursive_mutex> lck(_mtx);
|
lock_guard<recursive_mutex> lck(_mtx);
|
||||||
for (auto &pr : _track_map){
|
for (auto &pr : _track_map){
|
||||||
if(pr.second->getTrackType() == type){
|
if(trackReady && !pr.second->ready()){
|
||||||
if(!trackReady){
|
continue;
|
||||||
return pr.second;
|
|
||||||
}
|
}
|
||||||
return pr.second->ready() ? pr.second : nullptr;
|
ret.emplace_back(pr.second);
|
||||||
}
|
}
|
||||||
}
|
return std::move(ret);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,11 +38,29 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
|
class MediaSinkInterface : public FrameWriterInterface {
|
||||||
|
public:
|
||||||
|
MediaSinkInterface(){};
|
||||||
|
virtual ~MediaSinkInterface(){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加track,内部会调用Track的clone方法
|
||||||
|
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
|
||||||
|
* @param track
|
||||||
|
*/
|
||||||
|
virtual void addTrack(const Track::Ptr & track) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置track
|
||||||
|
*/
|
||||||
|
virtual void resetTracks() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该类的作用是等待Track ready()返回true也就是就绪后再通知派生类进行下一步的操作
|
* 该类的作用是等待Track ready()返回true也就是就绪后再通知派生类进行下一步的操作
|
||||||
* 目的是输入Frame前由Track截取处理下,以便获取有效的信息(譬如sps pps aa_cfg)
|
* 目的是输入Frame前由Track截取处理下,以便获取有效的信息(譬如sps pps aa_cfg)
|
||||||
*/
|
*/
|
||||||
class MediaSink : public FrameWriterInterface , public std::enable_shared_from_this<MediaSink>{
|
class MediaSink : public MediaSinkInterface , public TrackSource , public std::enable_shared_from_this<MediaSink>{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<MediaSink> Ptr;
|
typedef std::shared_ptr<MediaSink> Ptr;
|
||||||
MediaSink(){}
|
MediaSink(){}
|
||||||
@ -59,26 +77,18 @@ public:
|
|||||||
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
|
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
|
||||||
* @param track
|
* @param track
|
||||||
*/
|
*/
|
||||||
virtual void addTrack(const Track::Ptr & track);
|
void addTrack(const Track::Ptr & track) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置track
|
* 重置track
|
||||||
*/
|
*/
|
||||||
virtual void resetTracks();
|
void resetTracks() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全部Track是否都准备好了
|
* 获取所有Track
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool isAllTrackReady() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取特定类型的Track
|
|
||||||
* @param type track类型
|
|
||||||
* @param trackReady 是否获取已经准备好的Track
|
* @param trackReady 是否获取已经准备好的Track
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
Track::Ptr getTrack(TrackType type,bool trackReady = true) const;
|
vector<Track::Ptr> getTracks(bool trackReady = true) const override ;
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* 某track已经准备好,其ready()状态返回true,
|
* 某track已经准备好,其ready()状态返回true,
|
||||||
|
@ -92,7 +92,7 @@ public:
|
|||||||
string _param_strs;
|
string _param_strs;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MediaSource: public enable_shared_from_this<MediaSource> {
|
class MediaSource: public TrackSource, public enable_shared_from_this<MediaSource> {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<MediaSource> Ptr;
|
typedef std::shared_ptr<MediaSource> Ptr;
|
||||||
typedef unordered_map<string, weak_ptr<MediaSource> > StreamMap;
|
typedef unordered_map<string, weak_ptr<MediaSource> > StreamMap;
|
||||||
@ -191,14 +191,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual int readerCount() = 0;
|
virtual int readerCount() = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取track
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual vector<Track::Ptr> getTracks(bool trackReady) const{
|
|
||||||
return vector<Track::Ptr>(0);
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
void regist() ;
|
void regist() ;
|
||||||
bool unregist() ;
|
bool unregist() ;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include "Rtmp/RtmpMediaSourceMuxer.h"
|
#include "Rtmp/RtmpMediaSourceMuxer.h"
|
||||||
#include "MediaFile/MediaRecorder.h"
|
#include "MediaFile/MediaRecorder.h"
|
||||||
|
|
||||||
class MultiMediaSourceMuxer : public FrameWriterInterface{
|
class MultiMediaSourceMuxer : public MediaSink{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<MultiMediaSourceMuxer> Ptr;
|
typedef std::shared_ptr<MultiMediaSourceMuxer> Ptr;
|
||||||
|
|
||||||
@ -54,25 +54,10 @@ public:
|
|||||||
}
|
}
|
||||||
virtual ~MultiMediaSourceMuxer(){}
|
virtual ~MultiMediaSourceMuxer(){}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加音视频媒体
|
|
||||||
* @param track 媒体描述
|
|
||||||
*/
|
|
||||||
void addTrack(const Track::Ptr & track) {
|
|
||||||
if(_rtmp){
|
|
||||||
_rtmp->addTrack(track);
|
|
||||||
}
|
|
||||||
if(_rtsp){
|
|
||||||
_rtsp->addTrack(track);
|
|
||||||
}
|
|
||||||
_record->addTrack(track);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置音视频媒体
|
* 重置音视频媒体
|
||||||
*/
|
*/
|
||||||
void resetTracks() {
|
void resetTracks() override{
|
||||||
if(_rtmp){
|
if(_rtmp){
|
||||||
_rtmp->resetTracks();
|
_rtmp->resetTracks();
|
||||||
}
|
}
|
||||||
@ -82,20 +67,6 @@ public:
|
|||||||
_record->resetTracks();
|
_record->resetTracks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 写入帧数据然后打包rtmp
|
|
||||||
* @param frame 帧数据
|
|
||||||
*/
|
|
||||||
void inputFrame(const Frame::Ptr &frame) override {
|
|
||||||
if(_rtmp) {
|
|
||||||
_rtmp->inputFrame(frame);
|
|
||||||
}
|
|
||||||
if(_rtsp) {
|
|
||||||
_rtsp->inputFrame(frame);
|
|
||||||
}
|
|
||||||
_record->inputFrame(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置事件监听器
|
* 设置事件监听器
|
||||||
* @param listener
|
* @param listener
|
||||||
@ -122,6 +93,47 @@ public:
|
|||||||
_rtsp->setTimeStamp(stamp);
|
_rtsp->setTimeStamp(stamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* 添加音视频媒体
|
||||||
|
* @param track 媒体描述
|
||||||
|
*/
|
||||||
|
void onTrackReady(const Track::Ptr & track) override {
|
||||||
|
if(_rtmp){
|
||||||
|
_rtmp->addTrack(track);
|
||||||
|
}
|
||||||
|
if(_rtsp){
|
||||||
|
_rtsp->addTrack(track);
|
||||||
|
}
|
||||||
|
_record->addTrack(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入帧数据然后打包rtmp
|
||||||
|
* @param frame 帧数据
|
||||||
|
*/
|
||||||
|
void onTrackFrame(const Frame::Ptr &frame) override {
|
||||||
|
if(_rtmp) {
|
||||||
|
_rtmp->inputFrame(frame);
|
||||||
|
}
|
||||||
|
if(_rtsp) {
|
||||||
|
_rtsp->inputFrame(frame);
|
||||||
|
}
|
||||||
|
_record->inputFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所有Track都准备就绪,触发媒体注册事件
|
||||||
|
*/
|
||||||
|
void onAllTrackReady() override{
|
||||||
|
if(_rtmp) {
|
||||||
|
_rtmp->onAllTrackReady();
|
||||||
|
}
|
||||||
|
if(_rtsp) {
|
||||||
|
_rtsp->onAllTrackReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
RtmpMediaSourceMuxer::Ptr _rtmp;
|
RtmpMediaSourceMuxer::Ptr _rtmp;
|
||||||
RtspMediaSourceMuxer::Ptr _rtsp;
|
RtspMediaSourceMuxer::Ptr _rtsp;
|
||||||
|
@ -50,7 +50,7 @@ typedef enum {
|
|||||||
TrackVideo = 0,
|
TrackVideo = 0,
|
||||||
TrackAudio,
|
TrackAudio,
|
||||||
TrackTitle,
|
TrackTitle,
|
||||||
TrackMax = 0x7FFF
|
TrackMax = 3
|
||||||
} TrackType;
|
} TrackType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,6 +131,37 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TrackSource{
|
||||||
|
public:
|
||||||
|
TrackSource(){}
|
||||||
|
virtual ~TrackSource(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部的Track
|
||||||
|
* @param trackReady 是否获取全部已经准备好的Track
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual vector<Track::Ptr> getTracks(bool trackReady = true) const {
|
||||||
|
return vector<Track::Ptr>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取特定Track
|
||||||
|
* @param type track类型
|
||||||
|
* @param trackReady 是否获取全部已经准备好的Track
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Track::Ptr getTrack(TrackType type , bool trackReady = true) const {
|
||||||
|
auto tracks = getTracks(trackReady);
|
||||||
|
for(auto &track : tracks){
|
||||||
|
if(track->getTrackType() == type){
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
|
||||||
#endif //ZLMEDIAKIT_TRACK_H
|
#endif //ZLMEDIAKIT_TRACK_H
|
||||||
|
@ -67,8 +67,12 @@ void MP4MuxerBase::init(int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
void MP4Muxer::resetTracks() {
|
||||||
|
_codec_to_trackid.clear();
|
||||||
|
_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
void MP4Muxer::onTrackFrame(const Frame::Ptr &frame) {
|
void MP4Muxer::inputFrame(const Frame::Ptr &frame) {
|
||||||
if(frame->configFrame()){
|
if(frame->configFrame()){
|
||||||
//忽略配置帧
|
//忽略配置帧
|
||||||
return;
|
return;
|
||||||
@ -117,7 +121,7 @@ void MP4Muxer::onTrackFrame(const Frame::Ptr &frame) {
|
|||||||
with_nalu_size);
|
with_nalu_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4Muxer::onTrackReady(const Track::Ptr &track) {
|
void MP4Muxer::addTrack(const Track::Ptr &track) {
|
||||||
switch (track->getCodecId()) {
|
switch (track->getCodecId()) {
|
||||||
case CodecAAC: {
|
case CodecAAC: {
|
||||||
auto aac_track = dynamic_pointer_cast<AACTrack>(track);
|
auto aac_track = dynamic_pointer_cast<AACTrack>(track);
|
||||||
@ -210,7 +214,12 @@ void MP4Muxer::onTrackReady(const Track::Ptr &track) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MP4MuxerFile::MP4MuxerFile(const char *file) {
|
MP4MuxerFile::MP4MuxerFile(const char *file){
|
||||||
|
_file_name = file;
|
||||||
|
openFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MP4MuxerFile::openFile(const char *file) {
|
||||||
//创建文件
|
//创建文件
|
||||||
auto fp = File::createfile_file(file,"wb+");
|
auto fp = File::createfile_file(file,"wb+");
|
||||||
if(!fp){
|
if(!fp){
|
||||||
@ -237,7 +246,6 @@ MP4MuxerFile::MP4MuxerFile(const char *file) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
GET_CONFIG(bool, mp4FastStart, Record::kFastStart);
|
GET_CONFIG(bool, mp4FastStart, Record::kFastStart);
|
||||||
|
|
||||||
init(mp4FastStart ? MOV_FLAG_FASTSTART : 0);
|
init(mp4FastStart ? MOV_FLAG_FASTSTART : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +272,12 @@ uint64_t MP4MuxerFile::onTell() {
|
|||||||
return ftell64(_file.get());
|
return ftell64(_file.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MP4MuxerFile::resetTracks(){
|
||||||
|
MP4Muxer::resetTracks();
|
||||||
|
openFile(_file_name.data());
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
|
||||||
#endif//#ifdef ENABLE_MP4RECORD
|
#endif//#ifdef ENABLE_MP4RECORD
|
||||||
|
@ -57,23 +57,24 @@ protected:
|
|||||||
std::shared_ptr<mov_writer_t> _mov_writter;
|
std::shared_ptr<mov_writer_t> _mov_writter;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MP4Muxer : public MediaSink , public MP4MuxerBase{
|
class MP4Muxer : public MediaSinkInterface , public MP4MuxerBase{
|
||||||
public:
|
public:
|
||||||
MP4Muxer() = default;
|
MP4Muxer() = default;
|
||||||
~MP4Muxer() override = default;
|
~MP4Muxer() override = default;
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* 某track已经准备好,其ready()状态返回true,
|
|
||||||
* 此时代表可以获取其例如sps pps等相关信息了
|
|
||||||
* @param track
|
|
||||||
*/
|
|
||||||
void onTrackReady(const Track::Ptr & track) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
|
* 添加已经ready状态的track
|
||||||
* @param frame
|
|
||||||
*/
|
*/
|
||||||
void onTrackFrame(const Frame::Ptr &frame) override;
|
void addTrack(const Track::Ptr & track) override;
|
||||||
|
/**
|
||||||
|
* 输入帧
|
||||||
|
*/
|
||||||
|
void inputFrame(const Frame::Ptr &frame) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置所有track
|
||||||
|
*/
|
||||||
|
void resetTracks() override ;
|
||||||
private:
|
private:
|
||||||
struct track_info{
|
struct track_info{
|
||||||
int track_id = -1;
|
int track_id = -1;
|
||||||
@ -89,13 +90,16 @@ public:
|
|||||||
typedef std::shared_ptr<MP4MuxerFile> Ptr;
|
typedef std::shared_ptr<MP4MuxerFile> Ptr;
|
||||||
MP4MuxerFile(const char *file);
|
MP4MuxerFile(const char *file);
|
||||||
~MP4MuxerFile();
|
~MP4MuxerFile();
|
||||||
|
void resetTracks() override ;
|
||||||
protected:
|
protected:
|
||||||
int onRead(void* data, uint64_t bytes) override;
|
int onRead(void* data, uint64_t bytes) override;
|
||||||
int onWrite(const void* data, uint64_t bytes) override;
|
int onWrite(const void* data, uint64_t bytes) override;
|
||||||
int onSeek( uint64_t offset) override;
|
int onSeek( uint64_t offset) override;
|
||||||
uint64_t onTell() override ;
|
uint64_t onTell() override ;
|
||||||
|
void openFile(const char *file);
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<FILE> _file;
|
std::shared_ptr<FILE> _file;
|
||||||
|
string _file_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
@ -128,7 +128,7 @@ void MP4Recorder::closeFile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4Recorder::onTrackFrame(const Frame::Ptr &frame) {
|
void MP4Recorder::inputFrame(const Frame::Ptr &frame) {
|
||||||
GET_CONFIG(uint32_t,recordSec,Record::kFileSecond);
|
GET_CONFIG(uint32_t,recordSec,Record::kFileSecond);
|
||||||
if(!_muxer || ((_createFileTicker.elapsedTime() > recordSec * 1000) &&
|
if(!_muxer || ((_createFileTicker.elapsedTime() > recordSec * 1000) &&
|
||||||
(!_haveVideo || (_haveVideo && frame->keyFrame()))) ){
|
(!_haveVideo || (_haveVideo && frame->keyFrame()))) ){
|
||||||
@ -145,7 +145,7 @@ void MP4Recorder::onTrackFrame(const Frame::Ptr &frame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4Recorder::onTrackReady(const Track::Ptr & track){
|
void MP4Recorder::addTrack(const Track::Ptr & track){
|
||||||
//保存所有的track,为创建MP4MuxerFile做准备
|
//保存所有的track,为创建MP4MuxerFile做准备
|
||||||
_tracks.emplace_back(track);
|
_tracks.emplace_back(track);
|
||||||
if(track->getTrackType() == TrackVideo){
|
if(track->getTrackType() == TrackVideo){
|
||||||
@ -158,7 +158,6 @@ void MP4Recorder::resetTracks() {
|
|||||||
_tracks.clear();
|
_tracks.clear();
|
||||||
_haveVideo = false;
|
_haveVideo = false;
|
||||||
_createFileTicker.resetTime();
|
_createFileTicker.resetTime();
|
||||||
MediaSink::resetTracks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
string strStreamId;//流ID
|
string strStreamId;//流ID
|
||||||
string strVhost;//vhost
|
string strVhost;//vhost
|
||||||
};
|
};
|
||||||
class MP4Recorder : public MediaSink{
|
class MP4Recorder : public MediaSinkInterface{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<MP4Recorder> Ptr;
|
typedef std::shared_ptr<MP4Recorder> Ptr;
|
||||||
MP4Recorder(const string &strPath,
|
MP4Recorder(const string &strPath,
|
||||||
@ -68,19 +68,16 @@ public:
|
|||||||
* 重置所有Track
|
* 重置所有Track
|
||||||
*/
|
*/
|
||||||
void resetTracks() override;
|
void resetTracks() override;
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
|
|
||||||
* @param frame
|
|
||||||
*/
|
|
||||||
void onTrackFrame(const Frame::Ptr &frame) override ;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 某track已经准备好,其ready()状态返回true,
|
* 输入frame
|
||||||
* 此时代表可以获取其例如sps pps等相关信息了
|
|
||||||
* @param track
|
|
||||||
*/
|
*/
|
||||||
void onTrackReady(const Track::Ptr & track) override;
|
void inputFrame(const Frame::Ptr &frame) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加ready状态的track
|
||||||
|
*/
|
||||||
|
void addTrack(const Track::Ptr & track) override;
|
||||||
private:
|
private:
|
||||||
void createFile();
|
void createFile();
|
||||||
void closeFile();
|
void closeFile();
|
||||||
|
@ -37,7 +37,7 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
class MediaRecorder : public MediaSink{
|
class MediaRecorder : public MediaSinkInterface{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<MediaRecorder> Ptr;
|
typedef std::shared_ptr<MediaRecorder> Ptr;
|
||||||
MediaRecorder(const string &strVhost,
|
MediaRecorder(const string &strVhost,
|
||||||
|
@ -38,7 +38,7 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
class TsMuxer : public MediaSink {
|
class TsMuxer : public MediaSinkInterface {
|
||||||
public:
|
public:
|
||||||
TsMuxer();
|
TsMuxer();
|
||||||
virtual ~TsMuxer();
|
virtual ~TsMuxer();
|
||||||
|
@ -41,7 +41,7 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
class DemuxerBase {
|
class DemuxerBase : public TrackSource{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<DemuxerBase> Ptr;
|
typedef std::shared_ptr<DemuxerBase> Ptr;
|
||||||
|
|
||||||
@ -57,29 +57,6 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual bool isInited(int analysisMs) { return true; }
|
virtual bool isInited(int analysisMs) { return true; }
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取全部的Track
|
|
||||||
* @param trackReady 是否获取全部已经准备好的Track
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual vector<Track::Ptr> getTracks(bool trackReady = true) const { return vector<Track::Ptr>();}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取特定Track
|
|
||||||
* @param type track类型
|
|
||||||
* @param trackReady 是否获取全部已经准备好的Track
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual Track::Ptr getTrack(TrackType type , bool trackReady = true) const {
|
|
||||||
auto tracks = getTracks(trackReady);
|
|
||||||
for(auto &track : tracks){
|
|
||||||
if(track->getTrackType() == type){
|
|
||||||
return track;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -274,14 +251,14 @@ public:
|
|||||||
bool isInited(int analysisMs) override;
|
bool isInited(int analysisMs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有可用Track,请在isInited()返回true时调用
|
* 获取所有Track
|
||||||
* @return
|
* @return 所有Track
|
||||||
*/
|
*/
|
||||||
vector<Track::Ptr> getTracks(bool trackReady = true) const override;
|
vector<Track::Ptr> getTracks(bool trackReady = true) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取节目总时长
|
* 获取节目总时长
|
||||||
* @return
|
* @return 节目总时长,单位秒
|
||||||
*/
|
*/
|
||||||
float getDuration() const override;
|
float getDuration() const override;
|
||||||
protected:
|
protected:
|
||||||
|
@ -48,11 +48,12 @@ public:
|
|||||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||||
_mediaSouce->setListener(listener);
|
_mediaSouce->setListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
int readerCount() const{
|
int readerCount() const{
|
||||||
return _mediaSouce->readerCount();
|
return _mediaSouce->readerCount();
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
void onAllTrackReady() override {
|
void onAllTrackReady(){
|
||||||
_mediaSouce->onGetMetaData(getMetadata());
|
_mediaSouce->onGetMetaData(getMetadata());
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -38,13 +38,7 @@ RtmpMuxer::RtmpMuxer(const TitleMeta::Ptr &title) {
|
|||||||
_rtmpRing = std::make_shared<RtmpRingInterface::RingType>();
|
_rtmpRing = std::make_shared<RtmpRingInterface::RingType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtmpMuxer::onTrackReady(const Track::Ptr &track) {
|
void RtmpMuxer::addTrack(const Track::Ptr &track) {
|
||||||
//生成rtmp编码器
|
|
||||||
//克隆该Track,防止循环引用
|
|
||||||
auto encoder = Factory::getRtmpCodecByTrack(track->clone());
|
|
||||||
if (!encoder) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//根据track生产metadata
|
//根据track生产metadata
|
||||||
Metadata::Ptr metadata;
|
Metadata::Ptr metadata;
|
||||||
switch (track->getTrackType()){
|
switch (track->getTrackType()){
|
||||||
@ -57,26 +51,34 @@ void RtmpMuxer::onTrackReady(const Track::Ptr &track) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &encoder = _encoder[track->getTrackType()];
|
||||||
|
//生成rtmp编码器,克隆该Track,防止循环引用
|
||||||
|
encoder = Factory::getRtmpCodecByTrack(track->clone());
|
||||||
|
if (!encoder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置rtmp输出环形缓存
|
||||||
|
encoder->setRtmpRing(_rtmpRing);
|
||||||
|
|
||||||
//添加其metadata
|
//添加其metadata
|
||||||
metadata->getMetadata().object_for_each([&](const std::string &key, const AMFValue &value){
|
metadata->getMetadata().object_for_each([&](const std::string &key, const AMFValue &value){
|
||||||
_metadata.set(key,value);
|
_metadata.set(key,value);
|
||||||
});
|
});
|
||||||
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtmpEncoder中
|
|
||||||
track->addDelegate(encoder);
|
|
||||||
//Rtmp编码器共用同一个环形缓存
|
|
||||||
encoder->setRtmpRing(_rtmpRing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtmpMuxer::inputFrame(const Frame::Ptr &frame) {
|
||||||
|
auto &encoder = _encoder[frame->getTrackType()];
|
||||||
|
if(encoder){
|
||||||
|
encoder->inputFrame(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const AMFValue &RtmpMuxer::getMetadata() const {
|
const AMFValue &RtmpMuxer::getMetadata() const {
|
||||||
if(!isAllTrackReady()){
|
|
||||||
//尚未就绪
|
|
||||||
static AMFValue s_amf;
|
|
||||||
return s_amf;
|
|
||||||
}
|
|
||||||
return _metadata;
|
return _metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,4 +86,12 @@ RtmpRingInterface::RingType::Ptr RtmpMuxer::getRtmpRing() const {
|
|||||||
return _rtmpRing;
|
return _rtmpRing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtmpMuxer::resetTracks() {
|
||||||
|
_metadata.clear();
|
||||||
|
for(auto &encoder : _encoder){
|
||||||
|
encoder = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}/* namespace mediakit */
|
}/* namespace mediakit */
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
class RtmpMuxer : public MediaSink{
|
class RtmpMuxer : public MediaSinkInterface{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<RtmpMuxer> Ptr;
|
typedef std::shared_ptr<RtmpMuxer> Ptr;
|
||||||
|
|
||||||
@ -55,16 +55,26 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
RtmpRingInterface::RingType::Ptr getRtmpRing() const;
|
RtmpRingInterface::RingType::Ptr getRtmpRing() const;
|
||||||
protected:
|
|
||||||
/**
|
/**
|
||||||
* 某track已经准备好,其ready()状态返回true,
|
* 添加ready状态的track
|
||||||
* 此时代表可以获取其例如sps pps等相关信息了
|
|
||||||
* @param track
|
|
||||||
*/
|
*/
|
||||||
void onTrackReady(const Track::Ptr & track) override ;
|
void addTrack(const Track::Ptr & track) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入帧数据
|
||||||
|
* @param frame 帧
|
||||||
|
*/
|
||||||
|
void inputFrame(const Frame::Ptr &frame) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置所有track
|
||||||
|
*/
|
||||||
|
void resetTracks() override ;
|
||||||
private:
|
private:
|
||||||
RtmpRingInterface::RingType::Ptr _rtmpRing;
|
RtmpRingInterface::RingType::Ptr _rtmpRing;
|
||||||
AMFValue _metadata;
|
AMFValue _metadata;
|
||||||
|
RtmpCodec::Ptr _encoder[TrackMax];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,14 +48,16 @@ public:
|
|||||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||||
_mediaSouce->setListener(listener);
|
_mediaSouce->setListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
int readerCount() const{
|
int readerCount() const{
|
||||||
return _mediaSouce->readerCount();
|
return _mediaSouce->readerCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTimeStamp(uint32_t stamp){
|
void setTimeStamp(uint32_t stamp){
|
||||||
_mediaSouce->setTimeStamp(stamp);
|
_mediaSouce->setTimeStamp(stamp);
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
void onAllTrackReady() override {
|
void onAllTrackReady(){
|
||||||
_mediaSouce->onGetSDP(getSdp());
|
_mediaSouce->onGetSDP(getSdp());
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -38,29 +38,34 @@ RtspMuxer::RtspMuxer(const TitleSdp::Ptr &title){
|
|||||||
_rtpRing = std::make_shared<RtpRingInterface::RingType>();
|
_rtpRing = std::make_shared<RtpRingInterface::RingType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtspMuxer::onTrackReady(const Track::Ptr &track) {
|
void RtspMuxer::addTrack(const Track::Ptr &track) {
|
||||||
//根据track生成sdp
|
//根据track生成sdp
|
||||||
Sdp::Ptr sdp = track->getSdp();
|
Sdp::Ptr sdp = track->getSdp();
|
||||||
if (!sdp) {
|
if (!sdp) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto encoder = Factory::getRtpEncoderBySdp(sdp);
|
|
||||||
|
auto &encoder = _encoder[track->getTrackType()];
|
||||||
|
encoder = Factory::getRtpEncoderBySdp(sdp);
|
||||||
if (!encoder) {
|
if (!encoder) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//设置rtp输出环形缓存
|
||||||
|
encoder->setRtpRing(_rtpRing);
|
||||||
|
|
||||||
//添加其sdp
|
//添加其sdp
|
||||||
_sdp.append(sdp->getSdp());
|
_sdp.append(sdp->getSdp());
|
||||||
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtpEncoder中
|
}
|
||||||
track->addDelegate(encoder);
|
|
||||||
//rtp编码器共用同一个环形缓存
|
void RtspMuxer::inputFrame(const Frame::Ptr &frame) {
|
||||||
encoder->setRtpRing(_rtpRing);
|
auto &encoder = _encoder[frame->getTrackType()];
|
||||||
|
if(encoder){
|
||||||
|
encoder->inputFrame(frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string RtspMuxer::getSdp() {
|
string RtspMuxer::getSdp() {
|
||||||
if(!isAllTrackReady()){
|
|
||||||
//尚未就绪
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return _sdp;
|
return _sdp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,5 +73,12 @@ RtpRingInterface::RingType::Ptr RtspMuxer::getRtpRing() const {
|
|||||||
return _rtpRing;
|
return _rtpRing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtspMuxer::resetTracks() {
|
||||||
|
_sdp.clear();
|
||||||
|
for(auto &encoder : _encoder){
|
||||||
|
encoder = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
@ -35,7 +35,7 @@ namespace mediakit{
|
|||||||
/**
|
/**
|
||||||
* rtsp生成器
|
* rtsp生成器
|
||||||
*/
|
*/
|
||||||
class RtspMuxer : public MediaSink{
|
class RtspMuxer : public MediaSinkInterface{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<RtspMuxer> Ptr;
|
typedef std::shared_ptr<RtspMuxer> Ptr;
|
||||||
|
|
||||||
@ -57,16 +57,26 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
RtpRingInterface::RingType::Ptr getRtpRing() const;
|
RtpRingInterface::RingType::Ptr getRtpRing() const;
|
||||||
protected:
|
|
||||||
/**
|
/**
|
||||||
* 某track已经准备好,其ready()状态返回true,
|
* 添加ready状态的track
|
||||||
* 此时代表可以获取其例如sps pps等相关信息了
|
|
||||||
* @param track
|
|
||||||
*/
|
*/
|
||||||
void onTrackReady(const Track::Ptr & track) override ;
|
void addTrack(const Track::Ptr & track) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入帧数据
|
||||||
|
* @param frame 帧
|
||||||
|
*/
|
||||||
|
void inputFrame(const Frame::Ptr &frame) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置所有track
|
||||||
|
*/
|
||||||
|
void resetTracks() override ;
|
||||||
private:
|
private:
|
||||||
RtpRingInterface::RingType::Ptr _rtpRing;
|
|
||||||
string _sdp;
|
string _sdp;
|
||||||
|
RtpCodec::Ptr _encoder[TrackMax];
|
||||||
|
RtpRingInterface::RingType::Ptr _rtpRing;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user