mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	fix bug #45, support duration for live. change to 0.9.62
This commit is contained in:
		
							parent
							
								
									04a526b340
								
							
						
					
					
						commit
						9a036958d7
					
				
					 6 changed files with 36 additions and 14 deletions
				
			
		| 
						 | 
					@ -54,6 +54,7 @@ class SrsPithyPrint
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    int client_id;
 | 
					    int client_id;
 | 
				
			||||||
    int stage_id;
 | 
					    int stage_id;
 | 
				
			||||||
 | 
					    // in ms.
 | 
				
			||||||
    int64_t age;
 | 
					    int64_t age;
 | 
				
			||||||
    int64_t printed_age;
 | 
					    int64_t printed_age;
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -254,13 +254,13 @@ int SrsRtmpConn::stream_service_cycle()
 | 
				
			||||||
    int ret = ERROR_SUCCESS;
 | 
					    int ret = ERROR_SUCCESS;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    SrsRtmpConnType type;
 | 
					    SrsRtmpConnType type;
 | 
				
			||||||
    if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) {
 | 
					    if ((ret = rtmp->identify_client(res->stream_id, type, req->stream, req->duration)) != ERROR_SUCCESS) {
 | 
				
			||||||
        srs_error("identify client failed. ret=%d", ret);
 | 
					        srs_error("identify client failed. ret=%d", ret);
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    req->strip();
 | 
					    req->strip();
 | 
				
			||||||
    srs_trace("identify client success. type=%s, stream_name=%s", 
 | 
					    srs_trace("identify client success. type=%s, stream_name=%s, duration=%.2f", 
 | 
				
			||||||
        srs_client_type_string(type).c_str(), req->stream.c_str());
 | 
					        srs_client_type_string(type).c_str(), req->stream.c_str(), req->duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // client is identified, set the timeout to service timeout.
 | 
					    // client is identified, set the timeout to service timeout.
 | 
				
			||||||
    rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);
 | 
					    rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);
 | 
				
			||||||
| 
						 | 
					@ -417,6 +417,15 @@ int SrsRtmpConn::playing(SrsSource* source)
 | 
				
			||||||
    while (true) {
 | 
					    while (true) {
 | 
				
			||||||
        pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000);
 | 
					        pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        // if duration specified, and exceed it, stop play live.
 | 
				
			||||||
 | 
					        // @see: https://github.com/winlinvip/simple-rtmp-server/issues/45
 | 
				
			||||||
 | 
					        // TODO: maybe the duration should use the stream duration.
 | 
				
			||||||
 | 
					        if (req->duration > 0 && pithy_print.get_age() >= (int64_t)req->duration) {
 | 
				
			||||||
 | 
					            ret = ERROR_RTMP_DURATION_EXCEED;
 | 
				
			||||||
 | 
					            srs_trace("stop live for duration exceed. ret=%d", ret);
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        // switch to other st-threads.
 | 
					        // switch to other st-threads.
 | 
				
			||||||
        st_usleep(0);
 | 
					        st_usleep(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
// current release version
 | 
					// current release version
 | 
				
			||||||
#define VERSION_MAJOR "0"
 | 
					#define VERSION_MAJOR "0"
 | 
				
			||||||
#define VERSION_MINOR "9"
 | 
					#define VERSION_MINOR "9"
 | 
				
			||||||
#define VERSION_REVISION "61"
 | 
					#define VERSION_REVISION "62"
 | 
				
			||||||
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
 | 
					#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
 | 
				
			||||||
// server info.
 | 
					// server info.
 | 
				
			||||||
#define RTMP_SIG_SRS_KEY "srs"
 | 
					#define RTMP_SIG_SRS_KEY "srs"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,6 +75,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
// 1. srs is ok, ignore and turn to simple handshake.
 | 
					// 1. srs is ok, ignore and turn to simple handshake.
 | 
				
			||||||
// 2. srs-librtmp return error, to terminate the program.
 | 
					// 2. srs-librtmp return error, to terminate the program.
 | 
				
			||||||
#define ERROR_RTMP_HS_SSL_REQUIRE           318
 | 
					#define ERROR_RTMP_HS_SSL_REQUIRE           318
 | 
				
			||||||
 | 
					#define ERROR_RTMP_DURATION_EXCEED          319
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ERROR_SYSTEM_STREAM_INIT            400
 | 
					#define ERROR_SYSTEM_STREAM_INIT            400
 | 
				
			||||||
#define ERROR_SYSTEM_PACKET_INVALID         401
 | 
					#define ERROR_SYSTEM_PACKET_INVALID         401
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,7 @@ using namespace std;
 | 
				
			||||||
SrsRequest::SrsRequest()
 | 
					SrsRequest::SrsRequest()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    objectEncoding = RTMP_SIG_AMF0_VER;
 | 
					    objectEncoding = RTMP_SIG_AMF0_VER;
 | 
				
			||||||
 | 
					    duration = -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SrsRequest::~SrsRequest()
 | 
					SrsRequest::~SrsRequest()
 | 
				
			||||||
| 
						 | 
					@ -94,6 +95,7 @@ SrsRequest* SrsRequest::copy()
 | 
				
			||||||
    cp->swfUrl = swfUrl;
 | 
					    cp->swfUrl = swfUrl;
 | 
				
			||||||
    cp->tcUrl = tcUrl;
 | 
					    cp->tcUrl = tcUrl;
 | 
				
			||||||
    cp->vhost = vhost;
 | 
					    cp->vhost = vhost;
 | 
				
			||||||
 | 
					    cp->duration = duration;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return cp;
 | 
					    return cp;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -940,7 +942,7 @@ int SrsRtmpServer::on_bw_done()
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& stream_name)
 | 
					int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& stream_name, double& duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    type = SrsRtmpConnUnknown;
 | 
					    type = SrsRtmpConnUnknown;
 | 
				
			||||||
    int ret = ERROR_SUCCESS;
 | 
					    int ret = ERROR_SUCCESS;
 | 
				
			||||||
| 
						 | 
					@ -968,7 +970,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string&
 | 
				
			||||||
        SrsPacket* pkt = msg->get_packet();
 | 
					        SrsPacket* pkt = msg->get_packet();
 | 
				
			||||||
        if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
 | 
					        if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
 | 
				
			||||||
            srs_info("identify client by create stream, play or flash publish.");
 | 
					            srs_info("identify client by create stream, play or flash publish.");
 | 
				
			||||||
            return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name);
 | 
					            return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
 | 
					        if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
 | 
				
			||||||
            srs_info("identify client by releaseStream, fmle publish.");
 | 
					            srs_info("identify client by releaseStream, fmle publish.");
 | 
				
			||||||
| 
						 | 
					@ -976,7 +978,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string&
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dynamic_cast<SrsPlayPacket*>(pkt)) {
 | 
					        if (dynamic_cast<SrsPlayPacket*>(pkt)) {
 | 
				
			||||||
            srs_info("level0 identify client by play.");
 | 
					            srs_info("level0 identify client by play.");
 | 
				
			||||||
            return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name);
 | 
					            return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name, duration);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        srs_trace("ignore AMF0/AMF3 command message.");
 | 
					        srs_trace("ignore AMF0/AMF3 command message.");
 | 
				
			||||||
| 
						 | 
					@ -1373,7 +1375,7 @@ int SrsRtmpServer::start_flash_publish(int stream_id)
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, string& stream_name)
 | 
					int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, string& stream_name, double& duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret = ERROR_SUCCESS;
 | 
					    int ret = ERROR_SUCCESS;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -1413,7 +1415,7 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int
 | 
				
			||||||
        SrsPacket* pkt = msg->get_packet();
 | 
					        SrsPacket* pkt = msg->get_packet();
 | 
				
			||||||
        if (dynamic_cast<SrsPlayPacket*>(pkt)) {
 | 
					        if (dynamic_cast<SrsPlayPacket*>(pkt)) {
 | 
				
			||||||
            srs_info("level1 identify client by play.");
 | 
					            srs_info("level1 identify client by play.");
 | 
				
			||||||
            return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name);
 | 
					            return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name, duration);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dynamic_cast<SrsPublishPacket*>(pkt)) {
 | 
					        if (dynamic_cast<SrsPublishPacket*>(pkt)) {
 | 
				
			||||||
            srs_info("identify client by publish, falsh publish.");
 | 
					            srs_info("identify client by publish, falsh publish.");
 | 
				
			||||||
| 
						 | 
					@ -1460,14 +1462,15 @@ int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpC
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SrsRtmpServer::identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, string& stream_name)
 | 
					int SrsRtmpServer::identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, string& stream_name, double& duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret = ERROR_SUCCESS;
 | 
					    int ret = ERROR_SUCCESS;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    type = SrsRtmpConnPlay;
 | 
					    type = SrsRtmpConnPlay;
 | 
				
			||||||
    stream_name = req->stream_name;
 | 
					    stream_name = req->stream_name;
 | 
				
			||||||
 | 
					    duration = req->duration;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());
 | 
					    srs_trace("identity client type=play, stream_name=%s, duration=%.2f", stream_name.c_str(), duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +67,12 @@ public:
 | 
				
			||||||
    std::string app;
 | 
					    std::string app;
 | 
				
			||||||
    std::string stream;
 | 
					    std::string stream;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    // for play live stream, 
 | 
				
			||||||
 | 
					    // used to specified the stop when exceed the duration.
 | 
				
			||||||
 | 
					    // @see https://github.com/winlinvip/simple-rtmp-server/issues/45
 | 
				
			||||||
 | 
					    // in ms.
 | 
				
			||||||
 | 
					    double duration;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    SrsRequest();
 | 
					    SrsRequest();
 | 
				
			||||||
    virtual ~SrsRequest();
 | 
					    virtual ~SrsRequest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -222,8 +228,10 @@ public:
 | 
				
			||||||
    * @stream_id, client will createStream to play or publish by flash, 
 | 
					    * @stream_id, client will createStream to play or publish by flash, 
 | 
				
			||||||
    *         the stream_id used to response the createStream request.
 | 
					    *         the stream_id used to response the createStream request.
 | 
				
			||||||
    * @type, output the client type.
 | 
					    * @type, output the client type.
 | 
				
			||||||
 | 
					    * @stream_name, output the client publish/play stream name. @see: SrsRequest.stream
 | 
				
			||||||
 | 
					    * @duration, output the play client duration. @see: SrsRequest.duration
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    virtual int identify_client(int stream_id, SrsRtmpConnType& type, std::string& stream_name);
 | 
					    virtual int identify_client(int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration);
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    * set the chunk size when client type identified.
 | 
					    * set the chunk size when client type identified.
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
| 
						 | 
					@ -267,11 +275,11 @@ public:
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    virtual int start_flash_publish(int stream_id);
 | 
					    virtual int start_flash_publish(int stream_id);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name);
 | 
					    virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration);
 | 
				
			||||||
    virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
 | 
					    virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
 | 
				
			||||||
    virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name);
 | 
					    virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name);
 | 
					    virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue