Added support for proper range handling to HTTP-based fragmented protocols (Smooth, Live, Dynamic).
This commit is contained in:
parent
d3ce22c783
commit
cdcb71d8a8
4 changed files with 72 additions and 1 deletions
|
@ -269,6 +269,7 @@ namespace Connector_HTTP {
|
||||||
connconn[uid]->conn->SendNow(request);
|
connconn[uid]->conn->SendNow(request);
|
||||||
connconn[uid]->lastuse = 0;
|
connconn[uid]->lastuse = 0;
|
||||||
unsigned int timeout = 0;
|
unsigned int timeout = 0;
|
||||||
|
unsigned int retries = 0;
|
||||||
//wait for a response
|
//wait for a response
|
||||||
while (connconn.count(uid) && connconn[uid]->conn->connected() && conn->connected()){
|
while (connconn.count(uid) && connconn[uid]->conn->connected() && conn->connected()){
|
||||||
conn->spool();
|
conn->spool();
|
||||||
|
@ -285,6 +286,20 @@ namespace Connector_HTTP {
|
||||||
}
|
}
|
||||||
//check if the whole response was received
|
//check if the whole response was received
|
||||||
if (H.Read(connconn[uid]->conn->Received().get())){
|
if (H.Read(connconn[uid]->conn->Received().get())){
|
||||||
|
//208 means the fragment is too new, retry in 2000ms
|
||||||
|
if (H.url == "208"){
|
||||||
|
retries++;
|
||||||
|
if (retries >= 5){
|
||||||
|
std::cout << "[5 retry-laters, cancelled]" << std::endl;
|
||||||
|
connconn[uid]->conn->close();
|
||||||
|
return Handle_Timeout(H, conn);
|
||||||
|
}
|
||||||
|
connconn[uid]->lastuse = 0;
|
||||||
|
timeout = 0;
|
||||||
|
Util::sleep(2000);
|
||||||
|
connconn[uid]->conn->SendNow(request);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break; //continue down below this while loop
|
break; //continue down below this while loop
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -233,6 +233,25 @@ namespace Connector_HTTP {
|
||||||
#if DEBUG >= 5
|
#if DEBUG >= 5
|
||||||
printf("Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
|
printf("Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
|
||||||
#endif
|
#endif
|
||||||
|
if (Strm.metadata.isMember("live")){
|
||||||
|
int seekable = Strm.canSeekFrame(ReqFragment);
|
||||||
|
if (seekable < 0){
|
||||||
|
HTTP_S.Clean();
|
||||||
|
HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
|
||||||
|
conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
|
||||||
|
HTTP_R.Clean(); //clean for any possible next requests
|
||||||
|
std::cout << "Fragment @ F" << ReqFragment << " too old (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (seekable > 0){
|
||||||
|
HTTP_S.Clean();
|
||||||
|
HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
|
||||||
|
conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
|
||||||
|
HTTP_R.Clean(); //clean for any possible next requests
|
||||||
|
std::cout << "Fragment @ F" << ReqFragment << " not available yet (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::stringstream sstream;
|
std::stringstream sstream;
|
||||||
sstream << "f " << ReqFragment << "\no \n";
|
sstream << "f " << ReqFragment << "\no \n";
|
||||||
ss.SendNow(sstream.str().c_str());
|
ss.SendNow(sstream.str().c_str());
|
||||||
|
|
|
@ -167,7 +167,25 @@ namespace Connector_HTTP {
|
||||||
Segment = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find("_", temp) - temp).c_str());
|
Segment = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find("_", temp) - temp).c_str());
|
||||||
temp = HTTP_R.url.find("_", temp) + 1;
|
temp = HTTP_R.url.find("_", temp) + 1;
|
||||||
int frameCount = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find(".ts", temp) - temp).c_str());
|
int frameCount = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find(".ts", temp) - temp).c_str());
|
||||||
|
if (Strm.metadata.isMember("live")){
|
||||||
|
int seekable = Strm.canSeekFrame(Segment);
|
||||||
|
if (seekable < 0){
|
||||||
|
HTTP_S.Clean();
|
||||||
|
HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
|
||||||
|
conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
|
||||||
|
HTTP_R.Clean(); //clean for any possible next requests
|
||||||
|
std::cout << "Fragment @ F" << Segment << " too old (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (seekable > 0){
|
||||||
|
HTTP_S.Clean();
|
||||||
|
HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
|
||||||
|
conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
|
||||||
|
HTTP_R.Clean(); //clean for any possible next requests
|
||||||
|
std::cout << "Fragment @ F" << Segment << " not available yet (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::stringstream sstream;
|
std::stringstream sstream;
|
||||||
sstream << "f " << Segment << "\n";
|
sstream << "f " << Segment << "\n";
|
||||||
for (int i = 0; i < frameCount; i++){
|
for (int i = 0; i < frameCount; i++){
|
||||||
|
|
|
@ -166,6 +166,25 @@ namespace Connector_HTTP {
|
||||||
}
|
}
|
||||||
tempStr = tempStr.substr(tempStr.find("(") + 1);
|
tempStr = tempStr.substr(tempStr.find("(") + 1);
|
||||||
ReqFragment = atoll(tempStr.substr(0, tempStr.find(")")).c_str());
|
ReqFragment = atoll(tempStr.substr(0, tempStr.find(")")).c_str());
|
||||||
|
if (Strm.metadata.isMember("live")){
|
||||||
|
int seekable = Strm.canSeekms(ReqFragment / 10000);
|
||||||
|
if (seekable < 0){
|
||||||
|
HTTP_S.Clean();
|
||||||
|
HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
|
||||||
|
conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
|
||||||
|
HTTP_R.Clean(); //clean for any possible next requests
|
||||||
|
std::cout << "Fragment @ " << ReqFragment / 10000 << "ms too old (" << Strm.metadata["keytime"][0u].asInt() << " - " << Strm.metadata["keytime"][Strm.metadata["keytime"].size() - 1].asInt() << " ms)" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (seekable > 0){
|
||||||
|
HTTP_S.Clean();
|
||||||
|
HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
|
||||||
|
conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
|
||||||
|
HTTP_R.Clean(); //clean for any possible next requests
|
||||||
|
std::cout << "Fragment @ " << ReqFragment / 10000 << "ms not available yet (" << Strm.metadata["keytime"][0u].asInt() << " - " << Strm.metadata["keytime"][Strm.metadata["keytime"].size() - 1].asInt() << " ms)" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::stringstream sstream;
|
std::stringstream sstream;
|
||||||
sstream << "s " << (ReqFragment / 10000) << "\no \n";
|
sstream << "s " << (ReqFragment / 10000) << "\no \n";
|
||||||
ss.SendNow(sstream.str().c_str());
|
ss.SendNow(sstream.str().c_str());
|
||||||
|
|
Loading…
Add table
Reference in a new issue