2022-06-11 12:56:03 +08:00
/*
2020-04-04 20:30:09 +08:00
* Copyright ( c ) 2016 The ZLMediaKit project authors . All Rights Reserved .
2018-02-02 18:19:35 +08:00
*
2021-01-17 18:31:50 +08:00
* This file is part of ZLMediaKit ( https : //github.com/xia-chu/ZLMediaKit).
2018-02-02 18:19:35 +08:00
*
2020-04-04 20:30:09 +08:00
* 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 .
2018-02-02 18:19:35 +08:00
*/
# ifndef ZLMEDIAKIT_MEDIASOURCE_H
# define ZLMEDIAKIT_MEDIASOURCE_H
# include <string>
2022-01-10 16:37:50 +08:00
# include <atomic>
2018-02-02 18:19:35 +08:00
# include <memory>
# include <functional>
2020-09-27 11:32:49 +08:00
# include "Network/Socket.h"
2019-06-28 16:48:02 +08:00
# include "Extension/Track.h"
2020-04-05 09:26:29 +08:00
# include "Record/Recorder.h"
2018-02-02 18:19:35 +08:00
2022-10-31 17:53:20 +08:00
namespace toolkit {
class Session ;
} // namespace toolkit
2019-05-27 22:32:07 +08:00
2018-10-24 17:17:55 +08:00
namespace mediakit {
2018-02-02 18:19:35 +08:00
2020-09-27 11:32:49 +08:00
enum class MediaOriginType : uint8_t {
unknown = 0 ,
rtmp_push ,
rtsp_push ,
rtp_push ,
pull ,
ffmpeg_pull ,
mp4_vod ,
2021-04-07 18:17:49 +08:00
device_chn ,
rtc_push ,
2022-06-03 15:02:07 +08:00
srt_push
2020-09-27 11:32:49 +08:00
} ;
2022-02-02 20:34:50 +08:00
std : : string getOriginTypeString ( MediaOriginType type ) ;
2020-09-27 11:32:49 +08:00
2019-05-27 18:39:43 +08:00
class MediaSource ;
2022-04-03 18:25:36 +08:00
class MediaSourceEvent {
2018-02-02 18:19:35 +08:00
public :
2020-03-23 10:21:17 +08:00
friend class MediaSource ;
2022-08-28 17:25:56 +08:00
class NotImplemented : public std : : runtime_error {
public :
template < typename . . . T >
NotImplemented ( T & & . . . args ) : std : : runtime_error ( std : : forward < T > ( args ) . . . ) { }
~ NotImplemented ( ) override = default ;
} ;
2022-11-12 21:59:48 +08:00
MediaSourceEvent ( ) = default ;
virtual ~ MediaSourceEvent ( ) = default ;
2019-12-03 16:10:02 +08:00
2020-09-27 11:32:49 +08:00
// 获取媒体源类型
virtual MediaOriginType getOriginType ( MediaSource & sender ) const { return MediaOriginType : : unknown ; }
// 获取媒体源url或者文件路径
2022-02-02 20:34:50 +08:00
virtual std : : string getOriginUrl ( MediaSource & sender ) const ;
2020-09-27 11:32:49 +08:00
// 获取媒体源客户端相关信息
2022-02-02 20:34:50 +08:00
virtual std : : shared_ptr < toolkit : : SockInfo > getOriginSock ( MediaSource & sender ) const { return nullptr ; }
2020-09-27 11:32:49 +08:00
2019-12-03 16:10:02 +08:00
// 通知拖动进度条
2020-09-06 17:52:07 +08:00
virtual bool seekTo ( MediaSource & sender , uint32_t stamp ) { return false ; }
2021-08-12 16:07:31 +08:00
// 通知暂停或恢复
virtual bool pause ( MediaSource & sender , bool pause ) { return false ; }
2021-08-09 18:28:43 +08:00
// 通知倍数
2021-08-12 16:07:31 +08:00
virtual bool speed ( MediaSource & sender , float speed ) { return false ; }
2020-09-06 17:52:07 +08:00
// 通知其停止产生流
2022-09-18 20:36:47 +08:00
virtual bool close ( MediaSource & sender ) { return false ; }
2022-08-28 17:25:56 +08:00
// 获取观看总人数,此函数一般强制重载
virtual int totalReaderCount ( MediaSource & sender ) { throw NotImplemented ( toolkit : : demangle ( typeid ( * this ) . name ( ) ) + " ::totalReaderCount not implemented " ) ; }
2020-09-12 19:09:56 +08:00
// 通知观看人数变化
virtual void onReaderChanged ( MediaSource & sender , int size ) ;
2020-07-02 18:14:39 +08:00
//流注册或注销事件
2022-09-07 11:06:39 +08:00
virtual void onRegist ( MediaSource & sender , bool regist ) { }
2022-06-11 12:56:03 +08:00
// 获取丢包率
2022-09-03 15:53:01 +08:00
virtual float getLossRate ( MediaSource & sender , TrackType type ) { return - 1 ; }
2022-08-28 17:25:56 +08:00
// 获取所在线程, 此函数一般强制重载
virtual toolkit : : EventPoller : : Ptr getOwnerPoller ( MediaSource & sender ) { throw NotImplemented ( toolkit : : demangle ( typeid ( * this ) . name ( ) ) + " ::getOwnerPoller not implemented " ) ; }
2022-06-11 12:31:06 +08:00
2020-09-06 17:52:07 +08:00
////////////////////////仅供MultiMediaSourceMuxer对象继承////////////////////////
// 开启或关闭录制
2022-02-02 20:34:50 +08:00
virtual bool setupRecord ( MediaSource & sender , Recorder : : type type , bool start , const std : : string & custom_path , size_t max_second ) { return false ; } ;
2020-09-06 17:52:07 +08:00
// 获取录制状态
2022-09-07 11:06:39 +08:00
virtual bool isRecording ( MediaSource & sender , Recorder : : type type ) { return false ; }
2020-09-06 17:54:52 +08:00
// 获取所有track相关信息
2022-02-02 20:34:50 +08:00
virtual std : : vector < Track : : Ptr > getMediaTracks ( MediaSource & sender , bool trackReady = true ) const { return std : : vector < Track : : Ptr > ( ) ; } ;
2022-04-03 18:25:36 +08:00
class SendRtpArgs {
public :
// 是否采用udp方式发送rtp
bool is_udp = true ;
// rtp采用ps还是es方式
bool use_ps = true ;
//发送es流时指定是否只发送纯音频流
bool only_audio = true ;
2022-05-14 23:25:22 +08:00
//tcp被动方式
bool passive = false ;
2022-04-03 18:25:36 +08:00
// rtp payload type
uint8_t pt = 96 ;
// 指定rtp ssrc
std : : string ssrc ;
// 指定本地发送端口
uint16_t src_port = 0 ;
// 发送目标端口
uint16_t dst_port ;
// 发送目标主机地址, 可以是ip或域名
std : : string dst_url ;
2022-08-20 12:48:27 +08:00
//udp发送时, 是否开启rr rtcp接收超时判断
bool udp_rtcp_timeout = false ;
//tcp被动发送服务器延时关闭事件, 单位毫秒
uint32_t tcp_passive_close_delay_ms = 5 * 1000 ;
//udp 发送时, rr rtcp包接收超时时间, 单位毫秒
uint32_t rtcp_timeout_ms = 30 * 1000 ;
//udp 发送时, 发送sr rtcp包间隔, 单位毫秒
uint32_t rtcp_send_interval_ms = 5 * 1000 ;
2023-01-07 22:36:30 +08:00
//发送rtp同时接收, 一般用于双向语言对讲, 如果不为空,说明开启接收
std : : string recv_stream_id ;
2022-04-03 18:25:36 +08:00
} ;
2020-09-06 17:56:05 +08:00
// 开始发送ps-rtp
2022-04-03 18:25:36 +08:00
virtual void startSendRtp ( MediaSource & sender , const SendRtpArgs & args , const std : : function < void ( uint16_t , const toolkit : : SockException & ) > cb ) { cb ( 0 , toolkit : : SockException ( toolkit : : Err_other , " not implemented " ) ) ; } ;
2020-09-06 17:56:05 +08:00
// 停止发送ps-rtp
2022-02-02 20:34:50 +08:00
virtual bool stopSendRtp ( MediaSource & sender , const std : : string & ssrc ) { return false ; }
2020-09-06 17:52:07 +08:00
2020-03-23 10:21:17 +08:00
private :
2022-02-02 20:34:50 +08:00
toolkit : : Timer : : Ptr _async_close_timer ;
2018-02-02 18:19:35 +08:00
} ;
2019-05-27 18:39:43 +08:00
2022-11-12 23:54:35 +08:00
class ProtocolOption {
public :
ProtocolOption ( ) ;
//时间戳修复这一路流标志位
bool modify_stamp ;
//转协议是否开启音频
bool enable_audio ;
//添加静音音频,在关闭音频时,此开关无效
bool add_mute_audio ;
//断连续推延时,单位毫秒,默认采用配置文件
uint32_t continue_push_ms ;
//是否开启转换为hls
bool enable_hls ;
//是否开启MP4录制
bool enable_mp4 ;
//是否开启转换为rtsp/webrtc
bool enable_rtsp ;
//是否开启转换为rtmp/flv
bool enable_rtmp ;
//是否开启转换为http-ts/ws-ts
bool enable_ts ;
//是否开启转换为http-fmp4/ws-fmp4
bool enable_fmp4 ;
// hls协议是否按需生成, 如果hls.segNum配置为0(意味着hls录制), 那么hls将一直生成(不管此开关)
bool hls_demand ;
// rtsp[s]协议是否按需生成
bool rtsp_demand ;
// rtmp[s]、http[s]-flv、ws[s]-flv协议是否按需生成
bool rtmp_demand ;
// http[s]-ts协议是否按需生成
bool ts_demand ;
// http[s]-fmp4、ws[s]-fmp4协议是否按需生成
bool fmp4_demand ;
//是否将mp4录制当做观看者
bool mp4_as_player ;
//mp4切片大小, 单位秒
size_t mp4_max_second ;
//mp4录制保存路径
std : : string mp4_save_path ;
//hls录制保存路径
std : : string hls_save_path ;
template < typename MAP >
ProtocolOption ( const MAP & allArgs ) : ProtocolOption ( ) {
# define GET_OPT_VALUE(key) getArgsValue(allArgs, #key, key)
GET_OPT_VALUE ( modify_stamp ) ;
GET_OPT_VALUE ( enable_audio ) ;
GET_OPT_VALUE ( add_mute_audio ) ;
GET_OPT_VALUE ( continue_push_ms ) ;
GET_OPT_VALUE ( enable_hls ) ;
GET_OPT_VALUE ( enable_mp4 ) ;
GET_OPT_VALUE ( enable_rtsp ) ;
GET_OPT_VALUE ( enable_rtmp ) ;
GET_OPT_VALUE ( enable_ts ) ;
GET_OPT_VALUE ( enable_fmp4 ) ;
GET_OPT_VALUE ( hls_demand ) ;
GET_OPT_VALUE ( rtsp_demand ) ;
GET_OPT_VALUE ( rtmp_demand ) ;
GET_OPT_VALUE ( ts_demand ) ;
GET_OPT_VALUE ( fmp4_demand ) ;
GET_OPT_VALUE ( mp4_max_second ) ;
GET_OPT_VALUE ( mp4_as_player ) ;
GET_OPT_VALUE ( mp4_save_path ) ;
GET_OPT_VALUE ( hls_save_path ) ;
}
private :
template < typename MAP , typename KEY , typename TYPE >
static void getArgsValue ( const MAP & allArgs , const KEY & key , TYPE & value ) {
auto val = ( ( MAP & ) allArgs ) [ key ] ;
if ( ! val . empty ( ) ) {
value = ( TYPE ) val ;
}
}
} ;
2020-09-06 17:52:07 +08:00
//该对象用于拦截感兴趣的MediaSourceEvent事件
2022-10-31 17:53:20 +08:00
class MediaSourceEventInterceptor : public MediaSourceEvent {
2020-09-06 17:52:07 +08:00
public :
2022-10-31 17:53:20 +08:00
MediaSourceEventInterceptor ( ) = default ;
~ MediaSourceEventInterceptor ( ) override = default ;
2020-09-06 17:52:07 +08:00
2020-10-24 23:31:58 +08:00
void setDelegate ( const std : : weak_ptr < MediaSourceEvent > & listener ) ;
std : : shared_ptr < MediaSourceEvent > getDelegate ( ) const ;
2020-09-27 11:32:49 +08:00
MediaOriginType getOriginType ( MediaSource & sender ) const override ;
2022-02-02 20:34:50 +08:00
std : : string getOriginUrl ( MediaSource & sender ) const override ;
std : : shared_ptr < toolkit : : SockInfo > getOriginSock ( MediaSource & sender ) const override ;
2020-09-27 11:32:49 +08:00
2020-09-06 17:52:07 +08:00
bool seekTo ( MediaSource & sender , uint32_t stamp ) override ;
2021-08-12 16:07:31 +08:00
bool pause ( MediaSource & sender , bool pause ) override ;
bool speed ( MediaSource & sender , float speed ) override ;
2022-09-18 20:36:47 +08:00
bool close ( MediaSource & sender ) override ;
2020-09-06 17:52:07 +08:00
int totalReaderCount ( MediaSource & sender ) override ;
2020-09-12 19:09:56 +08:00
void onReaderChanged ( MediaSource & sender , int size ) override ;
2020-09-06 17:54:52 +08:00
void onRegist ( MediaSource & sender , bool regist ) override ;
2022-02-02 20:34:50 +08:00
bool setupRecord ( MediaSource & sender , Recorder : : type type , bool start , const std : : string & custom_path , size_t max_second ) override ;
2020-09-06 17:52:07 +08:00
bool isRecording ( MediaSource & sender , Recorder : : type type ) override ;
2022-02-02 20:34:50 +08:00
std : : vector < Track : : Ptr > getMediaTracks ( MediaSource & sender , bool trackReady = true ) const override ;
2022-04-03 18:25:36 +08:00
void startSendRtp ( MediaSource & sender , const SendRtpArgs & args , const std : : function < void ( uint16_t , const toolkit : : SockException & ) > cb ) override ;
2022-02-02 20:34:50 +08:00
bool stopSendRtp ( MediaSource & sender , const std : : string & ssrc ) override ;
2022-09-03 15:53:01 +08:00
float getLossRate ( MediaSource & sender , TrackType type ) override ;
2022-06-11 12:56:03 +08:00
toolkit : : EventPoller : : Ptr getOwnerPoller ( MediaSource & sender ) override ;
2020-10-24 23:31:58 +08:00
private :
2020-09-06 17:52:07 +08:00
std : : weak_ptr < MediaSourceEvent > _listener ;
} ;
2019-12-29 10:49:04 +08:00
/**
* 解 析 url获取媒体相关信息
*/
2022-10-31 17:53:20 +08:00
class MediaInfo {
2018-02-02 18:19:35 +08:00
public :
2022-10-31 17:53:20 +08:00
~ MediaInfo ( ) = default ;
MediaInfo ( ) = default ;
2022-02-02 20:34:50 +08:00
MediaInfo ( const std : : string & url ) { parse ( url ) ; }
void parse ( const std : : string & url ) ;
2022-10-31 17:53:20 +08:00
std : : string shortUrl ( ) const { return _vhost + " / " + _app + " / " + _streamid ; }
std : : string getUrl ( ) const { return _schema + " :// " + shortUrl ( ) ; }
2018-02-02 18:19:35 +08:00
public :
2022-10-31 17:53:20 +08:00
uint16_t _port = 0 ;
2022-02-02 20:34:50 +08:00
std : : string _full_url ;
std : : string _schema ;
std : : string _host ;
std : : string _vhost ;
std : : string _app ;
std : : string _streamid ;
std : : string _param_strs ;
2018-02-02 18:19:35 +08:00
} ;
2019-12-03 16:10:02 +08:00
/**
* 媒 体 源 , 任 何 rtsp / rtmp的直播流都源自该对象
*/
2022-02-02 20:34:50 +08:00
class MediaSource : public TrackSource , public std : : enable_shared_from_this < MediaSource > {
2018-02-02 18:19:35 +08:00
public :
2022-08-23 14:11:32 +08:00
static MediaSource & NullMediaSource ( ) ;
2021-06-16 10:14:24 +08:00
using Ptr = std : : shared_ptr < MediaSource > ;
2018-02-02 18:19:35 +08:00
2022-10-31 17:53:20 +08:00
MediaSource ( const std : : string & schema , const std : : string & vhost , const std : : string & app , const std : : string & stream_id ) ;
2021-07-20 13:15:57 +08:00
virtual ~ MediaSource ( ) ;
2019-12-03 16:10:02 +08:00
2020-09-06 17:54:52 +08:00
////////////////获取MediaSource相关信息////////////////
2019-12-03 16:10:02 +08:00
// 获取协议类型
2022-02-02 20:34:50 +08:00
const std : : string & getSchema ( ) const ;
2019-12-03 16:10:02 +08:00
// 虚拟主机
2022-02-02 20:34:50 +08:00
const std : : string & getVhost ( ) const ;
2019-12-03 16:10:02 +08:00
// 应用名
2022-02-02 20:34:50 +08:00
const std : : string & getApp ( ) const ;
2019-12-03 16:10:02 +08:00
// 流id
2022-02-02 20:34:50 +08:00
const std : : string & getId ( ) const ;
2019-12-03 16:10:02 +08:00
2022-10-31 17:53:20 +08:00
std : : string shortUrl ( ) const { return _vhost + " / " + _app + " / " + _stream_id ; }
std : : string getUrl ( ) const { return _schema + " :// " + shortUrl ( ) ; }
2022-01-10 16:37:50 +08:00
//获取对象所有权
std : : shared_ptr < void > getOwnership ( ) ;
2019-12-29 10:49:04 +08:00
// 获取所有Track
2022-02-02 20:34:50 +08:00
std : : vector < Track : : Ptr > getTracks ( bool ready = true ) const override ;
2019-12-29 10:49:04 +08:00
2020-09-06 17:54:52 +08:00
// 获取流当前时间戳
virtual uint32_t getTimeStamp ( TrackType type ) { return 0 ; } ;
// 设置时间戳
virtual void setTimeStamp ( uint32_t stamp ) { } ;
2020-10-01 11:02:00 +08:00
// 获取数据速率, 单位bytes/s
2020-12-05 12:22:17 +08:00
int getBytesSpeed ( TrackType type = TrackInvalid ) ;
2020-10-01 18:57:15 +08:00
// 获取流创建GMT unix时间戳, 单位秒
2022-10-31 17:53:20 +08:00
uint64_t getCreateStamp ( ) const { return _create_stamp ; }
2020-10-01 18:57:15 +08:00
// 获取流上线时间,单位秒
uint64_t getAliveSecond ( ) const ;
2020-10-01 11:02:00 +08:00
2020-09-06 17:54:52 +08:00
////////////////MediaSourceEvent相关接口实现////////////////
2019-12-03 16:10:02 +08:00
// 设置监听者
2020-10-24 23:31:58 +08:00
virtual void setListener ( const std : : weak_ptr < MediaSourceEvent > & listener ) ;
2019-12-29 10:49:04 +08:00
// 获取监听者
2020-10-24 23:31:58 +08:00
std : : weak_ptr < MediaSourceEvent > getListener ( bool next = false ) const ;
2019-12-29 10:49:04 +08:00
2019-12-28 16:48:11 +08:00
// 本协议获取观看者个数,可能返回本协议的观看人数,也可能返回总人数
2019-12-03 16:10:02 +08:00
virtual int readerCount ( ) = 0 ;
2019-12-28 16:48:11 +08:00
// 观看者个数,包括(hls/rtsp/rtmp)
virtual int totalReaderCount ( ) ;
2022-08-30 21:05:19 +08:00
// 获取播放器列表
virtual void getPlayerList ( const std : : function < void ( const std : : list < std : : shared_ptr < void > > & info_list ) > & cb ,
const std : : function < std : : shared_ptr < void > ( std : : shared_ptr < void > & & info ) > & on_change ) {
assert ( cb ) ;
cb ( std : : list < std : : shared_ptr < void > > ( ) ) ;
}
2019-12-29 10:49:04 +08:00
2020-09-27 11:32:49 +08:00
// 获取媒体源类型
MediaOriginType getOriginType ( ) const ;
// 获取媒体源url或者文件路径
2022-02-02 20:34:50 +08:00
std : : string getOriginUrl ( ) const ;
2020-09-27 11:32:49 +08:00
// 获取媒体源客户端相关信息
2022-02-02 20:34:50 +08:00
std : : shared_ptr < toolkit : : SockInfo > getOriginSock ( ) const ;
2020-09-27 11:32:49 +08:00
2019-12-03 16:10:02 +08:00
// 拖动进度条
2020-09-06 17:52:07 +08:00
bool seekTo ( uint32_t stamp ) ;
2022-10-31 17:53:20 +08:00
// 暂停
2021-08-12 16:07:31 +08:00
bool pause ( bool pause ) ;
2022-10-31 17:53:20 +08:00
// 倍数播放
2021-08-09 18:28:43 +08:00
bool speed ( float speed ) ;
2019-12-03 16:10:02 +08:00
// 关闭该流
bool close ( bool force ) ;
2020-09-12 19:09:56 +08:00
// 该流观看人数变化
void onReaderChanged ( int size ) ;
2020-04-05 09:26:29 +08:00
// 开启或关闭录制
2022-02-02 20:34:50 +08:00
bool setupRecord ( Recorder : : type type , bool start , const std : : string & custom_path , size_t max_second ) ;
2020-04-05 09:26:29 +08:00
// 获取录制状态
2020-09-06 17:52:33 +08:00
bool isRecording ( Recorder : : type type ) ;
2020-09-06 17:56:05 +08:00
// 开始发送ps-rtp
2022-04-03 18:25:36 +08:00
void startSendRtp ( const MediaSourceEvent : : SendRtpArgs & args , const std : : function < void ( uint16_t , const toolkit : : SockException & ) > cb ) ;
2020-09-06 17:56:05 +08:00
// 停止发送ps-rtp
2022-02-02 20:34:50 +08:00
bool stopSendRtp ( const std : : string & ssrc ) ;
2022-06-11 12:56:03 +08:00
// 获取丢包率
2022-09-03 15:53:01 +08:00
float getLossRate ( mediakit : : TrackType type ) ;
2022-06-11 12:56:03 +08:00
// 获取所在线程
toolkit : : EventPoller : : Ptr getOwnerPoller ( ) ;
2019-11-18 12:07:11 +08:00
2020-09-06 17:54:52 +08:00
////////////////static方法, 查找或生成MediaSource////////////////
2019-12-03 16:10:02 +08:00
// 同步查找流
2022-02-02 20:34:50 +08:00
static Ptr find ( const std : : string & schema , const std : : string & vhost , const std : : string & app , const std : : string & id , bool from_mp4 = false ) ;
2022-09-07 11:06:39 +08:00
static Ptr find ( const MediaInfo & info , bool from_mp4 = false ) {
return find ( info . _schema , info . _vhost , info . _app , info . _streamid , from_mp4 ) ;
}
2020-09-06 18:19:54 +08:00
2022-09-07 11:06:39 +08:00
// 忽略schema, 同步查找流, 可能返回rtmp/rtsp/hls类型
2022-02-02 20:34:50 +08:00
static Ptr find ( const std : : string & vhost , const std : : string & app , const std : : string & stream_id , bool from_mp4 = false ) ;
2020-09-06 18:19:54 +08:00
2019-12-03 16:10:02 +08:00
// 异步查找流
2022-02-02 20:34:50 +08:00
static void findAsync ( const MediaInfo & info , const std : : shared_ptr < toolkit : : Session > & session , const std : : function < void ( const Ptr & src ) > & cb ) ;
2019-12-03 16:10:02 +08:00
// 遍历所有流
2022-02-02 20:34:50 +08:00
static void for_each_media ( const std : : function < void ( const Ptr & src ) > & cb , const std : : string & schema = " " , const std : : string & vhost = " " , const std : : string & app = " " , const std : : string & stream = " " ) ;
2020-04-03 23:27:16 +08:00
// 从mp4文件生成MediaSource
2022-02-02 20:34:50 +08:00
static MediaSource : : Ptr createFromMP4 ( const std : : string & schema , const std : : string & vhost , const std : : string & app , const std : : string & stream , const std : : string & file_path = " " , bool check_app = true ) ;
2020-05-26 10:11:58 +08:00
2018-08-31 14:13:00 +08:00
protected :
2020-09-06 17:52:07 +08:00
//媒体注册
void regist ( ) ;
2020-05-26 10:11:58 +08:00
private :
2022-10-31 17:53:20 +08:00
// 媒体注销
2020-09-06 17:52:07 +08:00
bool unregist ( ) ;
2022-10-31 17:53:20 +08:00
// 触发媒体事件
2020-09-06 17:52:07 +08:00
void emitEvent ( bool regist ) ;
2020-10-01 11:02:00 +08:00
protected :
2022-08-30 21:05:19 +08:00
toolkit : : BytesSpeed _speed [ TrackMax ] ;
2020-10-01 11:02:00 +08:00
2018-02-02 18:19:35 +08:00
private :
2022-02-02 20:34:50 +08:00
std : : atomic_flag _owned { false } ;
2020-10-01 18:57:15 +08:00
time_t _create_stamp ;
2022-02-02 20:34:50 +08:00
toolkit : : Ticker _ticker ;
std : : string _schema ;
std : : string _vhost ;
std : : string _app ;
std : : string _stream_id ;
2020-09-06 17:52:07 +08:00
std : : weak_ptr < MediaSourceEvent > _listener ;
2022-10-31 17:53:20 +08:00
// 对象个数统计
2022-02-02 20:34:50 +08:00
toolkit : : ObjectStatistic < MediaSource > _statistic ;
2018-02-02 18:19:35 +08:00
} ;
2018-10-24 17:17:55 +08:00
} /* namespace mediakit */
2022-07-28 16:43:03 +08:00
# endif //ZLMEDIAKIT_MEDIASOURCE_H