diff --git a/lsp/mist.js b/lsp/mist.js index 37f1c5e4..3a3b9f8e 100644 --- a/lsp/mist.js +++ b/lsp/mist.js @@ -3568,6 +3568,7 @@ var UI = { ['STREAM_PUSH', 'STREAM_PUSH: right before an incoming push is accepted'], ['STREAM_TRACK_ADD', 'STREAM_TRACK_ADD: right before a track will be added to a stream; e.g.: additional push received'], ['STREAM_TRACK_REMOVE', 'STREAM_TRACK_REMOVE: right before a track will be removed track from a stream; e.g.: push timeout'], + ['RTMP_PUSH_REWRITE', 'RTMP_PUSH_REWRITE: allows rewriting of RTMP push URLs from external to internal representation before further parsing'], ['CONN_OPEN', 'CONN_OPEN: right after a new incoming connection has been received'], ['CONN_CLOSE', 'CONN_CLOSE: right after a connection has been closed'], ['CONN_PLAY', 'CONN_PLAY: right before a stream playback of a connection'] @@ -3581,6 +3582,7 @@ var UI = { case 'SYSTEM_CONFIG': case 'OUTPUT_START': case 'OUTPUT_STOP': + case 'RTMP_PUSH_REWRITE': $('[name=appliesto]').setval([]).closest('.UIelement').hide(); break; default: diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index d0d16a7a..88ebb9db 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -334,6 +334,13 @@ namespace Mist { /// output handler name /// request URL (if any) /// ~~~~~~~~~~~~~~~ + /// The `"RTMP_PUSH_REWRITE"` trigger is global and ran right before an RTMP publish request is parsed. It cannot be cancelled, but an invalid URL can be returned; which is effectively equivalent to cancelling. + /// This trigger is special: the response is used as RTMP URL override, and not handled as normal. If used, the handler for this trigger MUST return a valid RTMP URL to allow the push to go through. If used multiple times, the last defined handler overrides any and all previous handlers. + /// Its payload is: + /// ~~~~~~~~~~~~~~~ + /// current RTMP URL + /// connected client host + /// ~~~~~~~~~~~~~~~ void OutRTMP::parseAMFCommand(AMF::Object & amfData, int messageType, int streamId) { #if DEBUG >= 5 fprintf(stderr, "Received command: %s\n", amfData.Print().c_str()); @@ -478,6 +485,24 @@ namespace Mist { if (amfData.getContentP(3)) { streamName = amfData.getContentP(3)->StrValue(); reqUrl += "/"+streamName;//LTS + + /*LTS-START*/ + if(Triggers::shouldTrigger("RTMP_PUSH_REWRITE")){ + std::string payload = reqUrl+"\n" + myConn.getHost(); + std::string newUrl = ""; + Triggers::doTrigger("RTMP_PUSH_REWRITE", payload, "", false, newUrl); + if (!newUrl.size()){ + FAIL_MSG("Push from %s to URL %s rejected - RTMP_PUSH_REWRITE trigger blanked the URL", myConn.getHost().c_str(), reqUrl.c_str()); + myConn.close(); + return; + } + reqUrl = newUrl; + size_t lSlash = newUrl.rfind('/'); + if (lSlash != std::string::npos){ + streamName = newUrl.substr(lSlash+1); + } + } + /*LTS-END*/ if (streamName.find('/')){ streamName = streamName.substr(0, streamName.find('/'));