Fixed RTMP push out to YT (possibly others)
This commit is contained in:
parent
f75ea28221
commit
78844a6eec
4 changed files with 56 additions and 39 deletions
|
@ -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())){
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue