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
+ {
+ ///
+ /// Resizes a set of dimensions
+ ///
+ 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);
+ }
+
+ ///
+ /// Resizes a set of dimensions
+ ///
+ /// The original size object
+ /// A new fixed width, if desired
+ /// A new fixed neight, if desired
+ /// A max fixed width, if desired
+ /// A max fixed height, if desired
+ /// A new size object
+ 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 @@
+
False
..\packages\Rx-Main.1.0.11226\lib\Net4\System.Reactive.dll
@@ -57,6 +58,7 @@
+