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){ | ||||
|     //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; | ||||
|     // 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 << (M.getEncryption(tid) == "" ? "3" : "5"); | ||||
|  | @ -90,20 +95,20 @@ namespace Mist{ | |||
|     std::deque<std::string> lines; | ||||
|     std::deque<uint16_t> durations; | ||||
|     uint32_t totalDuration = 0; | ||||
|     DTSC::Keys keys(M.keys(tid)); | ||||
|     DTSC::Fragments fragments(M.fragments(tid)); | ||||
|     DTSC::Keys keys(M.keys(timingTid)); | ||||
|     DTSC::Fragments fragments(M.fragments(timingTid)); | ||||
|     uint32_t firstFragment = fragments.getFirstValid(); | ||||
|     uint32_t endFragment = fragments.getEndValid(); | ||||
|     for (int i = firstFragment; i < endFragment; i++){ | ||||
|       uint64_t duration = fragments.getDuration(i); | ||||
|       size_t keyNumber = fragments.getFirstKey(i); | ||||
|       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; | ||||
|       char lineBuf[400]; | ||||
| 
 | ||||
|       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); | ||||
|       }else{ | ||||
|         if (sessId.size()){ | ||||
|  | @ -146,7 +151,7 @@ namespace Mist{ | |||
|       /*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++){ | ||||
|       result << *it; | ||||
|  | @ -179,6 +184,7 @@ namespace Mist{ | |||
|     capa["codecs"][0u][4u].append("+MP3"); | ||||
|     capa["codecs"][0u][5u].append("+AC3"); | ||||
|     capa["codecs"][0u][6u].append("+MP2"); | ||||
|     capa["codecs"][0u][6u].append("+subtitle"); | ||||
|     capa["methods"][0u]["handler"] = "http"; | ||||
|     capa["methods"][0u]["type"] = "html5/application/vnd.apple.mpegurl"; | ||||
|     capa["methods"][0u]["priority"] = 9; | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ namespace Mist{ | |||
|     capa["desc"] = "Pseudostreaming in SubRip Text (SRT) and WebVTT formats over HTTP"; | ||||
|     capa["url_match"].append("/$.srt"); | ||||
|     capa["url_match"].append("/$.vtt"); | ||||
|     capa["url_match"].append("/$.webvtt"); | ||||
|     capa["codecs"][0u][0u].append("subtitle"); | ||||
|     capa["methods"][0u]["handler"] = "http"; | ||||
|     capa["methods"][0u]["type"] = "html5/text/plain"; | ||||
|  | @ -23,7 +24,7 @@ namespace Mist{ | |||
|     capa["methods"][1u]["handler"] = "http"; | ||||
|     capa["methods"][1u]["type"] = "html5/text/vtt"; | ||||
|     capa["methods"][1u]["priority"] = 9; | ||||
|     capa["methods"][1u]["url_rel"] = "/$.vtt"; | ||||
|     capa["methods"][1u]["url_rel"] = "/$.webvtt"; | ||||
|   } | ||||
| 
 | ||||
|   void OutSRT::sendNext(){ | ||||
|  | @ -78,7 +79,7 @@ namespace Mist{ | |||
| 
 | ||||
|   void OutSRT::onHTTP(){ | ||||
|     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") != ""){ | ||||
|       size_t tid = atoll(H.GetVar("track").c_str()); | ||||
|       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("to") != ""){filter_to = JSON::Value(H.GetVar("to")).asInt();} | ||||
|     if (filter_to){realTime = 0;} | ||||
| 
 | ||||
|     H.Clean(); | ||||
|     H.setCORSHeaders(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Thulinma
						Thulinma