正在显示
6 个修改的文件
包含
36 行增加
和
14 行删除
| @@ -254,13 +254,13 @@ int SrsRtmpConn::stream_service_cycle() | @@ -254,13 +254,13 @@ int SrsRtmpConn::stream_service_cycle() | ||
| 254 | int ret = ERROR_SUCCESS; | 254 | int ret = ERROR_SUCCESS; |
| 255 | 255 | ||
| 256 | SrsRtmpConnType type; | 256 | SrsRtmpConnType type; |
| 257 | - if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) { | 257 | + if ((ret = rtmp->identify_client(res->stream_id, type, req->stream, req->duration)) != ERROR_SUCCESS) { |
| 258 | srs_error("identify client failed. ret=%d", ret); | 258 | srs_error("identify client failed. ret=%d", ret); |
| 259 | return ret; | 259 | return ret; |
| 260 | } | 260 | } |
| 261 | req->strip(); | 261 | req->strip(); |
| 262 | - srs_trace("identify client success. type=%s, stream_name=%s", | ||
| 263 | - srs_client_type_string(type).c_str(), req->stream.c_str()); | 262 | + srs_trace("identify client success. type=%s, stream_name=%s, duration=%.2f", |
| 263 | + srs_client_type_string(type).c_str(), req->stream.c_str(), req->duration); | ||
| 264 | 264 | ||
| 265 | // client is identified, set the timeout to service timeout. | 265 | // client is identified, set the timeout to service timeout. |
| 266 | rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US); | 266 | rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US); |
| @@ -417,6 +417,15 @@ int SrsRtmpConn::playing(SrsSource* source) | @@ -417,6 +417,15 @@ int SrsRtmpConn::playing(SrsSource* source) | ||
| 417 | while (true) { | 417 | while (true) { |
| 418 | pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); | 418 | pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); |
| 419 | 419 | ||
| 420 | + // if duration specified, and exceed it, stop play live. | ||
| 421 | + // @see: https://github.com/winlinvip/simple-rtmp-server/issues/45 | ||
| 422 | + // TODO: maybe the duration should use the stream duration. | ||
| 423 | + if (req->duration > 0 && pithy_print.get_age() >= (int64_t)req->duration) { | ||
| 424 | + ret = ERROR_RTMP_DURATION_EXCEED; | ||
| 425 | + srs_trace("stop live for duration exceed. ret=%d", ret); | ||
| 426 | + return ret; | ||
| 427 | + } | ||
| 428 | + | ||
| 420 | // switch to other st-threads. | 429 | // switch to other st-threads. |
| 421 | st_usleep(0); | 430 | st_usleep(0); |
| 422 | 431 |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR "0" | 32 | #define VERSION_MAJOR "0" |
| 33 | #define VERSION_MINOR "9" | 33 | #define VERSION_MINOR "9" |
| 34 | -#define VERSION_REVISION "61" | 34 | +#define VERSION_REVISION "62" |
| 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION |
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "srs" | 37 | #define RTMP_SIG_SRS_KEY "srs" |
| @@ -75,6 +75,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -75,6 +75,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 75 | // 1. srs is ok, ignore and turn to simple handshake. | 75 | // 1. srs is ok, ignore and turn to simple handshake. |
| 76 | // 2. srs-librtmp return error, to terminate the program. | 76 | // 2. srs-librtmp return error, to terminate the program. |
| 77 | #define ERROR_RTMP_HS_SSL_REQUIRE 318 | 77 | #define ERROR_RTMP_HS_SSL_REQUIRE 318 |
| 78 | +#define ERROR_RTMP_DURATION_EXCEED 319 | ||
| 78 | 79 | ||
| 79 | #define ERROR_SYSTEM_STREAM_INIT 400 | 80 | #define ERROR_SYSTEM_STREAM_INIT 400 |
| 80 | #define ERROR_SYSTEM_PACKET_INVALID 401 | 81 | #define ERROR_SYSTEM_PACKET_INVALID 401 |
| @@ -74,6 +74,7 @@ using namespace std; | @@ -74,6 +74,7 @@ using namespace std; | ||
| 74 | SrsRequest::SrsRequest() | 74 | SrsRequest::SrsRequest() |
| 75 | { | 75 | { |
| 76 | objectEncoding = RTMP_SIG_AMF0_VER; | 76 | objectEncoding = RTMP_SIG_AMF0_VER; |
| 77 | + duration = -1; | ||
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | SrsRequest::~SrsRequest() | 80 | SrsRequest::~SrsRequest() |
| @@ -94,6 +95,7 @@ SrsRequest* SrsRequest::copy() | @@ -94,6 +95,7 @@ SrsRequest* SrsRequest::copy() | ||
| 94 | cp->swfUrl = swfUrl; | 95 | cp->swfUrl = swfUrl; |
| 95 | cp->tcUrl = tcUrl; | 96 | cp->tcUrl = tcUrl; |
| 96 | cp->vhost = vhost; | 97 | cp->vhost = vhost; |
| 98 | + cp->duration = duration; | ||
| 97 | 99 | ||
| 98 | return cp; | 100 | return cp; |
| 99 | } | 101 | } |
| @@ -940,7 +942,7 @@ int SrsRtmpServer::on_bw_done() | @@ -940,7 +942,7 @@ int SrsRtmpServer::on_bw_done() | ||
| 940 | return ret; | 942 | return ret; |
| 941 | } | 943 | } |
| 942 | 944 | ||
| 943 | -int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& stream_name) | 945 | +int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& stream_name, double& duration) |
| 944 | { | 946 | { |
| 945 | type = SrsRtmpConnUnknown; | 947 | type = SrsRtmpConnUnknown; |
| 946 | int ret = ERROR_SUCCESS; | 948 | int ret = ERROR_SUCCESS; |
| @@ -968,7 +970,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& | @@ -968,7 +970,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& | ||
| 968 | SrsPacket* pkt = msg->get_packet(); | 970 | SrsPacket* pkt = msg->get_packet(); |
| 969 | if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) { | 971 | if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) { |
| 970 | srs_info("identify client by create stream, play or flash publish."); | 972 | srs_info("identify client by create stream, play or flash publish."); |
| 971 | - return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name); | 973 | + return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration); |
| 972 | } | 974 | } |
| 973 | if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { | 975 | if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { |
| 974 | srs_info("identify client by releaseStream, fmle publish."); | 976 | srs_info("identify client by releaseStream, fmle publish."); |
| @@ -976,7 +978,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& | @@ -976,7 +978,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& | ||
| 976 | } | 978 | } |
| 977 | if (dynamic_cast<SrsPlayPacket*>(pkt)) { | 979 | if (dynamic_cast<SrsPlayPacket*>(pkt)) { |
| 978 | srs_info("level0 identify client by play."); | 980 | srs_info("level0 identify client by play."); |
| 979 | - return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name); | 981 | + return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name, duration); |
| 980 | } | 982 | } |
| 981 | 983 | ||
| 982 | srs_trace("ignore AMF0/AMF3 command message."); | 984 | srs_trace("ignore AMF0/AMF3 command message."); |
| @@ -1373,7 +1375,7 @@ int SrsRtmpServer::start_flash_publish(int stream_id) | @@ -1373,7 +1375,7 @@ int SrsRtmpServer::start_flash_publish(int stream_id) | ||
| 1373 | return ret; | 1375 | return ret; |
| 1374 | } | 1376 | } |
| 1375 | 1377 | ||
| 1376 | -int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, string& stream_name) | 1378 | +int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, string& stream_name, double& duration) |
| 1377 | { | 1379 | { |
| 1378 | int ret = ERROR_SUCCESS; | 1380 | int ret = ERROR_SUCCESS; |
| 1379 | 1381 | ||
| @@ -1413,7 +1415,7 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int | @@ -1413,7 +1415,7 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int | ||
| 1413 | SrsPacket* pkt = msg->get_packet(); | 1415 | SrsPacket* pkt = msg->get_packet(); |
| 1414 | if (dynamic_cast<SrsPlayPacket*>(pkt)) { | 1416 | if (dynamic_cast<SrsPlayPacket*>(pkt)) { |
| 1415 | srs_info("level1 identify client by play."); | 1417 | srs_info("level1 identify client by play."); |
| 1416 | - return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name); | 1418 | + return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name, duration); |
| 1417 | } | 1419 | } |
| 1418 | if (dynamic_cast<SrsPublishPacket*>(pkt)) { | 1420 | if (dynamic_cast<SrsPublishPacket*>(pkt)) { |
| 1419 | srs_info("identify client by publish, falsh publish."); | 1421 | srs_info("identify client by publish, falsh publish."); |
| @@ -1460,14 +1462,15 @@ int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpC | @@ -1460,14 +1462,15 @@ int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpC | ||
| 1460 | return ret; | 1462 | return ret; |
| 1461 | } | 1463 | } |
| 1462 | 1464 | ||
| 1463 | -int SrsRtmpServer::identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, string& stream_name) | 1465 | +int SrsRtmpServer::identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, string& stream_name, double& duration) |
| 1464 | { | 1466 | { |
| 1465 | int ret = ERROR_SUCCESS; | 1467 | int ret = ERROR_SUCCESS; |
| 1466 | 1468 | ||
| 1467 | type = SrsRtmpConnPlay; | 1469 | type = SrsRtmpConnPlay; |
| 1468 | stream_name = req->stream_name; | 1470 | stream_name = req->stream_name; |
| 1471 | + duration = req->duration; | ||
| 1469 | 1472 | ||
| 1470 | - srs_trace("identity client type=play, stream_name=%s", stream_name.c_str()); | 1473 | + srs_trace("identity client type=play, stream_name=%s, duration=%.2f", stream_name.c_str(), duration); |
| 1471 | 1474 | ||
| 1472 | return ret; | 1475 | return ret; |
| 1473 | } | 1476 | } |
| @@ -67,6 +67,12 @@ public: | @@ -67,6 +67,12 @@ public: | ||
| 67 | std::string app; | 67 | std::string app; |
| 68 | std::string stream; | 68 | std::string stream; |
| 69 | 69 | ||
| 70 | + // for play live stream, | ||
| 71 | + // used to specified the stop when exceed the duration. | ||
| 72 | + // @see https://github.com/winlinvip/simple-rtmp-server/issues/45 | ||
| 73 | + // in ms. | ||
| 74 | + double duration; | ||
| 75 | + | ||
| 70 | SrsRequest(); | 76 | SrsRequest(); |
| 71 | virtual ~SrsRequest(); | 77 | virtual ~SrsRequest(); |
| 72 | 78 | ||
| @@ -222,8 +228,10 @@ public: | @@ -222,8 +228,10 @@ public: | ||
| 222 | * @stream_id, client will createStream to play or publish by flash, | 228 | * @stream_id, client will createStream to play or publish by flash, |
| 223 | * the stream_id used to response the createStream request. | 229 | * the stream_id used to response the createStream request. |
| 224 | * @type, output the client type. | 230 | * @type, output the client type. |
| 231 | + * @stream_name, output the client publish/play stream name. @see: SrsRequest.stream | ||
| 232 | + * @duration, output the play client duration. @see: SrsRequest.duration | ||
| 225 | */ | 233 | */ |
| 226 | - virtual int identify_client(int stream_id, SrsRtmpConnType& type, std::string& stream_name); | 234 | + virtual int identify_client(int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration); |
| 227 | /** | 235 | /** |
| 228 | * set the chunk size when client type identified. | 236 | * set the chunk size when client type identified. |
| 229 | */ | 237 | */ |
| @@ -267,11 +275,11 @@ public: | @@ -267,11 +275,11 @@ public: | ||
| 267 | */ | 275 | */ |
| 268 | virtual int start_flash_publish(int stream_id); | 276 | virtual int start_flash_publish(int stream_id); |
| 269 | private: | 277 | private: |
| 270 | - virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name); | 278 | + virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration); |
| 271 | virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name); | 279 | virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name); |
| 272 | virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name); | 280 | virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name); |
| 273 | private: | 281 | private: |
| 274 | - virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name); | 282 | + virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration); |
| 275 | }; | 283 | }; |
| 276 | 284 | ||
| 277 | #endif | 285 | #endif |
-
请 注册 或 登录 后发表评论