ShareX.MediaLib interim commit

This commit is contained in:
Jaex 2015-08-04 10:31:43 +03:00
parent 2864cfeb0f
commit d8635a571a
9 changed files with 577 additions and 55 deletions

View file

@ -39,13 +39,6 @@ public enum TextFileExtensions
txt, log, nfo, c, cpp, cc, cxx, h, hpp, hxx, cs, vb, html, htm, xhtml, xht, xml, css, js, php, bat, java, lua, py, pl, cfg, ini txt, log, nfo, c, cpp, cc, cxx, h, hpp, hxx, cs, vb, html, htm, xhtml, xht, xml, css, js, php, bat, java, lua, py, pl, cfg, ini
} }
public enum EncryptionStrength
{
Low = 128,
Medium = 192,
High = 256
}
public enum EDataType public enum EDataType
{ {
Default, Default,
@ -55,14 +48,6 @@ public enum EDataType
URL URL
} }
public enum EInputType
{
None,
Clipboard,
FileSystem,
Screenshot
}
public enum GIFQuality // Localized public enum GIFQuality // Localized
{ {
Default, Default,
@ -73,34 +58,18 @@ public enum GIFQuality // Localized
public enum EImageFormat public enum EImageFormat
{ {
[Description("png")]
PNG, PNG,
[Description("jpg")]
JPEG, JPEG,
[Description("gif")]
GIF, GIF,
[Description("bmp")]
BMP, BMP,
[Description("tif")]
TIFF TIFF
} }
public enum AnimatedImageFormat
{
PNG,
GIF
}
public enum TaskStatus
{
InQueue,
Preparing,
Working,
Stopping,
Completed
}
public enum TaskProgress
{
ReportStarted,
ReportProgress
}
public enum TriangleAngle public enum TriangleAngle
{ {
Top, Top,

39
ShareX.MediaLib/Enums.cs Normal file
View file

@ -0,0 +1,39 @@
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright © 2007-2015 ShareX Developers
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
using System.ComponentModel;
namespace ShareX.MediaLib
{
public enum ThumbnailLocationType
{
[Description("Default folder")]
DefaultFolder,
[Description("Custom folder")]
CustomFolder,
[Description("Parent folder of the media file")]
ParentFolder
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ShareX MediaLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("ShareX Developers")]
[assembly: AssemblyProduct("ShareX")]
[assembly: AssemblyCopyright("Copyright © 2007-2015 ShareX Developers")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1a190e53-1419-4cc2-b0e5-3bc7ea861c8b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,52 @@
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright © 2007-2015 ShareX Developers
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace ShareX.MediaLib
{
internal class ScreenshotInfo
{
public string Args { get; set; }
public string FullImageLink { get; set; }
public string LinkedThumbnail { get; set; }
public string LocalPath { get; set; }
public TimeSpan Timestamp { get; set; }
public ScreenshotInfo(string fp)
{
LocalPath = fp;
}
public override string ToString()
{
return Path.GetFileName(LocalPath);
}
}
}

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.MediaLib</RootNamespace>
<AssemblyName>ShareX.MediaLib</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Enums.cs" />
<Compile Include="ScreenshotInfo.cs" />
<Compile Include="VideoThumbnailer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VideoThumbnailOptions.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ShareX.HelpersLib\ShareX.HelpersLib.csproj">
<Project>{327750e1-9fb7-4cc3-8aea-9bc42180cad3}</Project>
<Name>ShareX.HelpersLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,86 @@
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright © 2007-2015 ShareX Developers
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
using ShareX.HelpersLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
namespace ShareX.MediaLib
{
public class VideoThumbnailOptions
{
[Category("Screenshots"), DefaultValue(""), Description("Output folder where screenshots will get saved.")]
public string OutputDirectory { get; set; }
[Category("Screenshots"), DefaultValue(EImageFormat.PNG), Description("FFmpeg thumbnail extension e.g. png or jpg.")]
public EImageFormat FFmpegThumbnailExtension { get; set; }
[Category("Screenshots"), DefaultValue(3), Description("Total number of screenshots to take.")]
public int ScreenshotCount { get; set; }
[Category("Screenshots"), DefaultValue(true), Description("Choose random frame each time a media file is processed.")]
public bool RandomFrame { get; set; }
[Category("Screenshots"), DefaultValue(true), Description("Upload screenshots.")]
public bool UploadScreenshots { get; set; }
[Category("Screenshots"), DefaultValue(true), Description("Keep or delete screenshots after processing files.")]
public bool KeepScreenshots { get; set; }
[Category("Screenshots"), DefaultValue(true), Description("Create screenshots using thumbnailer.")]
public bool CreateScreenshots { get; set; }
[Category("Screenshots"), DefaultValue(ThumbnailLocationType.DefaultFolder), Description("Create screenshots in the same folders as the media file, default torrent folder or in a custom folder.")]
public ThumbnailLocationType ScreenshotsLocation { get; set; }
[Category("Screenshots"), DefaultValue(0), Description("Maximum thumbnail width size, 0 means don't resize.")]
public int MaxThumbnailWidth { get; set; }
[Category("Screenshots / Combined"), DefaultValue(false), Description("Combine all screenshots to one large screenshot.")]
public bool CombineScreenshots { get; set; }
[Category("Screenshots / Combined"), DefaultValue(20), Description("Space between border and content as pixel.")]
public int Padding { get; set; }
[Category("Screenshots / Combined"), DefaultValue(10), Description("Space between screenshots as pixel.")]
public int Spacing { get; set; }
[Category("Screenshots / Combined"), DefaultValue(1), Description("Number of screenshots per row.")]
public int ColumnCount { get; set; }
[Category("Screenshots / Combined"), DefaultValue(true), Description("Add movie information to the combined screenshot.")]
public bool AddMovieInfo { get; set; }
[Category("Screenshots / Combined"), DefaultValue(true), Description("Add timestamp of screenshot at corner of image.")]
public bool AddTimestamp { get; set; }
[Category("Screenshots / Combined"), DefaultValue(true), Description("Draw rectangle shadow behind thumbnails.")]
public bool DrawShadow { get; set; }
}
}

View file

@ -0,0 +1,279 @@
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright © 2007-2015 ShareX Developers
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
using ShareX.HelpersLib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
namespace ShareX.MediaLib
{
public class VideoThumbnailer
{
public string MediaPath { get; private set; }
public string FFmpegPath { get; private set; }
public VideoThumbnailOptions Options { get; private set; }
private List<ScreenshotInfo> TempScreenshots = new List<ScreenshotInfo>();
private List<ScreenshotInfo> Screenshots = new List<ScreenshotInfo>();
protected int TimeSlice;
protected List<int> MediaSeekTimes = new List<int>();
public VideoThumbnailer(string mediaPath, string ffmpegPath, VideoThumbnailOptions options)
{
FFmpegPath = ffmpegPath;
Options = options;
TimeSlice = GetTimeSlice(Options.ScreenshotCount);
for (int i = 1; i < Options.ScreenshotCount + 2; i++)
{
MediaSeekTimes.Add(GetTimeSlice(Options.ScreenshotCount, 2) * i);
}
}
public virtual void TakeScreenshots()
{
if (!File.Exists(FFmpegPath)) return;
for (int i = 0; i < Options.ScreenshotCount; i++)
{
string mediaFileName = Path.GetFileNameWithoutExtension(MediaPath);
//worker.ReportProgress((int)ProgressType.UPDATE_STATUSBAR_DEBUG, string.Format("Taking screenshot {0} of {1} for {2}", i + 1, Options.ScreenshotCount, mediaFileName));
int timeSliceElapsed = Options.RandomFrame ? GetRandomTimeSlice(i) : TimeSlice * (i + 1);
string filename = string.Format("{0}-{1}.{2}", mediaFileName, timeSliceElapsed.ToString("00000"), Options.FFmpegThumbnailExtension);
string tempScreenshotPath = Path.Combine(Options.OutputDirectory, filename);
ProcessStartInfo psi = new ProcessStartInfo(FFmpegPath);
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.Arguments = string.Format("-ss {0} -i \"{1}\" -f image2 -vframes 1 -y \"{2}\"", timeSliceElapsed, MediaPath, tempScreenshotPath);
using (Process p = new Process())
{
p.StartInfo = psi;
p.Start();
p.WaitForExit(1000 * 30);
p.Close();
}
if (File.Exists(tempScreenshotPath))
{
ScreenshotInfo screenshotInfo = new ScreenshotInfo(tempScreenshotPath)
{
Args = psi.Arguments,
Timestamp = TimeSpan.FromSeconds(timeSliceElapsed)
};
TempScreenshots.Add(screenshotInfo);
}
}
Finish();
}
protected virtual void Finish()
{
if (TempScreenshots != null && TempScreenshots.Count > 0)
{
if (Options.CombineScreenshots)
{
string temp_fp = "";
using (Image img = CombineScreenshots(TempScreenshots))
{
temp_fp = Path.Combine(Options.OutputDirectory, Path.GetFileNameWithoutExtension(MediaPath) + "_s." + Options.FFmpegThumbnailExtension);
switch (Options.FFmpegThumbnailExtension)
{
case EImageFormat.PNG:
img.Save(temp_fp, ImageFormat.Png);
break;
case EImageFormat.JPEG:
img.Save(temp_fp, ImageFormat.Jpeg);
break;
}
Screenshots.Add(new ScreenshotInfo(temp_fp) { Args = TempScreenshots[0].Args });
}
TempScreenshots.ForEach(x => File.Delete(x.LocalPath));
}
else
{
Screenshots.AddRange(TempScreenshots);
}
}
}
protected int GetRandomTimeSlice(int start)
{
Random random = new Random();
return (int)(random.NextDouble() * (MediaSeekTimes[start + 1] - MediaSeekTimes[start]) + MediaSeekTimes[start]);
}
protected int GetTimeSlice(int numScreenshots, int extraSlices = 1)
{
return (int)(10 / ((numScreenshots + extraSlices) * 1000));
}
private Image CombineScreenshots(List<ScreenshotInfo> screenshots)
{
List<Image> images = new List<Image>();
Image finalImage = null;
try
{
string infoString = "";
int infoStringHeight = 0;
if (Options.AddMovieInfo)
{
//infoString = MediaFile.GetMTNString();
using (Font font = new Font("Arial", 14))
{
infoStringHeight = Helpers.MeasureText(infoString, font).Height;
}
}
foreach (ScreenshotInfo screenshot in screenshots)
{
Image img = Image.FromFile(screenshot.LocalPath);
if (Options.MaxThumbnailWidth > 0 && img.Width > Options.MaxThumbnailWidth)
{
int maxThumbnailHeight = (int)((float)Options.MaxThumbnailWidth / img.Width * img.Height);
img = ImageHelpers.ResizeImage(img, Options.MaxThumbnailWidth, maxThumbnailHeight);
}
images.Add(img);
}
int columnCount = Options.ColumnCount;
int thumbWidth = images[0].Width;
int width = Options.Padding * 2 +
thumbWidth * columnCount +
(columnCount - 1) * Options.Spacing;
int rowCount = (int)Math.Ceiling(images.Count / (float)columnCount);
int thumbHeight = images[0].Height;
int height = Options.Padding * 3 +
infoStringHeight +
thumbHeight * rowCount +
(rowCount - 1) * Options.Spacing;
finalImage = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(finalImage))
{
g.Clear(Color.WhiteSmoke);
if (!string.IsNullOrEmpty(infoString))
{
using (Font font = new Font("Arial", 14))
{
g.DrawString(infoString, font, Brushes.Black, Options.Padding, Options.Padding);
}
}
int i = 0;
int offsetY = Options.Padding * 2 + infoStringHeight;
for (int y = 0; y < rowCount; y++)
{
int offsetX = Options.Padding;
for (int x = 0; x < columnCount; x++)
{
if (Options.DrawShadow)
{
int shadowOffset = 3;
using (Brush shadowBrush = new SolidBrush(Color.FromArgb(50, Color.Black)))
{
g.FillRectangle(shadowBrush, offsetX + shadowOffset, offsetY + shadowOffset, thumbWidth, thumbHeight);
}
}
g.DrawImage(images[i], offsetX, offsetY, thumbWidth, thumbHeight);
if (Options.AddTimestamp)
{
int timestampOffset = 10;
using (Font font = new Font("Arial", 12))
{
ImageHelpers.DrawTextWithShadow(g, screenshots[i].Timestamp.ToString(),
new Point(offsetX + timestampOffset, offsetY + timestampOffset), font, Color.White, Color.Black);
}
}
i++;
if (i >= images.Count)
{
return finalImage;
}
offsetX += thumbWidth + Options.Spacing;
}
offsetY += thumbHeight + Options.Spacing;
}
}
return finalImage;
}
catch
{
if (finalImage != null)
{
finalImage.Dispose();
}
throw;
}
finally
{
foreach (Image image in images)
{
if (image != null)
{
image.Dispose();
}
}
}
}
}
}

View file

@ -28,6 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{B1CCDF
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShareX.Setup", "ShareX.Setup\ShareX.Setup.csproj", "{3D19A94A-7A58-4451-A686-EE70B471C206}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShareX.Setup", "ShareX.Setup\ShareX.Setup.csproj", "{3D19A94A-7A58-4451-A686-EE70B471C206}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShareX.MediaLib", "ShareX.MediaLib\ShareX.MediaLib.csproj", "{1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -68,6 +70,10 @@ Global
{D13441B6-96E1-4D1B-8A95-58A7D6CB1E24}.Release|Any CPU.Build.0 = Release|Any CPU {D13441B6-96E1-4D1B-8A95-58A7D6CB1E24}.Release|Any CPU.Build.0 = Release|Any CPU
{3D19A94A-7A58-4451-A686-EE70B471C206}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3D19A94A-7A58-4451-A686-EE70B471C206}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D19A94A-7A58-4451-A686-EE70B471C206}.Release|Any CPU.ActiveCfg = Release|Any CPU {3D19A94A-7A58-4451-A686-EE70B471C206}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A190E53-1419-4CC2-B0E5-3BC7EA861C8B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -51,20 +51,6 @@ public enum SupportedLanguage
Turkish Turkish
} }
public enum EImageFormat
{
[Description("png")]
PNG,
[Description("jpg")]
JPEG,
[Description("gif")]
GIF,
[Description("bmp")]
BMP,
[Description("tif")]
TIFF
}
public enum TaskJob public enum TaskJob
{ {
Job, Job,
@ -75,6 +61,15 @@ public enum TaskJob
ShareURL ShareURL
} }
public enum TaskStatus
{
InQueue,
Preparing,
Working,
Stopping,
Completed
}
[Flags] [Flags]
public enum AfterCaptureTasks // Localized public enum AfterCaptureTasks // Localized
{ {
@ -231,9 +226,4 @@ public enum ImagePreviewVisibility
{ {
Show, Hide, Automatic Show, Hide, Automatic
} }
public enum ColorPickerFormat
{
RGB, Hexadecimal
}
} }