From a613022209eb27895e079bebf7f7d8d6aef4d2ac Mon Sep 17 00:00:00 2001 From: casey langen Date: Sat, 3 Jun 2017 22:10:15 -0700 Subject: [PATCH] Deliberately under-estimate the response length for the on-demand transcoder. HTTP clients in the wild seem to, in general, get more cranky when we over-estimate and close the stream too early. --- src/plugins/websocket_remote/Constants.h | 1 + src/plugins/websocket_remote/HttpServer.cpp | 7 +++++++ src/plugins/websocket_remote/TranscodingDataStream.cpp | 6 +++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/plugins/websocket_remote/Constants.h b/src/plugins/websocket_remote/Constants.h index 48d5ac37d..399c7b293 100644 --- a/src/plugins/websocket_remote/Constants.h +++ b/src/plugins/websocket_remote/Constants.h @@ -81,6 +81,7 @@ namespace key { static const std::string title = "title"; static const std::string external_id = "external_id"; static const std::string filename = "filename"; + static const std::string duration = "duration"; static const std::string artist = "artist"; static const std::string album = "album"; static const std::string album_artist = "album_artist"; diff --git a/src/plugins/websocket_remote/HttpServer.cpp b/src/plugins/websocket_remote/HttpServer.cpp index fb150e445..523b2ec64 100644 --- a/src/plugins/websocket_remote/HttpServer.cpp +++ b/src/plugins/websocket_remote/HttpServer.cpp @@ -349,7 +349,9 @@ int HttpServer::HandleRequest( } if (track) { + std::string duration = GetMetadataString(track, key::duration); std::string filename = GetMetadataString(track, key::filename); + track->Release(); size_t bitrate = getUnsignedUrlParam(connection, "bitrate", 0); @@ -448,6 +450,11 @@ int HttpServer::HandleRequest( MHD_add_response_header(response, "X-musikcube-Estimated-Content-Length", "true"); } + if (duration.size()) { + MHD_add_response_header(response, "X-Content-Duration", duration.c_str()); + MHD_add_response_header(response, "Content-Duration", duration.c_str()); + } + if (byExternalId) { /* if we're using an on-demand transcoder, ensure the client does not cache the result because we have to guess the content length. */ diff --git a/src/plugins/websocket_remote/TranscodingDataStream.cpp b/src/plugins/websocket_remote/TranscodingDataStream.cpp index d67458c72..4dc03e612 100644 --- a/src/plugins/websocket_remote/TranscodingDataStream.cpp +++ b/src/plugins/websocket_remote/TranscodingDataStream.cpp @@ -61,7 +61,11 @@ TranscodingDataStream::TranscodingDataStream( this->decoder = context.environment->GetDecoder(this->input); if (this->decoder) { this->pcmBuffer = context.environment->GetBuffer(SAMPLES_PER_BUFFER); - this->length = (PositionType)(this->decoder->GetDuration() * 1000.0 * (float)bitrate / 8.0); + + /* note that we purposely under-estimate the content length by a couple + seconds. we do this because http clients seem to be more likely to be + throw a fit if we over estimate, instead of under-estimate. */ + this->length = (PositionType)((this->decoder->GetDuration() - 2.0) * 1000.0 * (float)bitrate / 8.0); } } }