diff options
| -rw-r--r-- | MediaBrowser.Api/HttpHandlers/VideoHandler.cs | 140 | ||||
| -rw-r--r-- | MediaBrowser.Api/ImageProcessor.cs | 74 | ||||
| -rw-r--r-- | MediaBrowser.Common/Drawing/DrawingUtils.cs | 81 | ||||
| -rw-r--r-- | MediaBrowser.Common/MediaBrowser.Common.csproj | 2 |
4 files changed, 219 insertions, 78 deletions
diff --git a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs index 32ba45ede..7fe82ef0c 100644 --- a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.IO;
using System.Linq;
using MediaBrowser.Model.Entities;
+using System.Drawing;
+using MediaBrowser.Common.Drawing;
namespace MediaBrowser.Api.HttpHandlers
{
@@ -41,12 +43,16 @@ namespace MediaBrowser.Api.HttpHandlers return true;
}
+ if (RequiresVideoConversion())
+ {
+ return true;
+ }
+
AudioStream audio = LibraryItem.AudioStreams.FirstOrDefault();
if (audio != null)
{
- // If the number of channels is greater than our desired channels, we need to transcode
- if (AudioChannels.HasValue && AudioChannels.Value < audio.Channels)
+ if (RequiresAudioConversion(audio))
{
return true;
}
@@ -100,6 +106,16 @@ namespace MediaBrowser.Api.HttpHandlers string args = "-vcodec " + codec;
+ if (!codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
+ {
+ if (Width.HasValue || Height.HasValue || MaxHeight.HasValue || MaxWidth.HasValue)
+ {
+ Size size = DrawingUtils.Resize(LibraryItem.Width, LibraryItem.Height, Width, Height, MaxWidth, MaxHeight);
+
+ args += string.Format(" -s {0}x{1}", size.Width, size.Height);
+ }
+ }
+
return args;
}
@@ -157,6 +173,11 @@ namespace MediaBrowser.Api.HttpHandlers return "libtheora";
}
+ if (!RequiresVideoConversion())
+ {
+ return "copy";
+ }
+
return "libx264";
}
@@ -181,7 +202,7 @@ namespace MediaBrowser.Api.HttpHandlers }
// See if we can just copy the stream
- if (HasBasicAudio(audioStream))
+ if (!RequiresAudioConversion(audioStream))
{
return "copy";
}
@@ -208,30 +229,131 @@ namespace MediaBrowser.Api.HttpHandlers return GetNumAudioChannelsParam(libraryItemChannels);
}
- private bool HasBasicAudio(AudioStream audio)
+ private bool RequiresVideoConversion()
+ {
+ // Check dimensions
+ if (Width.HasValue)
+ {
+ if (Width.Value != LibraryItem.Width)
+ {
+ return true;
+ }
+ }
+ if (Height.HasValue)
+ {
+ if (Height.Value != LibraryItem.Height)
+ {
+ return true;
+ }
+ }
+ if (MaxWidth.HasValue)
+ {
+ if (MaxWidth.Value < LibraryItem.Width)
+ {
+ return true;
+ }
+ }
+ if (MaxHeight.HasValue)
+ {
+ if (MaxHeight.Value < LibraryItem.Height)
+ {
+ return true;
+ }
+ }
+
+ if (LibraryItem.VideoCodec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 || LibraryItem.VideoCodec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ return false;
+ }
+
+ return false;
+ }
+
+ private bool RequiresAudioConversion(AudioStream audio)
{
if (AudioChannels.HasValue)
{
if (audio.Channels > AudioChannels.Value)
{
- return false;
+ return true;
}
}
if (audio.AudioFormat.IndexOf("aac", StringComparison.OrdinalIgnoreCase) != -1)
{
- return true;
+ return false;
}
if (audio.AudioFormat.IndexOf("ac-3", StringComparison.OrdinalIgnoreCase) != -1 || audio.AudioFormat.IndexOf("ac3", StringComparison.OrdinalIgnoreCase) != -1)
{
- return true;
+ return false;
}
if (audio.AudioFormat.IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1 || audio.AudioFormat.IndexOf("mp3", StringComparison.OrdinalIgnoreCase) != -1)
{
- return true;
+ return false;
}
- return false;
+ return true;
+ }
+
+ private int? Height
+ {
+ get
+ {
+ string val = QueryString["height"];
+
+ if (string.IsNullOrEmpty(val))
+ {
+ return null;
+ }
+
+ return int.Parse(val);
+ }
+ }
+
+ private int? Width
+ {
+ get
+ {
+ string val = QueryString["width"];
+
+ if (string.IsNullOrEmpty(val))
+ {
+ return null;
+ }
+
+ return int.Parse(val);
+ }
+ }
+
+ private int? MaxHeight
+ {
+ get
+ {
+ string val = QueryString["maxheight"];
+
+ if (string.IsNullOrEmpty(val))
+ {
+ return null;
+ }
+
+ return int.Parse(val);
+ }
}
+
+ private int? MaxWidth
+ {
+ get
+ {
+ string val = QueryString["maxwidth"];
+
+ if (string.IsNullOrEmpty(val))
+ {
+ return null;
+ }
+
+ return int.Parse(val);
+ }
+ }
+
}
}
diff --git a/MediaBrowser.Api/ImageProcessor.cs b/MediaBrowser.Api/ImageProcessor.cs index 014f65598..c4a2fdb69 100644 --- a/MediaBrowser.Api/ImageProcessor.cs +++ b/MediaBrowser.Api/ImageProcessor.cs @@ -3,6 +3,7 @@ using System.Drawing; using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
+using MediaBrowser.Common.Drawing;
namespace MediaBrowser.Api
{
@@ -12,40 +13,9 @@ namespace MediaBrowser.Api {
Image originalImage = Image.FromStream(sourceImageStream);
- var newWidth = originalImage.Width;
- var newHeight = originalImage.Height;
+ Size newSize = DrawingUtils.Resize(originalImage.Size, width, height, maxWidth, maxHeight);
- if (width.HasValue && height.HasValue)
- {
- newWidth = width.Value;
- newHeight = height.Value;
- }
-
- else if (height.HasValue)
- {
- newWidth = GetNewWidth(newHeight, newWidth, height.Value);
- newHeight = height.Value;
- }
-
- else if (width.HasValue)
- {
- newHeight = GetNewHeight(newHeight, newWidth, width.Value);
- newWidth = width.Value;
- }
-
- if (maxHeight.HasValue && maxHeight < newHeight)
- {
- newWidth = GetNewWidth(newHeight, newWidth, maxHeight.Value);
- newHeight = maxHeight.Value;
- }
-
- if (maxWidth.HasValue && maxWidth < newWidth)
- {
- newHeight = GetNewHeight(newHeight, newWidth, maxWidth.Value);
- newWidth = maxWidth.Value;
- }
-
- Bitmap thumbnail = new Bitmap(newWidth, newHeight, originalImage.PixelFormat);
+ Bitmap thumbnail = new Bitmap(newSize.Width, newSize.Height, originalImage.PixelFormat);
thumbnail.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);
Graphics thumbnailGraph = Graphics.FromImage(thumbnail);
@@ -55,7 +25,7 @@ namespace MediaBrowser.Api thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality;
thumbnailGraph.CompositingMode = CompositingMode.SourceOver;
- thumbnailGraph.DrawImage(originalImage, 0, 0, newWidth, newHeight);
+ thumbnailGraph.DrawImage(originalImage, 0, 0, newSize.Width, newSize.Height);
Write(originalImage, thumbnail, toStream, quality);
@@ -74,7 +44,7 @@ namespace MediaBrowser.Api }
else if (ImageFormat.Png.Equals(originalImage.RawFormat))
{
- SavePng(newImage, toStream);
+ newImage.Save(toStream, ImageFormat.Png);
}
else
{
@@ -96,22 +66,6 @@ namespace MediaBrowser.Api }
}
- private static void SavePng(Image newImage, Stream target)
- {
- if (target.CanSeek)
- {
- newImage.Save(target, ImageFormat.Png);
- }
- else
- {
- using (MemoryStream ms = new MemoryStream(4096))
- {
- newImage.Save(ms, ImageFormat.Png);
- ms.WriteTo(target);
- }
- }
- }
-
private static ImageCodecInfo GetImageCodeInfo(string mimeType)
{
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
@@ -126,23 +80,5 @@ namespace MediaBrowser.Api }
return info[1];
}
-
- private static int GetNewWidth(int currentHeight, int currentWidth, int newHeight)
- {
- decimal scaleFactor = newHeight;
- scaleFactor /= currentHeight;
- scaleFactor *= currentWidth;
-
- return Convert.ToInt32(scaleFactor);
- }
-
- private static int GetNewHeight(int currentHeight, int currentWidth, int newWidth)
- {
- decimal scaleFactor = newWidth;
- scaleFactor /= currentWidth;
- scaleFactor *= currentHeight;
-
- return Convert.ToInt32(scaleFactor);
- }
}
}
diff --git a/MediaBrowser.Common/Drawing/DrawingUtils.cs b/MediaBrowser.Common/Drawing/DrawingUtils.cs new file mode 100644 index 000000000..4c0b5c207 --- /dev/null +++ b/MediaBrowser.Common/Drawing/DrawingUtils.cs @@ -0,0 +1,81 @@ +using System;
+using System.Drawing;
+
+namespace MediaBrowser.Common.Drawing
+{
+ public static class DrawingUtils
+ {
+ /// <summary>
+ /// Resizes a set of dimensions
+ /// </summary>
+ public static Size Resize(int currentWidth, int currentHeight, int? width, int? height, int? maxWidth, int? maxHeight)
+ {
+ return Resize(new Size(currentWidth, currentHeight), width, height, maxWidth, maxHeight);
+ }
+
+ /// <summary>
+ /// Resizes a set of dimensions
+ /// </summary>
+ /// <param name="size">The original size object</param>
+ /// <param name="width">A new fixed width, if desired</param>
+ /// <param name="height">A new fixed neight, if desired</param>
+ /// <param name="maxWidth">A max fixed width, if desired</param>
+ /// <param name="maxHeight">A max fixed height, if desired</param>
+ /// <returns>A new size object</returns>
+ public static Size Resize(Size size, int? width, int? height, int? maxWidth, int? maxHeight)
+ {
+ decimal newWidth = size.Width;
+ decimal newHeight = size.Height;
+
+ if (width.HasValue && height.HasValue)
+ {
+ newWidth = width.Value;
+ newHeight = height.Value;
+ }
+
+ else if (height.HasValue)
+ {
+ newWidth = GetNewWidth(newHeight, newWidth, height.Value);
+ newHeight = height.Value;
+ }
+
+ else if (width.HasValue)
+ {
+ newHeight = GetNewHeight(newHeight, newWidth, width.Value);
+ newWidth = width.Value;
+ }
+
+ if (maxHeight.HasValue && maxHeight < newHeight)
+ {
+ newWidth = GetNewWidth(newHeight, newWidth, maxHeight.Value);
+ newHeight = maxHeight.Value;
+ }
+
+ if (maxWidth.HasValue && maxWidth < newWidth)
+ {
+ newHeight = GetNewHeight(newHeight, newWidth, maxWidth.Value);
+ newWidth = maxWidth.Value;
+ }
+
+ return new Size(Convert.ToInt32(newWidth), Convert.ToInt32(newHeight));
+ }
+
+ private static decimal GetNewWidth(decimal currentHeight, decimal currentWidth, int newHeight)
+ {
+ decimal scaleFactor = newHeight;
+ scaleFactor /= currentHeight;
+ scaleFactor *= currentWidth;
+
+ return scaleFactor;
+ }
+
+ private static decimal GetNewHeight(decimal currentHeight, decimal currentWidth, int newWidth)
+ {
+ decimal scaleFactor = newWidth;
+ scaleFactor /= currentWidth;
+ scaleFactor *= currentHeight;
+
+ return scaleFactor;
+ }
+ }
+}
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 25a855c38..bd3a58c04 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -41,6 +41,7 @@ <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
+ <Reference Include="System.Drawing" />
<Reference Include="System.Reactive, Version=1.0.10621.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Rx-Main.1.0.11226\lib\Net4\System.Reactive.dll</HintPath>
@@ -57,6 +58,7 @@ <ItemGroup>
<Compile Include="Configuration\ApplicationPaths.cs" />
<Compile Include="Configuration\BaseApplicationConfiguration.cs" />
+ <Compile Include="Drawing\DrawingUtils.cs" />
<Compile Include="Events\GenericItemEventArgs.cs" />
<Compile Include="Net\Handlers\StaticFileHandler.cs" />
<Compile Include="Net\MimeTypes.cs" />
|
