ShareX.MediaLib interim commit 2

This commit is contained in:
Jaex 2015-08-04 12:39:27 +03:00
parent d8635a571a
commit 4b41b75404
4 changed files with 152 additions and 22 deletions

View file

@ -0,0 +1,78 @@
#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.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ShareX.MediaLib
{
public class FFmpegCLIManager : ExternalCLIManager
{
public string FFmpegPath { get; private set; }
public StringBuilder Output { get; private set; }
public FFmpegCLIManager(string ffmpegPath)
{
FFmpegPath = ffmpegPath;
Output = new StringBuilder();
OutputDataReceived += FFmpeg_DataReceived;
ErrorDataReceived += FFmpeg_DataReceived;
Helpers.CreateDirectoryIfNotExist(FFmpegPath);
}
private void FFmpeg_DataReceived(object sender, DataReceivedEventArgs e)
{
lock (this)
{
if (!string.IsNullOrEmpty(e.Data))
{
Output.AppendLine(e.Data);
}
}
}
public VideoInfo GetVideoInfo(string videoPath)
{
Open(FFmpegPath, "-i " + videoPath);
string output = Output.ToString();
Match match = Regex.Match(output, @"Duration: (?<Duration>\d{2}:\d{2}:\d{2}\.\d{2}),.+?start: (?<Start>\d+\.\d+),.+?bitrate: (?<Bitrate>\d+) kb/s", RegexOptions.CultureInvariant);
if (match.Success)
{
VideoInfo videoInfo = new VideoInfo();
videoInfo.FilePath = videoPath;
videoInfo.Duration = TimeSpan.Parse(match.Groups["Duration"].Value);
return videoInfo;
}
return null;
}
}
}

View file

@ -43,7 +43,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Enums.cs" />
<Compile Include="FFmpegCLIManager.cs" />
<Compile Include="ScreenshotInfo.cs" />
<Compile Include="VideoInfo.cs" />
<Compile Include="VideoThumbnailer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VideoThumbnailOptions.cs" />

View file

@ -0,0 +1,44 @@
#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
{
public class VideoInfo
{
public string FilePath { get; set; }
public TimeSpan Duration { get; set; }
public override string ToString()
{
return string.Format("Filename: {0}, Duration {1}", Path.GetFileName(FilePath), Duration);
}
}
}

View file

@ -40,23 +40,29 @@ public class VideoThumbnailer
public string MediaPath { get; private set; }
public string FFmpegPath { get; private set; }
public VideoThumbnailOptions Options { get; private set; }
public VideoInfo VideoInfo { 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>();
private List<ScreenshotInfo> tempScreenshots = new List<ScreenshotInfo>();
private List<ScreenshotInfo> screenshots = new List<ScreenshotInfo>();
private int timeSlice;
private List<int> mediaSeekTimes = new List<int>();
public VideoThumbnailer(string mediaPath, string ffmpegPath, VideoThumbnailOptions options)
{
MediaPath = mediaPath;
FFmpegPath = ffmpegPath;
Options = options;
TimeSlice = GetTimeSlice(Options.ScreenshotCount);
using (FFmpegCLIManager ffmpegCLI = new FFmpegCLIManager(FFmpegPath))
{
VideoInfo = ffmpegCLI.GetVideoInfo(MediaPath);
}
timeSlice = GetTimeSlice(Options.ScreenshotCount);
for (int i = 1; i < Options.ScreenshotCount + 2; i++)
{
MediaSeekTimes.Add(GetTimeSlice(Options.ScreenshotCount, 2) * i);
mediaSeekTimes.Add(GetTimeSlice(Options.ScreenshotCount + 2) * i);
}
}
@ -69,7 +75,7 @@ public virtual void TakeScreenshots()
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);
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);
@ -82,7 +88,6 @@ public virtual void TakeScreenshots()
p.StartInfo = psi;
p.Start();
p.WaitForExit(1000 * 30);
p.Close();
}
if (File.Exists(tempScreenshotPath))
@ -93,7 +98,7 @@ public virtual void TakeScreenshots()
Timestamp = TimeSpan.FromSeconds(timeSliceElapsed)
};
TempScreenshots.Add(screenshotInfo);
tempScreenshots.Add(screenshotInfo);
}
}
@ -102,12 +107,12 @@ public virtual void TakeScreenshots()
protected virtual void Finish()
{
if (TempScreenshots != null && TempScreenshots.Count > 0)
if (tempScreenshots != null && tempScreenshots.Count > 0)
{
if (Options.CombineScreenshots)
{
string temp_fp = "";
using (Image img = CombineScreenshots(TempScreenshots))
using (Image img = CombineScreenshots(tempScreenshots))
{
temp_fp = Path.Combine(Options.OutputDirectory, Path.GetFileNameWithoutExtension(MediaPath) + "_s." + Options.FFmpegThumbnailExtension);
@ -121,27 +126,27 @@ protected virtual void Finish()
break;
}
Screenshots.Add(new ScreenshotInfo(temp_fp) { Args = TempScreenshots[0].Args });
screenshots.Add(new ScreenshotInfo(temp_fp) { Args = tempScreenshots[0].Args });
}
TempScreenshots.ForEach(x => File.Delete(x.LocalPath));
tempScreenshots.ForEach(x => File.Delete(x.LocalPath));
}
else
{
Screenshots.AddRange(TempScreenshots);
screenshots.AddRange(tempScreenshots);
}
}
}
protected int GetTimeSlice(int count)
{
return (int)(VideoInfo.Duration.TotalSeconds / (count * 1000));
}
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));
return (int)(random.NextDouble() * (mediaSeekTimes[start + 1] - mediaSeekTimes[start]) + mediaSeekTimes[start]);
}
private Image CombineScreenshots(List<ScreenshotInfo> screenshots)
@ -156,7 +161,8 @@ private Image CombineScreenshots(List<ScreenshotInfo> screenshots)
if (Options.AddMovieInfo)
{
//infoString = MediaFile.GetMTNString();
infoString = VideoInfo.ToString();
using (Font font = new Font("Arial", 14))
{
infoStringHeight = Helpers.MeasureText(infoString, font).Height;