Fixed/improved HLS subtitle support
This commit is contained in:
parent
37af199a1c
commit
37cbafe284
2 changed files with 16 additions and 8 deletions
|
@ -72,9 +72,14 @@ namespace Mist{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OutHLS::liveIndex(size_t tid, const std::string &sessId){
|
std::string OutHLS::liveIndex(size_t tid, const std::string &sessId){
|
||||||
|
//Timing track is current track, unless non-video, then time by video track
|
||||||
|
size_t timingTid = tid;
|
||||||
|
if (M.getType(timingTid) != "video"){timingTid = M.mainTrack();}
|
||||||
|
if (timingTid == INVALID_TRACK_ID){timingTid = tid;}
|
||||||
|
|
||||||
std::stringstream result;
|
std::stringstream result;
|
||||||
// parse single track
|
// parse single track
|
||||||
uint32_t targetDuration = (M.biggestFragment(tid) / 1000) + 1;
|
uint32_t targetDuration = (M.biggestFragment(timingTid) / 1000) + 1;
|
||||||
result << "#EXTM3U\r\n#EXT-X-VERSION:";
|
result << "#EXTM3U\r\n#EXT-X-VERSION:";
|
||||||
|
|
||||||
result << (M.getEncryption(tid) == "" ? "3" : "5");
|
result << (M.getEncryption(tid) == "" ? "3" : "5");
|
||||||
|
@ -90,20 +95,20 @@ namespace Mist{
|
||||||
std::deque<std::string> lines;
|
std::deque<std::string> lines;
|
||||||
std::deque<uint16_t> durations;
|
std::deque<uint16_t> durations;
|
||||||
uint32_t totalDuration = 0;
|
uint32_t totalDuration = 0;
|
||||||
DTSC::Keys keys(M.keys(tid));
|
DTSC::Keys keys(M.keys(timingTid));
|
||||||
DTSC::Fragments fragments(M.fragments(tid));
|
DTSC::Fragments fragments(M.fragments(timingTid));
|
||||||
uint32_t firstFragment = fragments.getFirstValid();
|
uint32_t firstFragment = fragments.getFirstValid();
|
||||||
uint32_t endFragment = fragments.getEndValid();
|
uint32_t endFragment = fragments.getEndValid();
|
||||||
for (int i = firstFragment; i < endFragment; i++){
|
for (int i = firstFragment; i < endFragment; i++){
|
||||||
uint64_t duration = fragments.getDuration(i);
|
uint64_t duration = fragments.getDuration(i);
|
||||||
size_t keyNumber = fragments.getFirstKey(i);
|
size_t keyNumber = fragments.getFirstKey(i);
|
||||||
uint64_t startTime = keys.getTime(keyNumber);
|
uint64_t startTime = keys.getTime(keyNumber);
|
||||||
if (!duration){duration = M.getLastms(tid) - startTime;}
|
if (!duration){duration = M.getLastms(timingTid) - startTime;}
|
||||||
double floatDur = (double)duration / 1000;
|
double floatDur = (double)duration / 1000;
|
||||||
char lineBuf[400];
|
char lineBuf[400];
|
||||||
|
|
||||||
if (M.getCodec(tid) == "subtitle"){
|
if (M.getCodec(tid) == "subtitle"){
|
||||||
snprintf(lineBuf, 400, "#EXTINF:%f,\r\n../../../%s.vtt?track=%zu&from=%" PRIu64 "&to=%" PRIu64 "\r\n",
|
snprintf(lineBuf, 400, "#EXTINF:%f,\r\n../../../%s.webvtt?track=%zu&from=%" PRIu64 "&to=%" PRIu64 "\r\n",
|
||||||
(double)duration / 1000, streamName.c_str(), tid, startTime, startTime + duration);
|
(double)duration / 1000, streamName.c_str(), tid, startTime, startTime + duration);
|
||||||
}else{
|
}else{
|
||||||
if (sessId.size()){
|
if (sessId.size()){
|
||||||
|
@ -146,7 +151,7 @@ namespace Mist{
|
||||||
/*LTS-END*/
|
/*LTS-END*/
|
||||||
}
|
}
|
||||||
|
|
||||||
result << "#EXT-X-MEDIA-SEQUENCE:" << M.getMissedFragments(tid) + skippedLines << "\r\n";
|
result << "#EXT-X-MEDIA-SEQUENCE:" << M.getMissedFragments(timingTid) + skippedLines << "\r\n";
|
||||||
|
|
||||||
for (std::deque<std::string>::iterator it = lines.begin(); it != lines.end(); it++){
|
for (std::deque<std::string>::iterator it = lines.begin(); it != lines.end(); it++){
|
||||||
result << *it;
|
result << *it;
|
||||||
|
@ -179,6 +184,7 @@ namespace Mist{
|
||||||
capa["codecs"][0u][4u].append("+MP3");
|
capa["codecs"][0u][4u].append("+MP3");
|
||||||
capa["codecs"][0u][5u].append("+AC3");
|
capa["codecs"][0u][5u].append("+AC3");
|
||||||
capa["codecs"][0u][6u].append("+MP2");
|
capa["codecs"][0u][6u].append("+MP2");
|
||||||
|
capa["codecs"][0u][6u].append("+subtitle");
|
||||||
capa["methods"][0u]["handler"] = "http";
|
capa["methods"][0u]["handler"] = "http";
|
||||||
capa["methods"][0u]["type"] = "html5/application/vnd.apple.mpegurl";
|
capa["methods"][0u]["type"] = "html5/application/vnd.apple.mpegurl";
|
||||||
capa["methods"][0u]["priority"] = 9;
|
capa["methods"][0u]["priority"] = 9;
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Mist{
|
||||||
capa["desc"] = "Pseudostreaming in SubRip Text (SRT) and WebVTT formats over HTTP";
|
capa["desc"] = "Pseudostreaming in SubRip Text (SRT) and WebVTT formats over HTTP";
|
||||||
capa["url_match"].append("/$.srt");
|
capa["url_match"].append("/$.srt");
|
||||||
capa["url_match"].append("/$.vtt");
|
capa["url_match"].append("/$.vtt");
|
||||||
|
capa["url_match"].append("/$.webvtt");
|
||||||
capa["codecs"][0u][0u].append("subtitle");
|
capa["codecs"][0u][0u].append("subtitle");
|
||||||
capa["methods"][0u]["handler"] = "http";
|
capa["methods"][0u]["handler"] = "http";
|
||||||
capa["methods"][0u]["type"] = "html5/text/plain";
|
capa["methods"][0u]["type"] = "html5/text/plain";
|
||||||
|
@ -23,7 +24,7 @@ namespace Mist{
|
||||||
capa["methods"][1u]["handler"] = "http";
|
capa["methods"][1u]["handler"] = "http";
|
||||||
capa["methods"][1u]["type"] = "html5/text/vtt";
|
capa["methods"][1u]["type"] = "html5/text/vtt";
|
||||||
capa["methods"][1u]["priority"] = 9;
|
capa["methods"][1u]["priority"] = 9;
|
||||||
capa["methods"][1u]["url_rel"] = "/$.vtt";
|
capa["methods"][1u]["url_rel"] = "/$.webvtt";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutSRT::sendNext(){
|
void OutSRT::sendNext(){
|
||||||
|
@ -78,7 +79,7 @@ namespace Mist{
|
||||||
|
|
||||||
void OutSRT::onHTTP(){
|
void OutSRT::onHTTP(){
|
||||||
std::string method = H.method;
|
std::string method = H.method;
|
||||||
webVTT = (H.url.find(".vtt") != std::string::npos);
|
webVTT = (H.url.find(".vtt") != std::string::npos) || (H.url.find(".webvtt") != std::string::npos);
|
||||||
if (H.GetVar("track") != ""){
|
if (H.GetVar("track") != ""){
|
||||||
size_t tid = atoll(H.GetVar("track").c_str());
|
size_t tid = atoll(H.GetVar("track").c_str());
|
||||||
if (M.getValidTracks().count(tid)){
|
if (M.getValidTracks().count(tid)){
|
||||||
|
@ -93,6 +94,7 @@ namespace Mist{
|
||||||
|
|
||||||
if (H.GetVar("from") != ""){filter_from = JSON::Value(H.GetVar("from")).asInt();}
|
if (H.GetVar("from") != ""){filter_from = JSON::Value(H.GetVar("from")).asInt();}
|
||||||
if (H.GetVar("to") != ""){filter_to = JSON::Value(H.GetVar("to")).asInt();}
|
if (H.GetVar("to") != ""){filter_to = JSON::Value(H.GetVar("to")).asInt();}
|
||||||
|
if (filter_to){realTime = 0;}
|
||||||
|
|
||||||
H.Clean();
|
H.Clean();
|
||||||
H.setCORSHeaders();
|
H.setCORSHeaders();
|
||||||
|
|
Loading…
Add table
Reference in a new issue