Fixed RTMP push out to YT (possibly others)

This commit is contained in:
Thulinma 2017-05-11 13:46:30 +02:00
parent f75ea28221
commit 78844a6eec
4 changed files with 56 additions and 39 deletions

View file

@ -92,6 +92,10 @@ namespace Mist{
return buffer.size();
}
bool Output::isRecording(){
return config->hasOption("target") && config->getString("target").size();
}
void Output::updateMeta(){
//cancel if not alive or pushing a new stream
if (!nProxy.userClient.isAlive() || (isPushing() && myMeta.tracks.size())){

View file

@ -129,7 +129,7 @@ namespace Mist {
bool sentHeader;///< If false, triggers sendHeader if parseData is true.
std::map<int,DTSCPageData> bookKeeping;
virtual bool isRecording(){return false;};
virtual bool isRecording();
virtual bool isPushing(){return pushing;};
bool allowPush(const std::string & passwd);
void bufferLivePacket(DTSC::Packet & packet);

View file

@ -15,7 +15,8 @@ namespace Mist {
streamName = config->getString("streamname");
std::string pushStr= config->getString("target");
pushStr = pushStr.substr(7);
std::string host, app = "default", streamOut = streamName;
std::string host, app = "default";
streamOut = streamName;
int port = 1935;
size_t slash = pushStr.find('/');
@ -88,46 +89,16 @@ namespace Mist {
amfReply.getContentP(2)->addContent(AMF::Object("app", app));
amfReply.getContentP(2)->addContent(AMF::Object("type", "nonprivate"));
amfReply.getContentP(2)->addContent(AMF::Object("flashVer", "FMLE/3.0 (compatible; MistServer/" PACKAGE_VERSION "/" RELEASE ")"));
if (port != 1935){
amfReply.getContentP(2)->addContent(AMF::Object("tcUrl", "rtmp://" + host + ":" + JSON::Value((long long)port).asString() + "/" + app));
}else{
amfReply.getContentP(2)->addContent(AMF::Object("tcUrl", "rtmp://" + host + "/" + app));
}
sendCommand(amfReply, 20, 0);
}
RTMPStream::chunk_snd_max = 10240000; //10000KiB
myConn.SendNow(RTMPStream::SendCTL(1, RTMPStream::chunk_snd_max)); //send chunk size max (msg 1)
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "releaseStream")); //command
amfReply.addContent(AMF::Object("", (double)2)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
amfReply.addContent(AMF::Object("", streamOut)); //stream name
sendCommand(amfReply, 20, 0);
}
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "FCPublish")); //command
amfReply.addContent(AMF::Object("", (double)3)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
amfReply.addContent(AMF::Object("", streamOut)); //stream name
sendCommand(amfReply, 20, 0);
}
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "createStream")); //command
amfReply.addContent(AMF::Object("", (double)4)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
sendCommand(amfReply, 20, 0);
}
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "publish")); //command
amfReply.addContent(AMF::Object("", (double)5)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
amfReply.addContent(AMF::Object("", streamOut)); //stream name
amfReply.addContent(AMF::Object("", "live")); //stream name
sendCommand(amfReply, 20, 1);
}
HIGH_MSG("Publish starting");
realTime = 0;
parseData = true;
HIGH_MSG("Waiting for server to acknowledge connect request...");
}else{
setBlocking(true);
while (!conn.Received().available(1537) && conn.connected() && config->is_active) {
@ -801,6 +772,9 @@ namespace Mist {
sendCommand(amfReply, messageType, streamId);
return;
} //checkBandwidth
if (amfData.getContentP(0)->StrValue() == "onBWDone") {
return;
}
if ((amfData.getContentP(0)->StrValue() == "play") || (amfData.getContentP(0)->StrValue() == "play2")) {
//set reply number and stream name, actual reply is sent up in the ss.spool() handler
int playTransaction = amfData.getContentP(1)->NumValue();
@ -968,7 +942,45 @@ namespace Mist {
return;
}
if ((amfData.getContentP(0)->StrValue() == "_result") || (amfData.getContentP(0)->StrValue() == "onFCPublish") || (amfData.getContentP(0)->StrValue() == "onStatus")) {
//Results are ignored. We don't really care.
if (isRecording() && amfData.getContentP(0)->StrValue() == "_result" && amfData.getContentP(1)->NumValue() == 1){
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "releaseStream")); //command
amfReply.addContent(AMF::Object("", (double)2)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
amfReply.addContent(AMF::Object("", streamOut)); //stream name
sendCommand(amfReply, 20, 0);
}
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "FCPublish")); //command
amfReply.addContent(AMF::Object("", (double)3)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
amfReply.addContent(AMF::Object("", streamOut)); //stream name
sendCommand(amfReply, 20, 0);
}
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "createStream")); //command
amfReply.addContent(AMF::Object("", (double)4)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
sendCommand(amfReply, 20, 0);
}
{
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "publish")); //command
amfReply.addContent(AMF::Object("", (double)5)); //transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //options
amfReply.addContent(AMF::Object("", streamOut)); //stream name
amfReply.addContent(AMF::Object("", "live")); //stream name
sendCommand(amfReply, 20, 1);
}
HIGH_MSG("Publish starting");
realTime = 0;
parseData = true;
}
//Other results are ignored. We don't really care.
return;
}

View file

@ -17,6 +17,7 @@ namespace Mist {
void requestHandler();
bool onFinish();
protected:
std::string streamOut;///<When pushing out, the output stream name
uint64_t rtmpOffset;
unsigned int maxbps;
void parseVars(std::string data);