diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
index 3581d006e..b64e1750c 100644
--- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
@@ -15,6 +15,12 @@ namespace MediaBrowser.Api.Playback.Progressive
[Route("/Audio/{Id}/stream.flac", "GET")]
[Route("/Audio/{Id}/stream.ogg", "GET")]
[Route("/Audio/{Id}/stream", "GET")]
+ [Route("/Audio/{Id}/stream.mp3", "HEAD")]
+ [Route("/Audio/{Id}/stream.wma", "HEAD")]
+ [Route("/Audio/{Id}/stream.aac", "HEAD")]
+ [Route("/Audio/{Id}/stream.flac", "HEAD")]
+ [Route("/Audio/{Id}/stream.ogg", "HEAD")]
+ [Route("/Audio/{Id}/stream", "HEAD")]
[ServiceStack.ServiceHost.Api(Description = "Gets an audio stream")]
public class GetAudioStream : StreamRequest
{
@@ -38,7 +44,17 @@ namespace MediaBrowser.Api.Playback.Progressive
/// System.Object.
public object Get(GetAudioStream request)
{
- return ProcessRequest(request);
+ return ProcessRequest(request, false);
+ }
+
+ ///
+ /// Gets the specified request.
+ ///
+ /// The request.
+ /// System.Object.
+ public object Head(GetAudioStream request)
+ {
+ return ProcessRequest(request, true);
}
///
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index a4acc2845..56bb18752 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -94,38 +94,46 @@ namespace MediaBrowser.Api.Playback.Progressive
/// Processes the request.
///
/// The request.
+ /// if set to true [is head request].
/// Task.
- protected object ProcessRequest(StreamRequest request)
+ protected object ProcessRequest(StreamRequest request, bool isHeadRequest)
{
var state = GetState(request);
if (request.Static)
{
- return ToStaticFileResult(state.Item.Path);
+ return ToStaticFileResult(state.Item.Path, isHeadRequest);
}
var outputPath = GetOutputFilePath(state);
if (File.Exists(outputPath) && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive))
{
- return ToStaticFileResult(outputPath);
+ return ToStaticFileResult(outputPath, isHeadRequest);
}
- return GetStreamResult(state).Result;
+ return GetStreamResult(state, isHeadRequest).Result;
}
///
/// Gets the stream result.
///
/// The state.
+ /// if set to true [is head request].
/// Task{System.Object}.
- private async Task GetStreamResult(StreamState state)
+ private async Task GetStreamResult(StreamState state, bool isHeadRequest)
{
// Use the command line args with a dummy playlist path
var outputPath = GetOutputFilePath(state);
Response.ContentType = MimeTypes.GetMimeType(outputPath);
+ // Headers only
+ if (isHeadRequest)
+ {
+ return null;
+ }
+
if (!File.Exists(outputPath))
{
await StartFFMpeg(state, outputPath).ConfigureAwait(false);
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index cc1c5b1fc..0e94b7df8 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -23,6 +23,18 @@ namespace MediaBrowser.Api.Playback.Progressive
[Route("/Videos/{Id}/stream.avi", "GET")]
[Route("/Videos/{Id}/stream.m2ts", "GET")]
[Route("/Videos/{Id}/stream", "GET")]
+ [Route("/Videos/{Id}/stream.ts", "HEAD")]
+ [Route("/Videos/{Id}/stream.webm", "HEAD")]
+ [Route("/Videos/{Id}/stream.asf", "HEAD")]
+ [Route("/Videos/{Id}/stream.wmv", "HEAD")]
+ [Route("/Videos/{Id}/stream.ogv", "HEAD")]
+ [Route("/Videos/{Id}/stream.mp4", "HEAD")]
+ [Route("/Videos/{Id}/stream.m4v", "HEAD")]
+ [Route("/Videos/{Id}/stream.mkv", "HEAD")]
+ [Route("/Videos/{Id}/stream.mpeg", "HEAD")]
+ [Route("/Videos/{Id}/stream.avi", "HEAD")]
+ [Route("/Videos/{Id}/stream.m2ts", "HEAD")]
+ [Route("/Videos/{Id}/stream", "HEAD")]
[ServiceStack.ServiceHost.Api(Description = "Gets a video stream")]
public class GetVideoStream : VideoStreamRequest
{
@@ -46,9 +58,14 @@ namespace MediaBrowser.Api.Playback.Progressive
/// System.Object.
public object Get(GetVideoStream request)
{
- return ProcessRequest(request);
+ return ProcessRequest(request, false);
}
+ public object Head(GetVideoStream request)
+ {
+ return ProcessRequest(request, true);
+ }
+
///
/// Gets the command line arguments.
///
diff --git a/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs b/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs
index 0445cd863..baa5b0888 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs
@@ -132,14 +132,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer
return factoryFn();
}
-
+
///
/// To the static file result.
///
/// The path.
+ /// if set to true [headers only].
/// System.Object.
/// path
- protected object ToStaticFileResult(string path)
+ protected object ToStaticFileResult(string path, bool headersOnly = false)
{
if (string.IsNullOrEmpty(path))
{
@@ -150,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
var cacheKey = path + dateModified.Ticks;
- return ToStaticResult(cacheKey.GetMD5(), dateModified, null, MimeTypes.GetMimeType(path), () => Task.FromResult(GetFileStream(path)));
+ return ToStaticResult(cacheKey.GetMD5(), dateModified, null, MimeTypes.GetMimeType(path), () => Task.FromResult(GetFileStream(path)), headersOnly);
}
///
@@ -162,7 +163,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
{
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous);
}
-
+
///
/// To the static result.
///
@@ -171,9 +172,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// Duration of the cache.
/// Type of the content.
/// The factory fn.
+ /// if set to true [headers only].
/// System.Object.
/// cacheKey
- protected object ToStaticResult(Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType, Func> factoryFn)
+ protected object ToStaticResult(Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType, Func> factoryFn, bool headersOnly = false)
{
if (cacheKey == Guid.Empty)
{
@@ -203,7 +205,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
Response.AddHeader("Vary", "Accept-Encoding");
}
- return ToStaticResult(contentType, factoryFn, compress).Result;
+ return ToStaticResult(contentType, factoryFn, compress, headersOnly).Result;
}
///
@@ -249,8 +251,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// Type of the content.
/// The factory fn.
/// if set to true [compress].
+ /// if set to true [headers only].
/// System.Object.
- private async Task
/// The source stream.
- public Stream SourceStream { get; set; }
- public HttpListenerResponse Response { get; set; }
- public NameValueCollection RequestHeaders { get; set; }
+ private Stream SourceStream { get; set; }
+ private HttpListenerResponse Response { get; set; }
+ private NameValueCollection RequestHeaders { get; set; }
+ private bool IsHeadRequest { get; set; }
///
/// Initializes a new instance of the class.
@@ -25,11 +26,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// The request headers.
/// The response.
/// The source.
- public RangeRequestWriter(NameValueCollection requestHeaders, HttpListenerResponse response, Stream source)
+ /// if set to true [is head request].
+ public RangeRequestWriter(NameValueCollection requestHeaders, HttpListenerResponse response, Stream source, bool isHeadRequest)
{
RequestHeaders = requestHeaders;
Response = response;
SourceStream = source;
+ IsHeadRequest = isHeadRequest;
}
///
@@ -132,6 +135,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer
Response.ContentLength64 = rangeLength;
Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength);
+ // Headers only
+ if (IsHeadRequest)
+ {
+ return Task.FromResult(true);
+ }
+
if (rangeStart > 0)
{
sourceStream.Position = rangeStart;
@@ -157,6 +166,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer
Response.ContentLength64 = rangeLength;
Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength);
+ // Headers only
+ if (IsHeadRequest)
+ {
+ return;
+ }
+
sourceStream.Position = rangeStart;
// Fast track to just copy the stream to the end
diff --git a/MediaBrowser.WebDashboard/Html/scripts/MediaPlayer.js b/MediaBrowser.WebDashboard/Html/scripts/MediaPlayer.js
index 486527bd0..4c78d5dfa 100644
--- a/MediaBrowser.WebDashboard/Html/scripts/MediaPlayer.js
+++ b/MediaBrowser.WebDashboard/Html/scripts/MediaPlayer.js
@@ -108,6 +108,7 @@
var item = items[0];
+ // Account for screen rotation. Use the larger dimension as the width.
var screenWidth = Math.max(screen.height, screen.width);
var screenHeight = Math.min(screen.height, screen.width);
@@ -152,13 +153,6 @@
html += '';
html += '';
- //html += '';
- //html += '';
- //html += '';
- //html += '';
- ////html += '';
- //html += '';
-
html += '