2017-10-09 22:11:01 +08:00
/*
2023-12-09 16:23:51 +08:00
* Copyright ( c ) 2016 - present The ZLMediaKit project authors . All Rights Reserved .
2017-09-27 16:20:30 +08:00
*
2023-12-09 16:23:51 +08:00
* This file is part of ZLMediaKit ( https : //github.com/ZLMediaKit/ZLMediaKit).
2017-09-27 16:20:30 +08:00
*
2023-12-09 16:23:51 +08:00
* Use of this source code is governed by MIT - like license that can be found in the
2020-04-04 20:30:09 +08:00
* 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 .
2017-04-01 16:35:56 +08:00
*/
# include "PlayerProxy.h"
2023-05-03 21:46:25 +08:00
# include "Common/config.h"
2022-11-29 11:07:13 +08:00
# include "Rtmp/RtmpMediaSource.h"
# include "Rtmp/RtmpPlayer.h"
2023-05-03 21:46:25 +08:00
# include "Rtsp/RtspMediaSource.h"
2022-11-29 11:07:13 +08:00
# include "Rtsp/RtspPlayer.h"
2023-05-03 21:46:25 +08:00
# include "Util/MD5.h"
# include "Util/logger.h"
# include "Util/mini.h"
2017-04-01 16:35:56 +08:00
2018-10-24 17:17:55 +08:00
using namespace toolkit ;
2022-02-02 20:34:50 +08:00
using namespace std ;
2017-04-01 16:35:56 +08:00
2018-10-24 17:17:55 +08:00
namespace mediakit {
2017-04-01 16:35:56 +08:00
2023-05-03 21:46:25 +08:00
PlayerProxy : : PlayerProxy (
2024-07-14 09:32:41 +08:00
const MediaTuple & tuple , const ProtocolOption & option , int retry_count ,
2023-05-12 11:20:31 +08:00
const EventPoller : : Ptr & poller , int reconnect_delay_min , int reconnect_delay_max , int reconnect_delay_step )
2024-07-14 09:32:41 +08:00
: MediaPlayer ( poller ) , _tuple ( tuple ) , _option ( option ) {
2020-08-01 10:22:12 +08:00
_retry_count = retry_count ;
2023-05-03 21:46:25 +08:00
2023-05-13 00:14:35 +08:00
setOnClose ( nullptr ) ;
2023-05-12 11:20:31 +08:00
setOnConnect ( nullptr ) ;
setOnDisconnect ( nullptr ) ;
_reconnect_delay_min = reconnect_delay_min > 0 ? reconnect_delay_min : 2 ;
_reconnect_delay_max = reconnect_delay_max > 0 ? reconnect_delay_max : 60 ;
_reconnect_delay_step = reconnect_delay_step > 0 ? reconnect_delay_step : 3 ;
2023-05-03 18:52:11 +08:00
_live_secs = 0 ;
_live_status = 1 ;
_repull_count = 0 ;
2021-11-10 13:56:58 +08:00
( * this ) [ Client : : kWaitTrackReady ] = false ;
2017-04-01 16:35:56 +08:00
}
2019-05-20 18:08:55 +08:00
2023-05-13 00:14:35 +08:00
void PlayerProxy : : setPlayCallbackOnce ( function < void ( const SockException & ex ) > cb ) {
_on_play = std : : move ( cb ) ;
2019-05-20 18:08:55 +08:00
}
2019-05-27 14:14:42 +08:00
2023-05-13 00:14:35 +08:00
void PlayerProxy : : setOnClose ( function < void ( const SockException & ex ) > cb ) {
_on_close = cb ? std : : move ( cb ) : [ ] ( const SockException & ) { } ;
2019-05-27 14:14:42 +08:00
}
2023-05-12 11:20:31 +08:00
void PlayerProxy : : setOnDisconnect ( std : : function < void ( ) > cb ) {
_on_disconnect = cb ? std : : move ( cb ) : [ ] ( ) { } ;
}
void PlayerProxy : : setOnConnect ( std : : function < void ( const TranslationInfo & ) > cb ) {
_on_connect = cb ? std : : move ( cb ) : [ ] ( const TranslationInfo & ) { } ;
}
void PlayerProxy : : setTranslationInfo ( )
{
2023-05-13 00:02:06 +08:00
_transtalion_info . byte_speed = _media_src ? _media_src - > getBytesSpeed ( ) : - 1 ;
_transtalion_info . start_time_stamp = _media_src ? _media_src - > getCreateStamp ( ) : 0 ;
2023-05-12 11:20:31 +08:00
_transtalion_info . stream_info . clear ( ) ;
auto tracks = _muxer - > getTracks ( ) ;
for ( auto & track : tracks ) {
2023-11-07 23:36:41 +08:00
track - > update ( ) ;
2023-05-12 11:20:31 +08:00
_transtalion_info . stream_info . emplace_back ( ) ;
auto & back = _transtalion_info . stream_info . back ( ) ;
back . bitrate = track - > getBitRate ( ) ;
back . codec_type = track - > getTrackType ( ) ;
back . codec_name = track - > getCodecName ( ) ;
switch ( back . codec_type ) {
case TrackAudio : {
auto audio_track = dynamic_pointer_cast < AudioTrack > ( track ) ;
back . audio_sample_rate = audio_track - > getAudioSampleRate ( ) ;
back . audio_channel = audio_track - > getAudioChannel ( ) ;
back . audio_sample_bit = audio_track - > getAudioSampleBit ( ) ;
break ;
}
case TrackVideo : {
auto video_track = dynamic_pointer_cast < VideoTrack > ( track ) ;
back . video_width = video_track - > getVideoWidth ( ) ;
back . video_height = video_track - > getVideoHeight ( ) ;
back . video_fps = video_track - > getVideoFps ( ) ;
break ;
}
default :
break ;
}
}
}
2023-12-09 22:34:22 +08:00
static int getMaxTrackSize ( const std : : string & url ) {
if ( url . find ( " .m3u8 " ) ! = std : : string : : npos | | url . find ( " .ts " ) ! = std : : string : : npos ) {
2024-09-19 14:53:50 +08:00
// hls和ts协议才开放多track支持 [AUTO-TRANSLATED:6c5f8f04]
// Only hls and ts protocols support multiple tracks
2023-12-09 22:34:22 +08:00
return 16 ;
}
return 2 ;
}
2019-03-27 18:41:52 +08:00
void PlayerProxy : : play ( const string & strUrlTmp ) {
2023-12-09 22:34:22 +08:00
_option . max_track = getMaxTrackSize ( strUrlTmp ) ;
2020-03-20 11:51:24 +08:00
weak_ptr < PlayerProxy > weakSelf = shared_from_this ( ) ;
2023-05-03 21:46:25 +08:00
std : : shared_ptr < int > piFailedCnt ( new int ( 0 ) ) ; // 连续播放失败次数
2021-06-09 15:01:45 +08:00
setOnPlayResult ( [ weakSelf , strUrlTmp , piFailedCnt ] ( const SockException & err ) {
2020-03-20 11:51:24 +08:00
auto strongSelf = weakSelf . lock ( ) ;
2021-06-09 15:01:45 +08:00
if ( ! strongSelf ) {
2020-03-20 11:51:24 +08:00
return ;
}
2019-05-20 18:08:55 +08:00
2021-06-09 15:01:45 +08:00
if ( strongSelf - > _on_play ) {
2020-08-01 10:22:12 +08:00
strongSelf - > _on_play ( err ) ;
strongSelf - > _on_play = nullptr ;
2019-05-20 18:08:55 +08:00
}
2021-06-09 15:01:45 +08:00
if ( ! err ) {
2024-09-19 14:53:50 +08:00
// 取消定时器,避免hls拉流索引文件因为网络波动失败重连成功后出现循环重试的情况 [AUTO-TRANSLATED:91e5f0c8]
// Cancel the timer to avoid the situation where the hls stream index file fails to reconnect due to network fluctuations and then retries in a loop after successful reconnection
2023-05-03 18:52:11 +08:00
strongSelf - > _timer . reset ( ) ;
strongSelf - > _live_ticker . resetTime ( ) ;
strongSelf - > _live_status = 0 ;
2024-09-19 14:53:50 +08:00
// 播放成功 [AUTO-TRANSLATED:e43f9fb8]
// Play successfully
2023-05-03 21:46:25 +08:00
* piFailedCnt = 0 ; // 连续播放失败次数清0
2020-03-20 11:51:24 +08:00
strongSelf - > onPlaySuccess ( ) ;
2023-05-12 11:20:31 +08:00
strongSelf - > setTranslationInfo ( ) ;
strongSelf - > _on_connect ( strongSelf - > _transtalion_info ) ;
2023-05-03 18:52:11 +08:00
InfoL < < " play " < < strUrlTmp < < " success " ;
2021-06-09 15:01:45 +08:00
} else if ( * piFailedCnt < strongSelf - > _retry_count | | strongSelf - > _retry_count < 0 ) {
2024-09-19 14:53:50 +08:00
// 播放失败,延时重试播放 [AUTO-TRANSLATED:d7537c9c]
// Play failed, retry playing with delay
2023-05-12 11:20:31 +08:00
strongSelf - > _on_disconnect ( ) ;
2021-06-09 15:01:45 +08:00
strongSelf - > rePlay ( strUrlTmp , ( * piFailedCnt ) + + ) ;
} else {
2024-09-19 14:53:50 +08:00
// 达到了最大重试次数,回调关闭 [AUTO-TRANSLATED:610f31f3]
// Reached the maximum number of retries, callback to close
2021-06-09 15:01:45 +08:00
strongSelf - > _on_close ( err ) ;
2020-03-20 11:51:24 +08:00
}
} ) ;
2021-06-09 15:01:45 +08:00
setOnShutdown ( [ weakSelf , strUrlTmp , piFailedCnt ] ( const SockException & err ) {
2020-03-20 11:51:24 +08:00
auto strongSelf = weakSelf . lock ( ) ;
2021-06-09 15:01:45 +08:00
if ( ! strongSelf ) {
2020-03-20 11:51:24 +08:00
return ;
}
2020-10-24 23:30:25 +08:00
2024-09-19 14:53:50 +08:00
// 注销直接拉流代理产生的流:#532 [AUTO-TRANSLATED:c6343a3b]
// Unregister the stream generated by the direct stream proxy: #532
2020-10-24 23:30:25 +08:00
strongSelf - > setMediaSource ( nullptr ) ;
2021-06-09 15:01:45 +08:00
if ( strongSelf - > _muxer ) {
2020-09-06 17:54:52 +08:00
auto tracks = strongSelf - > MediaPlayer : : getTracks ( false ) ;
2021-06-09 15:01:45 +08:00
for ( auto & track : tracks ) {
2020-08-01 10:22:12 +08:00
track - > delDelegate ( strongSelf - > _muxer . get ( ) ) ;
2020-03-20 11:51:24 +08:00
}
2019-10-11 16:51:10 +08:00
2022-03-12 13:19:21 +08:00
GET_CONFIG ( bool , reset_when_replay , General : : kResetWhenRePlay ) ;
if ( reset_when_replay ) {
2020-08-01 10:22:12 +08:00
strongSelf - > _muxer . reset ( ) ;
2020-03-20 11:51:24 +08:00
} else {
2020-08-01 10:22:12 +08:00
strongSelf - > _muxer - > resetTracks ( ) ;
2020-03-20 11:51:24 +08:00
}
}
2023-05-03 18:52:11 +08:00
2023-05-03 21:46:25 +08:00
if ( * piFailedCnt = = 0 ) {
2024-09-19 14:53:50 +08:00
// 第一次重拉更新时长 [AUTO-TRANSLATED:3c414b08]
// Update the duration for the first time
2023-05-03 21:46:25 +08:00
strongSelf - > _live_secs + = strongSelf - > _live_ticker . elapsedTime ( ) / 1000 ;
2023-05-03 18:52:11 +08:00
strongSelf - > _live_ticker . resetTime ( ) ;
2023-05-03 21:46:25 +08:00
TraceL < < " live secs " < < strongSelf - > _live_secs ;
2023-05-03 18:52:11 +08:00
}
2024-09-19 14:53:50 +08:00
// 播放异常中断,延时重试播放 [AUTO-TRANSLATED:fee316b2]
// Play interrupted abnormally, retry playing with delay
2021-06-09 15:01:45 +08:00
if ( * piFailedCnt < strongSelf - > _retry_count | | strongSelf - > _retry_count < 0 ) {
2023-05-03 18:52:11 +08:00
strongSelf - > _repull_count + + ;
2021-06-09 15:01:45 +08:00
strongSelf - > rePlay ( strUrlTmp , ( * piFailedCnt ) + + ) ;
} else {
2024-09-19 14:53:50 +08:00
// 达到了最大重试次数,回调关闭 [AUTO-TRANSLATED:610f31f3]
// Reached the maximum number of retries, callback to close
2021-06-09 15:01:45 +08:00
strongSelf - > _on_close ( err ) ;
2020-03-20 11:51:24 +08:00
}
} ) ;
2023-04-24 14:32:34 +08:00
try {
MediaPlayer : : play ( strUrlTmp ) ;
} catch ( std : : exception & ex ) {
ErrorL < < ex . what ( ) ;
2023-05-13 00:14:35 +08:00
onPlayResult ( SockException ( Err_other , ex . what ( ) ) ) ;
2023-04-24 14:32:34 +08:00
return ;
}
2020-09-27 11:32:49 +08:00
_pull_url = strUrlTmp ;
2021-01-17 10:22:51 +08:00
setDirectProxy ( ) ;
}
2019-07-19 11:30:39 +08:00
2021-06-09 15:01:45 +08:00
void PlayerProxy : : setDirectProxy ( ) {
2020-03-20 11:51:24 +08:00
MediaSource : : Ptr mediaSource ;
2021-01-17 10:22:51 +08:00
if ( dynamic_pointer_cast < RtspPlayer > ( _delegate ) ) {
2024-09-19 14:53:50 +08:00
// rtsp拉流 [AUTO-TRANSLATED:189cf691]
// Rtsp stream
2021-01-17 10:22:51 +08:00
GET_CONFIG ( bool , directProxy , Rtsp : : kDirectProxy ) ;
2024-08-02 21:32:32 +08:00
if ( directProxy & & _option . enable_rtsp ) {
2023-05-25 16:23:24 +08:00
mediaSource = std : : make_shared < RtspMediaSource > ( _tuple ) ;
2020-03-20 11:51:24 +08:00
}
2021-01-17 10:22:51 +08:00
} else if ( dynamic_pointer_cast < RtmpPlayer > ( _delegate ) ) {
2024-09-19 14:53:50 +08:00
// rtmp拉流 [AUTO-TRANSLATED:f70a142c]
// Rtmp stream
2023-12-09 16:23:51 +08:00
GET_CONFIG ( bool , directProxy , Rtmp : : kDirectProxy ) ;
2024-08-02 21:32:32 +08:00
if ( directProxy & & _option . enable_rtmp ) {
2023-12-09 16:23:51 +08:00
mediaSource = std : : make_shared < RtmpMediaSource > ( _tuple ) ;
}
2020-03-20 11:51:24 +08:00
}
2021-01-17 10:22:51 +08:00
if ( mediaSource ) {
2020-10-24 23:30:06 +08:00
setMediaSource ( mediaSource ) ;
2020-03-20 11:51:24 +08:00
}
2017-04-01 16:35:56 +08:00
}
PlayerProxy : : ~ PlayerProxy ( ) {
2020-03-20 11:51:24 +08:00
_timer . reset ( ) ;
2024-09-19 14:53:50 +08:00
// 避免析构时, 忘记回调api请求 [AUTO-TRANSLATED:1ad9ad52]
// Avoid forgetting to callback api request when destructing
2023-05-03 21:46:25 +08:00
if ( _on_play ) {
2023-06-11 22:07:15 +08:00
try {
_on_play ( SockException ( Err_shutdown , " player proxy close " ) ) ;
} catch ( std : : exception & ex ) {
WarnL < < " Exception occurred: " < < ex . what ( ) ;
}
2022-04-01 20:59:58 +08:00
_on_play = nullptr ;
}
2017-04-01 16:35:56 +08:00
}
2020-08-01 10:22:12 +08:00
2021-06-09 15:01:45 +08:00
void PlayerProxy : : rePlay ( const string & strUrl , int iFailedCnt ) {
2023-05-12 11:20:31 +08:00
auto iDelay = MAX ( _reconnect_delay_min * 1000 , MIN ( iFailedCnt * _reconnect_delay_step * 1000 , _reconnect_delay_max * 1000 ) ) ;
2020-03-20 11:51:24 +08:00
weak_ptr < PlayerProxy > weakSelf = shared_from_this ( ) ;
2023-05-03 21:46:25 +08:00
_timer = std : : make_shared < Timer > (
iDelay / 1000.0f ,
[ weakSelf , strUrl , iFailedCnt ] ( ) {
2024-09-19 14:53:50 +08:00
// 播放失败次数越多,则延时越长 [AUTO-TRANSLATED:5af39264]
// The more times the playback fails, the longer the delay
2023-05-03 21:46:25 +08:00
auto strongPlayer = weakSelf . lock ( ) ;
if ( ! strongPlayer ) {
return false ;
}
WarnL < < " 重试播放[ " < < iFailedCnt < < " ]: " < < strUrl ;
strongPlayer - > MediaPlayer : : play ( strUrl ) ;
strongPlayer - > setDirectProxy ( ) ;
2020-03-20 11:51:24 +08:00
return false ;
2023-05-03 21:46:25 +08:00
} ,
getPoller ( ) ) ;
2017-04-01 16:35:56 +08:00
}
2019-07-19 11:30:39 +08:00
2022-09-18 20:36:47 +08:00
bool PlayerProxy : : close ( MediaSource & sender ) {
2024-09-19 14:53:50 +08:00
// 通知其停止推流 [AUTO-TRANSLATED:d69d10d8]
// Notify it to stop pushing the stream
2020-08-01 10:22:12 +08:00
weak_ptr < PlayerProxy > weakSelf = dynamic_pointer_cast < PlayerProxy > ( shared_from_this ( ) ) ;
getPoller ( ) - > async_first ( [ weakSelf ] ( ) {
auto strongSelf = weakSelf . lock ( ) ;
if ( ! strongSelf ) {
return ;
}
strongSelf - > _muxer . reset ( ) ;
2020-10-24 23:30:06 +08:00
strongSelf - > setMediaSource ( nullptr ) ;
2020-08-01 10:22:12 +08:00
strongSelf - > teardown ( ) ;
2020-03-20 11:51:24 +08:00
} ) ;
2021-06-09 15:01:45 +08:00
_on_close ( SockException ( Err_shutdown , " closed by user " ) ) ;
2022-09-18 20:36:47 +08:00
WarnL < < " close media: " < < sender . getUrl ( ) ;
2018-02-08 17:24:42 +08:00
return true ;
}
2017-04-01 16:35:56 +08:00
2021-06-09 15:01:45 +08:00
int PlayerProxy : : totalReaderCount ( ) {
2021-11-10 10:58:43 +08:00
return ( _muxer ? _muxer - > totalReaderCount ( ) : 0 ) + ( _media_src ? _media_src - > readerCount ( ) : 0 ) ;
2019-12-28 16:48:11 +08:00
}
int PlayerProxy : : totalReaderCount ( MediaSource & sender ) {
2020-03-20 11:51:24 +08:00
return totalReaderCount ( ) ;
2019-12-28 16:48:11 +08:00
}
2021-06-09 15:01:45 +08:00
MediaOriginType PlayerProxy : : getOriginType ( MediaSource & sender ) const {
2020-09-27 11:32:49 +08:00
return MediaOriginType : : pull ;
}
2021-06-09 15:01:45 +08:00
string PlayerProxy : : getOriginUrl ( MediaSource & sender ) const {
2020-09-27 11:32:49 +08:00
return _pull_url ;
}
2021-06-09 15:01:45 +08:00
std : : shared_ptr < SockInfo > PlayerProxy : : getOriginSock ( MediaSource & sender ) const {
2020-09-27 11:32:49 +08:00
return getSockInfo ( ) ;
}
2022-09-03 15:53:01 +08:00
float PlayerProxy : : getLossRate ( MediaSource & sender , TrackType type ) {
return getPacketLossRate ( type ) ;
}
2023-05-12 11:20:31 +08:00
TranslationInfo PlayerProxy : : getTranslationInfo ( ) {
return _transtalion_info ;
}
2018-10-26 17:14:39 +08:00
void PlayerProxy : : onPlaySuccess ( ) {
2022-03-12 13:19:21 +08:00
GET_CONFIG ( bool , reset_when_replay , General : : kResetWhenRePlay ) ;
2021-11-10 10:58:43 +08:00
if ( dynamic_pointer_cast < RtspMediaSource > ( _media_src ) ) {
2024-09-19 14:53:50 +08:00
// rtsp拉流代理 [AUTO-TRANSLATED:3935cf68]
// Rtsp stream proxy
2022-03-12 13:19:21 +08:00
if ( reset_when_replay | | ! _muxer ) {
2024-08-22 11:11:04 +08:00
auto old = _option . enable_rtsp ;
2022-03-12 13:19:21 +08:00
_option . enable_rtsp = false ;
2023-05-25 16:23:24 +08:00
_muxer = std : : make_shared < MultiMediaSourceMuxer > ( _tuple , getDuration ( ) , _option ) ;
2024-08-22 11:11:04 +08:00
_option . enable_rtsp = old ;
2020-03-20 11:51:24 +08:00
}
2021-11-10 10:58:43 +08:00
} else if ( dynamic_pointer_cast < RtmpMediaSource > ( _media_src ) ) {
2024-09-19 14:53:50 +08:00
// rtmp拉流代理 [AUTO-TRANSLATED:21173335]
// Rtmp stream proxy
2022-03-12 13:19:21 +08:00
if ( reset_when_replay | | ! _muxer ) {
2024-08-22 11:11:04 +08:00
auto old = _option . enable_rtmp ;
2022-03-12 13:19:21 +08:00
_option . enable_rtmp = false ;
2023-05-25 16:23:24 +08:00
_muxer = std : : make_shared < MultiMediaSourceMuxer > ( _tuple , getDuration ( ) , _option ) ;
2024-08-22 11:11:04 +08:00
_option . enable_rtmp = old ;
2020-03-20 11:51:24 +08:00
}
} else {
2024-09-19 14:53:50 +08:00
// 其他拉流代理 [AUTO-TRANSLATED:e5f2e45d]
// Other stream proxies
2022-03-12 13:19:21 +08:00
if ( reset_when_replay | | ! _muxer ) {
2023-05-25 16:23:24 +08:00
_muxer = std : : make_shared < MultiMediaSourceMuxer > ( _tuple , getDuration ( ) , _option ) ;
2020-03-20 11:51:24 +08:00
}
}
2020-08-01 10:22:12 +08:00
_muxer - > setMediaListener ( shared_from_this ( ) ) ;
2018-10-26 17:14:39 +08:00
2020-08-01 10:22:12 +08:00
auto videoTrack = getTrack ( TrackVideo , false ) ;
if ( videoTrack ) {
2024-09-19 14:53:50 +08:00
// 添加视频 [AUTO-TRANSLATED:afc7e0f7]
// Add video
2020-08-01 10:22:12 +08:00
_muxer - > addTrack ( videoTrack ) ;
2024-09-19 14:53:50 +08:00
// 视频数据写入_mediaMuxer [AUTO-TRANSLATED:fc07e1c9]
// Write video data to _mediaMuxer
2020-08-01 10:22:12 +08:00
videoTrack - > addDelegate ( _muxer ) ;
2020-03-20 11:51:24 +08:00
}
2018-10-26 17:14:39 +08:00
2020-03-20 11:51:24 +08:00
auto audioTrack = getTrack ( TrackAudio , false ) ;
2020-08-01 10:22:12 +08:00
if ( audioTrack ) {
2024-09-19 14:53:50 +08:00
// 添加音频 [AUTO-TRANSLATED:e08e79ce]
// Add audio
2020-08-01 10:22:12 +08:00
_muxer - > addTrack ( audioTrack ) ;
2024-09-19 14:53:50 +08:00
// 音频数据写入_mediaMuxer [AUTO-TRANSLATED:69911524]
// Write audio data to _mediaMuxer
2020-08-01 10:22:12 +08:00
audioTrack - > addDelegate ( _muxer ) ;
2020-03-20 11:51:24 +08:00
}
2019-12-17 09:05:34 +08:00
2024-09-19 14:53:50 +08:00
// 添加完毕所有track, 防止单track情况下最大等待3秒 [AUTO-TRANSLATED:8908bc01]
// After adding all tracks, prevent the maximum waiting time of 3 seconds in the case of a single track
2020-08-01 10:22:12 +08:00
_muxer - > addTrackCompleted ( ) ;
2020-02-25 14:59:40 +08:00
2021-11-10 10:58:43 +08:00
if ( _media_src ) {
2024-09-19 14:53:50 +08:00
// 让_muxer对象拦截一部分事件(比如说录像相关事件) [AUTO-TRANSLATED:7d27c400]
// Let the _muxer object intercept some events (such as recording related events)
2021-11-10 10:58:43 +08:00
_media_src - > setListener ( _muxer ) ;
2019-12-17 09:05:34 +08:00
}
2018-06-30 23:02:16 +08:00
}
2023-05-03 18:52:11 +08:00
int PlayerProxy : : getStatus ( ) {
return _live_status . load ( ) ;
}
uint64_t PlayerProxy : : getLiveSecs ( ) {
2023-05-03 21:46:25 +08:00
if ( _live_status = = 0 ) {
return _live_secs + _live_ticker . elapsedTime ( ) / 1000 ;
2023-05-03 18:52:11 +08:00
}
2023-05-13 00:14:35 +08:00
return _live_secs ;
2023-05-03 18:52:11 +08:00
}
2023-05-03 21:46:25 +08:00
uint64_t PlayerProxy : : getRePullCount ( ) {
2023-05-03 18:52:11 +08:00
return _repull_count ;
}
2018-10-24 17:17:55 +08:00
} /* namespace mediakit */