-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
563 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.30907.101 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoCompresser", "VideoCompresser\VideoCompresser.csproj", "{7A51C92D-7338-4C35-9470-DF2C0E3E8B69}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{7A51C92D-7338-4C35-9470-DF2C0E3E8B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{7A51C92D-7338-4C35-9470-DF2C0E3E8B69}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{7A51C92D-7338-4C35-9470-DF2C0E3E8B69}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{7A51C92D-7338-4C35-9470-DF2C0E3E8B69}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {6FB7EC85-8392-48BE-8750-0ABBB6F88920} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace VideoCompresser | ||
{ | ||
public struct ConsoleCommand | ||
{ | ||
public ConsoleCommand(string command, string args) | ||
{ | ||
Command = command; | ||
Args = args; | ||
} | ||
|
||
public string Command { get; set; } | ||
public string Args { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using static ConsoleUtilitiesLite.ConsoleUtilitiesLite; | ||
|
||
namespace VideoCompresser | ||
{ | ||
class Program | ||
{ | ||
static readonly string[] Title = new string[] | ||
{ | ||
"░█──░█ ─▀─ █▀▀▄ █▀▀ █▀▀█ ░█▀▀█ █▀▀█ █▀▄▀█ █▀▀█ █▀▀█ █▀▀ █▀▀ █▀▀ █▀▀ █▀▀█ ", | ||
"─░█░█─ ▀█▀ █──█ █▀▀ █──█ ░█─── █──█ █─▀─█ █──█ █▄▄▀ █▀▀ ▀▀█ ▀▀█ █▀▀ █▄▄▀ ", | ||
"──▀▄▀─ ▀▀▀ ▀▀▀─ ▀▀▀ ▀▀▀▀ ░█▄▄█ ▀▀▀▀ ▀───▀ █▀▀▀ ▀─▀▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀─▀▀" | ||
}; | ||
|
||
public static readonly string FFMPEG_PATH = Path.Combine(AppContext.BaseDirectory, @"ffmpeg 4.4\ffmpeg.exe"); | ||
public static readonly string FFPLAY_PATH = Path.Combine(AppContext.BaseDirectory, @"ffmpeg 4.4\ffplay.exe"); | ||
public static readonly string FFPROBE_PATH = Path.Combine(AppContext.BaseDirectory, @"ffmpeg 4.4\ffprobe.exe"); | ||
|
||
static void Main(string[] args) | ||
{ | ||
Console.OutputEncoding = System.Text.Encoding.Unicode; | ||
Console.Clear(); | ||
|
||
//Console.WriteLine(FFMPEG_PATH); | ||
//Console.WriteLine(); | ||
//Console.WriteLine(FFPLAY_PATH); | ||
//Console.WriteLine(); | ||
//Console.WriteLine(FFPROBE_PATH); | ||
//Console.WriteLine(); | ||
|
||
Console.Title = "Video Compresser"; | ||
ShowTitle(Title); | ||
ShowVersion(System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); | ||
|
||
string path; | ||
while (true) | ||
{ | ||
Console.Write("Please insert a path: "); | ||
path = Console.ReadLine().Trim(); | ||
if (Directory.Exists(path)) | ||
break; | ||
LogErrorMessage("Please write a valid path!"); | ||
} | ||
|
||
Console.Write("Do you want to delete the file after compressing? (y/n): "); | ||
bool deleteFiles = Console.ReadLine().Trim().ToLower().Equals("y"); | ||
if (deleteFiles) | ||
LogWarningMessage("Files will be deleted after compressing."); | ||
else | ||
LogWarningMessage("Files will not be deleted after compressing."); | ||
|
||
int maxNumberOfVideos = 5; | ||
while (true) | ||
{ | ||
Console.Write("How many videos at a time can be converted? (more may slow the computer, default is 5): "); | ||
string answer = Console.ReadLine().Trim(); | ||
if (string.IsNullOrEmpty(answer)) | ||
break; | ||
if (int.TryParse(answer, out maxNumberOfVideos)) | ||
break; | ||
LogErrorMessage("Please write a valid number!"); | ||
} | ||
LogWarningMessage("{0} videos will be converted at the same time.", maxNumberOfVideos); | ||
|
||
//TODO Make compress videos recursively | ||
SubDivision(); | ||
new VideoCompresser(maxNumberOfVideos).CompressAllVideos(path, deleteFiles); | ||
} | ||
|
||
#region Static Methods | ||
internal static Task<string> ExecuteCommandAsync(ConsoleCommand command) | ||
{ | ||
try | ||
{ | ||
TaskCompletionSource<string> taskSource = new TaskCompletionSource<string>(); | ||
ProcessStartInfo procStartInfo = | ||
new ProcessStartInfo(command.Command, command.Args) | ||
{ | ||
RedirectStandardOutput = true, | ||
RedirectStandardInput = true, | ||
UseShellExecute = false, | ||
CreateNoWindow = false, | ||
WindowStyle = ProcessWindowStyle.Hidden, | ||
}; | ||
|
||
Process process = new Process() { StartInfo = procStartInfo, EnableRaisingEvents = true }; | ||
process.Exited += (sender, args) => | ||
{ | ||
taskSource.SetResult(process.StandardOutput.ReadToEnd()); | ||
process.Dispose(); | ||
}; | ||
|
||
process.Start(); | ||
return taskSource.Task; | ||
} | ||
catch (Exception) { throw; } | ||
} | ||
internal static string ExecuteCommandSync(ConsoleCommand command) | ||
{ | ||
try | ||
{ | ||
ProcessStartInfo procStartInfo = | ||
new ProcessStartInfo(command.Command, command.Args) | ||
{ | ||
RedirectStandardOutput = true, | ||
RedirectStandardInput = true, | ||
UseShellExecute = false, | ||
CreateNoWindow = false, | ||
WindowStyle = ProcessWindowStyle.Hidden, | ||
}; | ||
|
||
using Process process = new Process() { StartInfo = procStartInfo }; | ||
process.Start(); | ||
process.WaitForExit(); | ||
|
||
string result = process.StandardOutput.ReadToEnd(); | ||
return result; | ||
} | ||
catch (Exception) { throw; } | ||
} | ||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
|
||
namespace VideoCompresser | ||
{ | ||
public class StopWatch | ||
{ | ||
DateTime _startTime; | ||
DateTime _endTime; | ||
|
||
public void StartRecording() => _startTime = DateTime.Now; | ||
public void StopRecording() => _endTime = DateTime.Now; | ||
public TimeSpan GetTimeSpan() => _endTime - _startTime; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using System; | ||
|
||
namespace VideoCompresser | ||
{ | ||
public struct Video | ||
{ | ||
public static VideoFactory Factory = new VideoFactory(); | ||
|
||
public Video(string path, long numberOfFrames, double durationInSeconds, double frameRate) | ||
{ | ||
Path = path ?? throw new ArgumentNullException(nameof(path)); | ||
NumberOfFrames = numberOfFrames; | ||
DurationInSeconds = durationInSeconds; | ||
FrameRate = frameRate; | ||
} | ||
|
||
public string Path { get; } | ||
public long NumberOfFrames { get; } | ||
public double DurationInSeconds { get; } | ||
public double FrameRate { get; } | ||
public override string ToString() => $"{System.IO.Path.GetFileName(Path)}: {NumberOfFrames}"; | ||
} | ||
|
||
public class VideoFactory | ||
{ | ||
public Video Create(string videoPath) | ||
{ | ||
try | ||
{ | ||
double durationInSeconds = GetVideoDuration(videoPath).TotalSeconds; | ||
double frameRate = GetFrameRate(videoPath); | ||
long numberOfFrames = (long)Math.Round(durationInSeconds * frameRate, 0); | ||
|
||
return new Video(videoPath, numberOfFrames, durationInSeconds, frameRate); | ||
} | ||
catch (Exception) { return new Video(); } | ||
} | ||
static TimeSpan GetVideoDuration(string videoPath) | ||
{ | ||
ConsoleCommand command = new ConsoleCommand() | ||
{ | ||
Command = Program.FFPROBE_PATH, | ||
Args = $"-v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -sexagesimal \"{videoPath}\"" | ||
}; | ||
string result = Program.ExecuteCommandSync(command); | ||
return TimeSpan.Parse(result); | ||
} | ||
static double GetFrameRate(string videoPath) | ||
{ | ||
ConsoleCommand command = new ConsoleCommand() | ||
{ | ||
Command = Program.FFPROBE_PATH, | ||
Args = $"-v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 \"{videoPath}\"" | ||
}; | ||
string result = Program.ExecuteCommandSync(command); | ||
return ConvertFractionToDecimal(result.Trim()); | ||
} | ||
static double ConvertFractionToDecimal(string v) | ||
{ | ||
string[] numbers = v.Split('/'); | ||
int number1 = int.Parse(numbers[0]); | ||
int number2 = int.Parse(numbers[1]); | ||
return number1 / (number2 == 0 ? 1 : number2); | ||
} | ||
} | ||
} |
Oops, something went wrong.