Advertisement
VladislavSavvateev

Untitled

May 27th, 2021
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.62 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.Drawing.Imaging;
  6. using System.IO;
  7. using System.Json;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Text;
  11. using System.Text.RegularExpressions;
  12. using System.Threading;
  13.  
  14. namespace DictorWatch {
  15. internal static class Program {
  16. private static readonly string[] RequiredPrograms = {"youtube-dl.exe", "ffmpeg.exe", "ffprobe.exe"};
  17.  
  18. private static readonly string[] FunnyTracksIGuess = {
  19. "https://www.youtube.com/watch?v=tw7HHUItwAg",
  20. "https://www.youtube.com/watch?v=pqQq4hla0xo"
  21. };
  22.  
  23. static void Main(string[] args) {
  24. if (RequiredPrograms.Any(p => !IsItInstalled(p))) {
  25. Console.WriteLine("ERR: {0} is not installed!",
  26. string.Join(", ", RequiredPrograms.Where(p => !IsItInstalled(p))));
  27. return;
  28. }
  29.  
  30. var filename = RandomString();
  31.  
  32. Console.Write("Enter YouTube URL: ");
  33. var ytUrl = Console.ReadLine();
  34. if (ytUrl == null) {
  35. Console.WriteLine("ERR: Provide an Youtube URL!");
  36. return;
  37. }
  38.  
  39. Log("Downloading the source video...");
  40. DownloadYouTubeVideo(ytUrl, filename);
  41. DoSomeFfmpeg(filename);
  42. }
  43.  
  44. private static void DownloadYouTubeVideo(string url, string outputFile) {
  45. var proc = Process.Start(new ProcessStartInfo {
  46. FileName = "youtube-dl.exe",
  47. Arguments = $"{url} -o {outputFile}",
  48. WorkingDirectory = Directory.GetCurrentDirectory(),
  49. RedirectStandardError = true
  50. });
  51. proc.WaitForExit();
  52. }
  53.  
  54. private static void DoSomeFfmpeg(string filename) {
  55. var proc = Process.Start(new ProcessStartInfo {
  56. FileName = "ffprobe.exe",
  57. Arguments = @"D:\temp.mkv",
  58. RedirectStandardError = true
  59. });
  60. if (proc == null) throw new Exception("Something happened with ffprobe!");
  61.  
  62. var output = proc.StandardError.ReadToEnd();
  63. var regex = new Regex(@"DURATION.+(\d\d:\d\d:\d\d.\d{9})");
  64. var match = regex.Match(output);
  65. var duration = TimeSpan.Parse(match.Groups[1].Value[..match.Groups[1].Value.IndexOf('.')]);
  66. var framerate = int.Parse(new Regex(@"(\d*) fps").Match(output).Groups[1].Value);
  67.  
  68. Log("Getting frames...");
  69.  
  70. proc = Process.Start(new ProcessStartInfo {
  71. FileName = "ffmpeg.exe",
  72. Arguments = $"-i \"D:\\temp.mkv\" -ss {new Random().Next((int) duration.TotalSeconds - 60)} -t 60 -r {framerate / 24} {filename}_%03d.png",
  73. WorkingDirectory = Directory.GetCurrentDirectory()
  74. });
  75. proc.WaitForExit();
  76.  
  77. var filesToDelete = new List<string>();
  78.  
  79. var files = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), $"{filename}_*.png").ToList();
  80.  
  81. Log("Processing images through Face API. This might take a while...");
  82.  
  83. for (var i = 0; i < files.Count; i++) {
  84. Console.WriteLine("Processing {0} of {1}...", i + 1, files.Count);
  85.  
  86. var path = files[i];
  87.  
  88. var facePos = GetFacePositions(path).ToList();
  89. if (facePos.Count == 0) {
  90. filesToDelete.Add(path);
  91. Thread.Sleep(4000);
  92. continue;
  93. }
  94.  
  95. Bitmap cropped;
  96.  
  97. using (var bmp = new Bitmap(path)) cropped = bmp.Clone(facePos[0], PixelFormat.Format24bppRgb);
  98.  
  99. cropped.Save(path);
  100.  
  101. Thread.Sleep(4000);
  102. }
  103.  
  104. foreach (var file in filesToDelete) File.Delete(file);
  105.  
  106. Log("Downloading funny audio...");
  107.  
  108. // download audio
  109. DownloadYouTubeVideo(FunnyTracksIGuess[new Random().Next(FunnyTracksIGuess.Length)], $"{filename}.audio");
  110. proc = Process.Start(new ProcessStartInfo {
  111. FileName = "ffmpeg.exe",
  112. Arguments = $"-i \"{filename}.audio.mkv\" {filename}.mp3",
  113. WorkingDirectory = Directory.GetCurrentDirectory()
  114. });
  115. proc.WaitForExit();
  116.  
  117. Log("Generating gif...");
  118.  
  119. // generate gif (or yi-ff, whatever)
  120. proc = Process.Start(new ProcessStartInfo {
  121. FileName = "ffmpeg.exe",
  122. Arguments = $"-i {filename}_%03d.png -pix_fmt rgb24 {filename}.gif",
  123. WorkingDirectory = Directory.GetCurrentDirectory()
  124. });
  125. proc.WaitForExit();
  126.  
  127. Log("Generating the result...");
  128.  
  129. // generate result
  130. proc = Process.Start(new ProcessStartInfo {
  131. FileName = "ffmpeg.exe",
  132. Arguments = $"-stream_loop -1 -i {filename}.gif -i {filename}.mp3 -shortest {filename}.mp4",
  133. WorkingDirectory = Directory.GetCurrentDirectory()
  134. });
  135. proc.WaitForExit();
  136.  
  137. Log("Cleaning after ourselves...");
  138.  
  139. foreach (var path in Directory.GetFiles(Directory.GetCurrentDirectory(), $"{filename}*"))
  140. if (!path.EndsWith($"{filename}.mp4")) File.Delete(path);
  141. }
  142.  
  143. private static void Log(string log) {
  144. var oldColor = Console.ForegroundColor;
  145. Console.ForegroundColor = ConsoleColor.DarkGreen;
  146. Console.WriteLine(log);
  147. Console.ForegroundColor = oldColor;
  148. }
  149.  
  150. private static string RandomString() {
  151. var bytes = new byte[16];
  152. new Random().NextBytes(bytes);
  153. return bytes.Aggregate("", (s, b) => $"{s}{b:x2}");
  154. }
  155.  
  156. private static bool IsItInstalled(string program) {
  157. try {
  158. Process.Start(new ProcessStartInfo {
  159. FileName = program,
  160. RedirectStandardOutput = true,
  161. RedirectStandardError = true
  162. });
  163. return true;
  164. } catch { return false; }
  165. }
  166.  
  167. static IEnumerable<Rectangle> GetFacePositions(string path) {
  168. var req = WebRequest.Create("https://westeurope.api.cognitive.microsoft.com/face/v1.0/detect");
  169. req.Method = "POST";
  170. req.ContentType = "application/octet-stream";
  171. req.Headers["Ocp-Apim-Subscription-Key"] = "test";
  172.  
  173. using (var stream = req.GetRequestStream())
  174. using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
  175. fs.CopyTo(stream);
  176.  
  177. var res = req.GetResponse();
  178.  
  179. var resStream = res.GetResponseStream();
  180. if (resStream == null) yield break;
  181.  
  182. using (var sr = new StreamReader(resStream, Encoding.UTF8)) {
  183. if (JsonValue.Parse(sr.ReadToEnd()) is not JsonArray json) yield break;
  184. foreach (var face in json.OfType<JsonObject>()) {
  185. if (face["faceRectangle"] is not JsonObject faceRectangle) continue;
  186.  
  187. yield return new Rectangle(faceRectangle["left"], faceRectangle["top"], faceRectangle["width"],
  188. faceRectangle["height"]);
  189. }
  190. }
  191. }
  192. }
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement