Merge branch 'development' into LTS_development
# Conflicts: # src/output/output_rtmp.h
This commit is contained in:
commit
2f6cd40fb3
6 changed files with 50 additions and 13 deletions
10
lsp/mist.js
10
lsp/mist.js
|
@ -2824,7 +2824,7 @@ var UI = {
|
||||||
var embedoptions = {autoplay: true};
|
var embedoptions = {autoplay: true};
|
||||||
function embedhtml(opts) {
|
function embedhtml(opts) {
|
||||||
var open = ['div'];
|
var open = ['div'];
|
||||||
var inner = "\n"+' <script src="'+embedbase+'embed_'+other+'.js"><'+'/script>'+"\n"; //don't leave the closing script tag complete
|
var inner = "\n"+' <script src="'+embedbase+'embed_'+encodeURIComponent(other)+'.js"><'+'/script>'+"\n"; //don't leave the closing script tag complete
|
||||||
if (!opts.autoplay) {
|
if (!opts.autoplay) {
|
||||||
open.push('data-noautoplay');
|
open.push('data-noautoplay');
|
||||||
}
|
}
|
||||||
|
@ -2844,17 +2844,17 @@ var UI = {
|
||||||
{
|
{
|
||||||
label: 'Embedable script',
|
label: 'Embedable script',
|
||||||
type: 'str',
|
type: 'str',
|
||||||
value: embedbase+'embed_'+other+'.js',
|
value: embedbase+'embed_'+encodeURIComponent(other)+'.js',
|
||||||
readonly: true
|
readonly: true
|
||||||
},{
|
},{
|
||||||
label: 'Stream info script',
|
label: 'Stream info script',
|
||||||
type: 'str',
|
type: 'str',
|
||||||
value: embedbase+'info_'+other+'.js',
|
value: embedbase+'info_'+encodeURIComponent(other)+'.js',
|
||||||
readonly: true
|
readonly: true
|
||||||
},{
|
},{
|
||||||
label: 'Autodetect player',
|
label: 'Autodetect player',
|
||||||
type: 'str',
|
type: 'str',
|
||||||
value: embedbase+other+'.html',
|
value: embedbase+encodeURIComponent(other)+'.html',
|
||||||
readonly: true,
|
readonly: true,
|
||||||
qrcode: true
|
qrcode: true
|
||||||
},$('<h3>').text('Embed code'),{
|
},$('<h3>').text('Embed code'),{
|
||||||
|
@ -3027,7 +3027,7 @@ var UI = {
|
||||||
|
|
||||||
// jQuery doesn't work -> use DOM magic
|
// jQuery doesn't work -> use DOM magic
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
script.src = embedbase+'embed_'+other+'.js';
|
script.src = embedbase+'embed_'+encodeURIComponent(other)+'.js';
|
||||||
script.onerror = function(){
|
script.onerror = function(){
|
||||||
$c.html('Error loading "'+script.src+'".<br>').append(
|
$c.html('Error loading "'+script.src+'".<br>').append(
|
||||||
$('<button>').text('Try again').click(function(){
|
$('<button>').text('Try again').click(function(){
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
var embedtype = $('input[name=force]').val();
|
var embedtype = $('input[name=force]').val();
|
||||||
|
|
||||||
var info = document.createElement('script');
|
var info = document.createElement('script');
|
||||||
info.src = 'http://'+(window.location.hostname == '' ? 'localhost' : window.location.hostname)+':8080/info_'+streamName+'.js?video=0';
|
info.src = 'http://'+(window.location.hostname == '' ? 'localhost' : window.location.hostname)+':8080/info_'+encodeURIComponent(streamName)+'.js';
|
||||||
document.getElementById('embedcontainer').appendChild(info);
|
document.getElementById('embedcontainer').appendChild(info);
|
||||||
info.onload = function(){
|
info.onload = function(){
|
||||||
if (embedtype == '') {
|
if (embedtype == '') {
|
||||||
|
|
|
@ -189,7 +189,7 @@ function mistembed(streamname) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'html5':
|
case 'html5':
|
||||||
container.innerHTML += '<video width="' + videowidth + '" height="' + videoheight + '" src="' + encodeURI(src.url) + '" controls="controls" '+(autoplay ? 'autoplay="autoplay"' : '')+'><strong>No HTML5 video support</strong></video>';
|
container.innerHTML += '<video width="' + videowidth + '" height="' + videoheight + '" src="' + src.url + '" controls="controls" '+(autoplay ? 'autoplay="autoplay"' : '')+'><strong>No HTML5 video support</strong></video>';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'rtsp':
|
case 'rtsp':
|
||||||
|
|
|
@ -1034,6 +1034,7 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
stats();
|
stats();
|
||||||
}
|
}
|
||||||
|
onFinish();
|
||||||
MEDIUM_MSG("MistOut client handler shutting down: %s, %s, %s", myConn.connected() ? "conn_active" : "conn_closed", wantRequest ? "want_request" : "no_want_request", parseData ? "parsing_data" : "not_parsing_data");
|
MEDIUM_MSG("MistOut client handler shutting down: %s, %s, %s", myConn.connected() ? "conn_active" : "conn_closed", wantRequest ? "want_request" : "no_want_request", parseData ? "parsing_data" : "not_parsing_data");
|
||||||
|
|
||||||
/*LTS-START*/
|
/*LTS-START*/
|
||||||
|
@ -1332,11 +1333,13 @@ namespace Mist {
|
||||||
nProxy.userClient = IPC::sharedClient(userPageName, PLAY_EX_SIZE, true);
|
nProxy.userClient = IPC::sharedClient(userPageName, PLAY_EX_SIZE, true);
|
||||||
if (!nProxy.userClient.getData()){
|
if (!nProxy.userClient.getData()){
|
||||||
WARN_MSG("Player connection failure - aborting output");
|
WARN_MSG("Player connection failure - aborting output");
|
||||||
|
onFinish();
|
||||||
myConn.close();
|
myConn.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nProxy.userClient.isAlive()){
|
if (!nProxy.userClient.isAlive()){
|
||||||
|
onFinish();
|
||||||
myConn.close();
|
myConn.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,38 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OutRTMP::onFinish(){
|
||||||
|
MEDIUM_MSG("Finishing stream %s, %s", streamName.c_str(), myConn?"while connected":"already disconnected");
|
||||||
|
if (myConn){
|
||||||
|
myConn.SendNow(RTMPStream::SendUSR(1, 1)); //send UCM StreamEOF (1), stream 1
|
||||||
|
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
|
||||||
|
amfreply.addContent(AMF::Object("", "onStatus")); //status reply
|
||||||
|
amfreply.addContent(AMF::Object("", (double)0)); //transaction ID
|
||||||
|
amfreply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //null - command info
|
||||||
|
amfreply.addContent(AMF::Object("")); //info
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("level", "status"));
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("code", "NetStream.Play.Stop"));
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("description", "Stream stopped"));
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("details", "DDV"));
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("clientid", (double)1337));
|
||||||
|
sendCommand(amfreply, 20, 1);
|
||||||
|
|
||||||
|
amfreply = AMF::Object ("container", AMF::AMF0_DDV_CONTAINER);
|
||||||
|
amfreply.addContent(AMF::Object("", "onStatus")); //status reply
|
||||||
|
amfreply.addContent(AMF::Object("", (double)0)); //transaction ID
|
||||||
|
amfreply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //null - command info
|
||||||
|
amfreply.addContent(AMF::Object("")); //info
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("level", "status"));
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("code", "NetStream.Play.UnpublishNotify"));
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("description", "Stream stopped"));
|
||||||
|
amfreply.getContentP(3)->addContent(AMF::Object("clientid", (double)1337));
|
||||||
|
sendCommand(amfreply, 20, 1);
|
||||||
|
|
||||||
|
myConn.close();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void OutRTMP::parseVars(std::string data){
|
void OutRTMP::parseVars(std::string data){
|
||||||
std::string varname;
|
std::string varname;
|
||||||
std::string varval;
|
std::string varval;
|
||||||
|
@ -614,6 +646,7 @@ namespace Mist {
|
||||||
} //createStream
|
} //createStream
|
||||||
if ((amfData.getContentP(0)->StrValue() == "closeStream") || (amfData.getContentP(0)->StrValue() == "deleteStream")) {
|
if ((amfData.getContentP(0)->StrValue() == "closeStream") || (amfData.getContentP(0)->StrValue() == "deleteStream")) {
|
||||||
stop();
|
stop();
|
||||||
|
onFinish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((amfData.getContentP(0)->StrValue() == "FCUnpublish") || (amfData.getContentP(0)->StrValue() == "releaseStream")) {
|
if ((amfData.getContentP(0)->StrValue() == "FCUnpublish") || (amfData.getContentP(0)->StrValue() == "releaseStream")) {
|
||||||
|
@ -713,7 +746,7 @@ namespace Mist {
|
||||||
if (streamCfg){
|
if (streamCfg){
|
||||||
if (streamCfg.getMember("source").asString().substr(0, 7) != "push://"){
|
if (streamCfg.getMember("source").asString().substr(0, 7) != "push://"){
|
||||||
FAIL_MSG("Push rejected - stream %s not a push-able stream. (%s != push://*)", streamName.c_str(), streamCfg.getMember("source").asString().c_str());
|
FAIL_MSG("Push rejected - stream %s not a push-able stream. (%s != push://*)", streamName.c_str(), streamCfg.getMember("source").asString().c_str());
|
||||||
myConn.close();
|
onFinish();
|
||||||
}else{
|
}else{
|
||||||
std::string source = streamCfg.getMember("source").asString().substr(7);
|
std::string source = streamCfg.getMember("source").asString().substr(7);
|
||||||
std::string IP = source.substr(0, source.find('@'));
|
std::string IP = source.substr(0, source.find('@'));
|
||||||
|
@ -747,13 +780,13 @@ namespace Mist {
|
||||||
if (IP != ""){
|
if (IP != ""){
|
||||||
if (!myConn.isAddress(IP)){
|
if (!myConn.isAddress(IP)){
|
||||||
FAIL_MSG("Push from %s to %s rejected - source host not whitelisted", getConnectedHost().c_str(), streamName.c_str());
|
FAIL_MSG("Push from %s to %s rejected - source host not whitelisted", getConnectedHost().c_str(), streamName.c_str());
|
||||||
myConn.close();
|
onFinish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
FAIL_MSG("Push from %s rejected - stream '%s' not configured.", getConnectedHost().c_str(), streamName.c_str());
|
FAIL_MSG("Push from %s rejected - stream '%s' not configured.", getConnectedHost().c_str(), streamName.c_str());
|
||||||
myConn.close();
|
onFinish();
|
||||||
}
|
}
|
||||||
configLock.post();
|
configLock.post();
|
||||||
configLock.close();
|
configLock.close();
|
||||||
|
@ -994,7 +1027,7 @@ namespace Mist {
|
||||||
inputBuffer.get().clear();
|
inputBuffer.get().clear();
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
myConn.close();
|
onFinish();
|
||||||
break; //happens when connection breaks unexpectedly
|
break; //happens when connection breaks unexpectedly
|
||||||
case 1: //set chunk size
|
case 1: //set chunk size
|
||||||
RTMPStream::chunk_rec_max = ntohl(*(int *)next.data.c_str());
|
RTMPStream::chunk_rec_max = ntohl(*(int *)next.data.c_str());
|
||||||
|
@ -1067,7 +1100,7 @@ namespace Mist {
|
||||||
static std::map<unsigned int, AMF::Object> pushMeta;
|
static std::map<unsigned int, AMF::Object> pushMeta;
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
MEDIUM_MSG("Received useless media data");
|
MEDIUM_MSG("Received useless media data");
|
||||||
myConn.close();
|
onFinish();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
F.ChunkLoader(next);
|
F.ChunkLoader(next);
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Mist {
|
||||||
bool isReadyForPlay();
|
bool isReadyForPlay();
|
||||||
static bool listenMode();
|
static bool listenMode();
|
||||||
void requestHandler();
|
void requestHandler();
|
||||||
|
bool onFinish();
|
||||||
protected:
|
protected:
|
||||||
bool isPushing;
|
bool isPushing;
|
||||||
unsigned int maxbps;
|
unsigned int maxbps;
|
||||||
|
|
Loading…
Add table
Reference in a new issue