diff --git a/src/connectors/conn_http.cpp b/src/connectors/conn_http.cpp
index 71897f86..5be144c9 100644
--- a/src/connectors/conn_http.cpp
+++ b/src/connectors/conn_http.cpp
@@ -296,7 +296,7 @@ namespace Connector_HTTP {
}
connconn[uid]->lastuse = 0;
timeout = 0;
- Util::sleep(2000);
+ Util::sleep(5000);
connconn[uid]->conn->SendNow(request);
continue;
}
diff --git a/src/connectors/conn_http_dynamic.cpp b/src/connectors/conn_http_dynamic.cpp
index e8a1570b..759f4d8c 100644
--- a/src/connectors/conn_http_dynamic.cpp
+++ b/src/connectors/conn_http_dynamic.cpp
@@ -26,15 +26,11 @@
/// Holds everything unique to HTTP Dynamic Connector.
namespace Connector_HTTP {
- std::string GenerateBootstrap(std::string & MovieId, JSON::Value & metadata, int fragnum, int starttime, int endtime){
+ std::string GenerateBootstrap(std::string & MovieId, JSON::Value & metadata, int fragnum = 0){
std::string empty;
MP4::ASRT asrt;
- if (starttime == 0 && metadata.isMember("vod")){
- asrt.setUpdate(false);
- }else{
- asrt.setUpdate(true);
- }
+ asrt.setUpdate(false);
asrt.setVersion(1);
//asrt.setQualityEntry(empty, 0);
if (metadata.isMember("live")){
@@ -44,18 +40,19 @@ namespace Connector_HTTP {
}
MP4::AFRT afrt;
- if (starttime == 0 && metadata.isMember("vod")){
- afrt.setUpdate(false);
- }else{
- afrt.setUpdate(true);
- }
+ afrt.setUpdate(false);
afrt.setVersion(1);
afrt.setTimeScale(1000);
//afrt.setQualityEntry(empty, 0);
MP4::afrt_runtable afrtrun;
if (metadata.isMember("live")){
+ // restrict data to last 2 fragments, unless an earlier fragment was expressly requested.
int count = 0;
- for (int i = std::max(0u, metadata["keynum"].size() - 3); i < metadata["keynum"].size(); i++){
+ unsigned int begin = std::max(0u, metadata["keynum"].size() - 3);
+ while (begin > 0 && fragnum && metadata["keynum"][begin].asInt() > fragnum){
+ begin--;
+ }
+ for (int i = begin; i < metadata["keynum"].size(); i++){
afrtrun.firstFragment = metadata["keynum"][i].asInt();
afrtrun.firstTimestamp = metadata["keytime"][i].asInt();
afrtrun.duration = metadata["keylen"][i].asInt();
@@ -72,17 +69,9 @@ namespace Connector_HTTP {
MP4::ABST abst;
abst.setVersion(1);
- if (metadata.isMember("live")){
- abst.setBootstrapinfoVersion(metadata["keynum"][metadata["keynum"].size() - 2].asInt());
- }else{
- abst.setBootstrapinfoVersion(1);
- }
+ abst.setBootstrapinfoVersion(1);
abst.setProfile(0);
- if (starttime == 0){
- abst.setUpdate(false);
- }else{
- abst.setUpdate(true);
- }
+ abst.setUpdate(false);
abst.setTimeScale(1000);
abst.setLive(false);
abst.setCurrentMediaTime(metadata["lastms"].asInt());
@@ -111,7 +100,7 @@ namespace Connector_HTTP {
"video/mp4\n"
"recorded\n"
"streaming\n"
- "" + Base64::encode(GenerateBootstrap(MovieId, metadata, 1, 0, 0)) + "\n"
+ "" + Base64::encode(GenerateBootstrap(MovieId, metadata)) + "\n"
"\n"
"AgAKb25NZXRhRGF0YQMAAAk=\n"
"\n"
@@ -195,7 +184,7 @@ namespace Connector_HTTP {
}
if (HTTP_R.url.find(".abst") != std::string::npos){
HTTP_S.Clean();
- HTTP_S.SetBody(GenerateBootstrap(streamname, Strm.metadata, 1, 0, 0));
+ HTTP_S.SetBody(GenerateBootstrap(streamname, Strm.metadata));
HTTP_S.SetHeader("Content-Type", "binary/octet");
HTTP_S.SetHeader("Cache-Control", "no-cache");
conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
@@ -215,6 +204,10 @@ namespace Connector_HTTP {
#endif
if (Strm.metadata.isMember("live")){
int seekable = Strm.canSeekFrame(ReqFragment);
+ if (seekable == 0){
+ // iff the fragment in question is available, check if the next is available too
+ seekable = Strm.canSeekFrame(ReqFragment + 1);
+ }
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");
@@ -261,7 +254,7 @@ namespace Connector_HTTP {
HTTP_S.Clean();
HTTP_S.SetHeader("Content-Type", "video/mp4");
HTTP_S.SetBody("");
- std::string new_strap = GenerateBootstrap(streamname, Strm.metadata, 1, 0, 0);
+ std::string new_strap = GenerateBootstrap(streamname, Strm.metadata, ReqFragment);
HTTP_S.SetHeader("Content-Length", FlashBufSize + 8 + new_strap.size()); //32+33+btstrp.size());
conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
conn.SendNow(new_strap);
diff --git a/src/connectors/conn_http_smooth.cpp b/src/connectors/conn_http_smooth.cpp
index e7b7e6f3..e7b5a5ab 100644
--- a/src/connectors/conn_http_smooth.cpp
+++ b/src/connectors/conn_http_smooth.cpp
@@ -23,7 +23,7 @@
#include
#include
-/// Holds everything unique to HTTP Dynamic Connector.
+/// Holds everything unique to HTTP Connectors.
namespace Connector_HTTP {
/// Returns a Smooth-format manifest file
std::string BuildManifest(std::string & MovieId, JSON::Value & metadata){
@@ -31,7 +31,7 @@ namespace Connector_HTTP {
Result << "\n";
Result << "\n";
- for (int i = 0; i < metadata["keytime"].size() - 1; i++){
+ for (unsigned int i = 0; i < metadata["keylen"].size(); i++){
Result << " \n";
+ Result << "d=\"" << metadata["keylen"][i].asInt() * 10000 << "\" />\n";
}
- Result << " \n";
Result << " \n";
}
if (metadata.isMember("video")){
@@ -73,14 +72,13 @@ namespace Connector_HTTP {
Result << std::dec;
Result << "\" MaxWidth=\"" << metadata["video"]["width"].asInt() << "\" MaxHeight=\"" << metadata["video"]["height"].asInt()
<< "\" FourCC=\"AVC1\" />\n";
- for (int i = 0; i < metadata["keytime"].size() - 1; i++){
+ for (unsigned int i = 0; i < metadata["keylen"].size(); i++){
Result << " \n";
+ Result << "d=\"" << metadata["keylen"][i].asInt() * 10000 << "\" />\n";
}
- Result << " \n";
Result << " \n";
}
Result << "\n";
@@ -168,6 +166,17 @@ namespace Connector_HTTP {
ReqFragment = atoll(tempStr.substr(0, tempStr.find(")")).c_str());
if (Strm.metadata.isMember("live")){
int seekable = Strm.canSeekms(ReqFragment / 10000);
+ if (seekable == 0){
+ // iff the fragment in question is available, check if the next is available too
+ for (int i = 0; i < Strm.metadata["keytime"].size(); i++){
+ if (Strm.metadata["keytime"][i].asInt() >= (ReqFragment / 10000)){
+ if (i + 1 == Strm.metadata["keytime"].size()){
+ seekable = 1;
+ }
+ break;
+ }
+ }
+ }
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");
@@ -266,8 +275,7 @@ namespace Connector_HTTP {
if (Strm.metadata["keytime"][i].asInt() > (ReqFragment / 10000)){
fragref_box.setTime(fragCount, Strm.metadata["keytime"][i].asInt() * 10000);
fragref_box.setDuration(fragCount, Strm.metadata["keylen"][i].asInt() * 10000);
- fragCount++;
- fragref_box.setFragmentCount(fragCount);
+ fragref_box.setFragmentCount(++fragCount);
}
}
traf_box.setContent(fragref_box, 3);