support static trailer streaming

This commit is contained in:
Luke Pulverenti
2013-05-17 14:05:49 -04:00
parent da7af24fca
commit e2d6a5c05d
10 changed files with 195 additions and 22 deletions

View File

@@ -56,6 +56,8 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
@@ -82,6 +84,7 @@
<Compile Include="Playback\Progressive\BaseProgressiveStreamingService.cs" />
<Compile Include="Playback\BaseStreamingService.cs" />
<Compile Include="Playback\Progressive\ProgressiveStreamWriter.cs" />
<Compile Include="Playback\StaticRemoteStreamWriter.cs" />
<Compile Include="Playback\StreamRequest.cs" />
<Compile Include="Playback\StreamState.cs" />
<Compile Include="Playback\Progressive\VideoService.cs" />

View File

@@ -621,10 +621,27 @@ namespace MediaBrowser.Api.Playback
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
protected string GetUserAgentParam(BaseItem item)
{
var useragent = GetUserAgent(item);
if (!string.IsNullOrEmpty(useragent))
{
return "-user-agent \"" + useragent + "\"";
}
return string.Empty;
}
/// <summary>
/// Gets the user agent.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
protected string GetUserAgent(BaseItem item)
{
if (item.Path.IndexOf("apple.com", StringComparison.OrdinalIgnoreCase) != -1)
{
return "-user-agent \"QuickTime/7.6.2\"";
return "QuickTime/7.6.2";
}
return string.Empty;

View File

@@ -1,4 +1,7 @@
using MediaBrowser.Api.Images;
using System.Net;
using System.Net.Cache;
using System.Net.Http;
using MediaBrowser.Api.Images;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Common.Net;
@@ -188,6 +191,11 @@ namespace MediaBrowser.Api.Playback.Progressive
var responseHeaders = new Dictionary<string, string>();
if (request.Static && state.Item.LocationType == LocationType.Remote)
{
return GetStaticRemoteStreamResult(state.Item, responseHeaders, isHeadRequest).Result;
}
var outputPath = GetOutputFilePath(state);
var outputPathExists = File.Exists(outputPath);
@@ -209,6 +217,60 @@ namespace MediaBrowser.Api.Playback.Progressive
return GetStreamResult(state, responseHeaders, isHeadRequest).Result;
}
/// <summary>
/// Gets the static remote stream result.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="responseHeaders">The response headers.</param>
/// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
/// <returns>Task{System.Object}.</returns>
private async Task<object> GetStaticRemoteStreamResult(BaseItem item, Dictionary<string, string> responseHeaders, bool isHeadRequest)
{
responseHeaders["Accept-Ranges"] = "none";
var httpClient = new HttpClient(new WebRequestHandler
{
CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache),
AutomaticDecompression = DecompressionMethods.None
});
using (var message = new HttpRequestMessage(HttpMethod.Get, item.Path))
{
var useragent = GetUserAgent(item);
if (!string.IsNullOrEmpty(useragent))
{
message.Headers.Add("User-Agent", useragent);
}
var response = await httpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var contentType = response.Content.Headers.ContentType.MediaType;
// Headers only
if (isHeadRequest)
{
response.Dispose();
return ResultFactory.GetResult(null, contentType, responseHeaders);
}
var result = new StaticRemoteStreamWriter(response, httpClient);
result.Options["Content-Type"] = contentType;
// Add the response headers to the result object
foreach (var header in responseHeaders)
{
result.Options[header.Key] = header.Value;
}
return result;
}
}
/// <summary>
/// Gets the album art response.
/// </summary>

View File

@@ -0,0 +1,75 @@
using ServiceStack.Service;
using ServiceStack.ServiceHost;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace MediaBrowser.Api.Playback
{
/// <summary>
/// Class StaticRemoteStreamWriter
/// </summary>
public class StaticRemoteStreamWriter : IStreamWriter, IHasOptions
{
/// <summary>
/// The _input stream
/// </summary>
private readonly HttpResponseMessage _msg;
private readonly HttpClient _client;
/// <summary>
/// The _options
/// </summary>
private readonly IDictionary<string, string> _options = new Dictionary<string, string>();
/// <summary>
/// Initializes a new instance of the <see cref="StaticRemoteStreamWriter"/> class.
/// </summary>
public StaticRemoteStreamWriter(HttpResponseMessage msg, HttpClient client)
{
_msg = msg;
_client = client;
}
/// <summary>
/// Gets the options.
/// </summary>
/// <value>The options.</value>
public IDictionary<string, string> Options
{
get { return _options; }
}
/// <summary>
/// Writes to.
/// </summary>
/// <param name="responseStream">The response stream.</param>
public void WriteTo(Stream responseStream)
{
var task = WriteToAsync(responseStream);
Task.WaitAll(task);
}
/// <summary>
/// Writes to async.
/// </summary>
/// <param name="responseStream">The response stream.</param>
/// <returns>Task.</returns>
public async Task WriteToAsync(Stream responseStream)
{
using (_client)
{
using (_msg)
{
using (var input = await _msg.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
await input.CopyToAsync(responseStream).ConfigureAwait(false);
}
}
}
}
}
}

View File

@@ -135,7 +135,7 @@ namespace MediaBrowser.Api.UserLibrary
{
if (!string.IsNullOrEmpty(request.NameStartsWithOrGreater))
{
items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.Name, StringComparison.OrdinalIgnoreCase) < 1);
items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.Name, StringComparison.CurrentCultureIgnoreCase) < 1);
}
var filters = request.GetFilters().ToList();

View File

@@ -456,7 +456,7 @@ namespace MediaBrowser.Api.UserLibrary
if (!string.IsNullOrEmpty(request.NameStartsWithOrGreater))
{
items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.SortName, StringComparison.OrdinalIgnoreCase) < 1);
items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.SortName, StringComparison.CurrentCultureIgnoreCase) < 1);
}
// Filter by Series Status