Fixed near-live playback of HLS, HDS and HSS.

This commit is contained in:
Thulinma 2014-12-19 00:52:07 +01:00
parent 6ce3678056
commit cc4539c4da
3 changed files with 47 additions and 36 deletions

View file

@ -210,13 +210,16 @@ namespace Mist {
std::cout << "Fragment " << fragNum << " too old" << std::endl; std::cout << "Fragment " << fragNum << " too old" << std::endl;
return; return;
} }
if (fragNum > myMeta.tracks[tid].missedFrags + myMeta.tracks[tid].fragments.size() - 1){ //delay if we don't have the next fragment available yet
H.Clean(); unsigned int timeout = 0;
H.SetBody("Proxy, re-request this in a second or two.\n"); while (myConn && fragNum > myMeta.tracks[tid].missedFrags + myMeta.tracks[tid].fragments.size() - 1){
H.SendResponse("208", "Ask again later", myConn); //time out after 21 seconds
H.Clean(); //clean for any possible next requests if (++timeout > 42){
std::cout << "Fragment after fragment " << fragNum << " not available yet" << std::endl; myConn.close();
return; break;
}
Util::sleep(500);
updateMeta();
} }
mstime = myMeta.tracks[tid].getKey(myMeta.tracks[tid].fragments[fragNum - myMeta.tracks[tid].missedFrags].getNumber()).getTime(); mstime = myMeta.tracks[tid].getKey(myMeta.tracks[tid].fragments[fragNum - myMeta.tracks[tid].missedFrags].getNumber()).getTime();
mslen = myMeta.tracks[tid].fragments[fragNum - myMeta.tracks[tid].missedFrags].getDuration(); mslen = myMeta.tracks[tid].fragments[fragNum - myMeta.tracks[tid].missedFrags].getDuration();

View file

@ -304,8 +304,21 @@ namespace Mist {
} }
if (myMeta.live){ if (myMeta.live){
/// \todo Detection of out-of-range parts. unsigned int timeout = 0;
int seekable = canSeekms(from); int seekable;
do {
seekable = canSeekms(from);
/// \todo Detection of out-of-range parts.
if (seekable > 0){
//time out after 21 seconds
if (++timeout > 42){
myConn.close();
break;
}
Util::sleep(500);
updateMeta();
}
}while (myConn && seekable > 0);
if (seekable < 0){ if (seekable < 0){
H.Clean(); H.Clean();
H.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n"); H.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
@ -314,14 +327,6 @@ namespace Mist {
DEBUG_MSG(DLVL_WARN, "Fragment @ %llu too old", from); DEBUG_MSG(DLVL_WARN, "Fragment @ %llu too old", from);
return; return;
} }
if (seekable > 0){
H.Clean();
H.SetBody("Proxy, re-request this in a second or two.\n");
myConn.SendNow(H.BuildResponse("208", "Ask again later"));
H.Clean(); //clean for any possible next requests
DEBUG_MSG(DLVL_WARN, "Fragment @ %llu not available yet", from);
return;
}
} }
seek(from); seek(from);

View file

@ -112,18 +112,31 @@ namespace Mist {
selectedTracks.insert(tid); selectedTracks.insert(tid);
if (myMeta.live) { if (myMeta.live) {
updateMeta(); updateMeta();
int seekable = canSeekms(seekTime); unsigned int timeout = 0;
if (seekable == 0){ int seekable;
// iff the fragment in question is available, check if the next is available too do {
for (std::deque<DTSC::Key>::iterator it = myMeta.tracks[tid].keys.begin(); it != myMeta.tracks[tid].keys.end(); it++){ seekable = canSeekms(seekTime);
if (it->getTime() >= seekTime){ if (seekable == 0){
if ((it + 1) == myMeta.tracks[tid].keys.end()){ // iff the fragment in question is available, check if the next is available too
seekable = 1; for (std::deque<DTSC::Key>::iterator it = myMeta.tracks[tid].keys.begin(); it != myMeta.tracks[tid].keys.end(); it++){
if (it->getTime() >= seekTime){
if ((it + 1) == myMeta.tracks[tid].keys.end()){
seekable = 1;
}
break;
} }
break;
} }
} }
} if (seekable > 0){
//time out after 21 seconds
if (++timeout > 42){
myConn.close();
break;
}
Util::sleep(500);
updateMeta();
}
}while (myConn && seekable > 0);
if (seekable < 0){ if (seekable < 0){
H.Clean(); H.Clean();
H.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n"); H.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
@ -134,16 +147,6 @@ namespace Mist {
wantRequest = true; wantRequest = true;
return; return;
} }
if (seekable > 0){
H.Clean();
H.SetBody("Proxy, re-request this in a second or two.\n");
myConn.SendNow(H.BuildResponse("208", "Ask again later"));
H.Clean(); //clean for any possible next requests
std::cout << "Fragment @ " << seekTime << "ms not available yet (" << myMeta.tracks[tid].firstms << " - " << myMeta.tracks[tid].lastms << " ms)" << std::endl;
stop();
wantRequest = true;
return;
}
} }
seek(seekTime); seek(seekTime);
playUntil = (*(keyTimes[tid].upper_bound(seekTime))); playUntil = (*(keyTimes[tid].upper_bound(seekTime)));