From d0040e9b41617b42b009419fe7f2b147a13b5c3b Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 15 Jan 2013 10:56:19 +0100 Subject: [PATCH] Fixed HLS playback in Apple products (tested on Mac version of Quicktime). --- src/conn_http.cpp | 5 ++--- src/conn_http_live.cpp | 29 ++++++++++++++++------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/conn_http.cpp b/src/conn_http.cpp index 53d4a10f..60741fce 100644 --- a/src/conn_http.cpp +++ b/src/conn_http.cpp @@ -389,7 +389,7 @@ namespace Connector_HTTP { << ")" << std::endl; #endif bool closeConnection = false; - if( Client.GetHeader( "Connection" ) == "close" ) { + if (Client.GetHeader("Connection") == "close"){ closeConnection = true; } @@ -405,8 +405,7 @@ namespace Connector_HTTP { #if DEBUG >= 4 std::cout << "Completed request (" << conn->getSocket() << ") " << handler << " in " << (Util::getMS() - startms) << " ms" << std::endl; #endif - if( closeConnection ) { -fprintf( stderr, "Called for connection close\n" ); + if (closeConnection){ break; } Client.Clean(); //clean for any possible next requests diff --git a/src/conn_http_live.cpp b/src/conn_http_live.cpp index 24cb5482..41388388 100644 --- a/src/conn_http_live.cpp +++ b/src/conn_http_live.cpp @@ -56,22 +56,22 @@ namespace Connector_HTTP { if (metadata.isMember("length") && metadata["length"].asInt() > 0){ Result << "#EXTM3U\r\n" //"#EXT-X-VERSION:1\r\n" - //"#EXT-X-ALLOW-CACHE:YES\r\n" + //"#EXT-X-ALLOW-CACHE:YES\r\n" "#EXT-X-TARGETDURATION:" << (longestFragment / 1000) + 1 << "\r\n" - "#EXT-X-MEDIA-SEQUENCE:0\r\n"; + "#EXT-X-MEDIA-SEQUENCE:0\r\n"; //"#EXT-X-PLAYLIST-TYPE:VOD\r\n"; int lastDuration = 0; bool writeOffset = true; for (int i = 0; i < fragIndices.size() - 1; i++){ - Result << "#EXTINF:" << (metadata["keytime"][fragIndices[i+1]].asInt() - lastDuration) / 1000 << ", no desc\r\n" << fragIndices[i] << "_" + Result << "#EXTINF:" << (metadata["keytime"][fragIndices[i + 1]].asInt() - lastDuration) / 1000 << ", no desc\r\n" << fragIndices[i] << "_" << fragIndices[i + 1] - fragIndices[i] << ".ts\r\n"; - lastDuration = metadata["keytime"][fragIndices[i+1]].asInt(); + lastDuration = metadata["keytime"][fragIndices[i + 1]].asInt(); } Result << "#EXT-X-ENDLIST"; }else{ Result << "#EXTM3U\r\n" "#EXT-X-VERSION:4\r\n" - "#EXT-X-MEDIA-SEQUENCE:1\r\n" + "#EXT-X-MEDIA-SEQUENCE:0\r\n" "#EXT-X-TARGETDURATION:" << ((metadata["video"]["keyms"].asInt() + metadata["video"]["keyvar"].asInt()) / 1000) + 1 << "\r\n"; } #if DEBUG >= 8 @@ -112,7 +112,7 @@ namespace Connector_HTTP { bool haveAvcc = false; std::vector fragIndices; - + std::string manifestType; int Segment = -1; @@ -171,7 +171,7 @@ namespace Connector_HTTP { streamname = HTTP_R.url.substr(5, HTTP_R.url.find("/", 5) - 5); if (HTTP_R.url.find(".m3u8") != std::string::npos){ manifestType = "audio/x-mpegurl"; - } else { + }else{ manifestType = "audio/mpegurl"; } if ( !Strm.metadata.isNull()){ @@ -183,10 +183,9 @@ namespace Connector_HTTP { } std::string manifest = BuildIndex(streamname, Strm.metadata); HTTP_S.SetBody(manifest); -fprintf( stderr, "%s\n", HTTP_S.GetHeader( "Content-Type" ).c_str() ); conn.SendNow(HTTP_S.BuildResponse("200", "OK")); #if DEBUG >= 3 - printf("Sent manifest\n"); + printf("Sent index\n"); #endif pending_manifest = false; }else{ @@ -243,14 +242,15 @@ fprintf( stderr, "%s\n", HTTP_S.GetHeader( "Content-Type" ).c_str() ); } if (pending_manifest){ HTTP_S.Clean(); + HTTP_S.protocol = "HTTP/1.1"; HTTP_S.SetHeader("Cache-Control", "no-cache"); if (Strm.metadata.isMember("length")){ receive_marks = true; } std::string manifest = BuildIndex(streamname, Strm.metadata); HTTP_S.SetHeader("Content-Type", manifestType); + HTTP_S.SetHeader("Connection", "keep-alive"); HTTP_S.SetBody(manifest); -fprintf( stderr, "%s\n", HTTP_S.GetHeader( "Content-Type" ).c_str() ); conn.SendNow(HTTP_S.BuildResponse("200", "OK")); #if DEBUG >= 3 printf("Sent manifest\n"); @@ -270,7 +270,9 @@ fprintf( stderr, "%s\n", HTTP_S.GetHeader( "Content-Type" ).c_str() ); fprintf(stderr, "Sending a fragment..."); #endif HTTP_S.Clean(); - HTTP_S.SetHeader("Content-Type", "video/MP2T"); + HTTP_S.protocol = "HTTP/1.1"; + HTTP_S.SetHeader("Content-Type", "video/mp2t"); + HTTP_S.SetHeader("Connection", "keep-alive"); HTTP_S.SetBody(""); HTTP_S.SetHeader("Content-Length", TSBuf.str().size()); conn.SendNow(HTTP_S.BuildResponse("200", "OK")); @@ -384,17 +386,18 @@ fprintf( stderr, "%s\n", HTTP_S.GetHeader( "Content-Type" ).c_str() ); } if (pending_manifest && !Strm.metadata.isNull()){ HTTP_S.Clean(); + HTTP_S.protocol = "HTTP/1.1"; HTTP_S.SetHeader("Cache-Control", "no-cache"); if (Strm.metadata.isMember("length")){ receive_marks = true; } HTTP_S.SetHeader("Content-Type", manifestType); + HTTP_S.SetHeader("Connection", "keep-alive"); std::string manifest = BuildIndex(streamname, Strm.metadata); HTTP_S.SetBody(manifest); -fprintf( stderr, "%s\n", HTTP_S.GetHeader( "Content-Type" ).c_str() ); conn.SendNow(HTTP_S.BuildResponse("200", "OK")); #if DEBUG >= 3 - printf("Sent manifest\n"); + printf("Sent index\n"); #endif pending_manifest = false; }