Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Json;
- using System.Linq;
- using System.Net;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading;
- namespace DictorWatch {
- internal static class Program {
- private static readonly string[] RequiredPrograms = {"youtube-dl.exe", "ffmpeg.exe", "ffprobe.exe"};
- private static readonly string[] FunnyTracksIGuess = {
- "https://www.youtube.com/watch?v=tw7HHUItwAg",
- "https://www.youtube.com/watch?v=pqQq4hla0xo"
- };
- static void Main(string[] args) {
- if (RequiredPrograms.Any(p => !IsItInstalled(p))) {
- Console.WriteLine("ERR: {0} is not installed!",
- string.Join(", ", RequiredPrograms.Where(p => !IsItInstalled(p))));
- return;
- }
- var filename = RandomString();
- Console.Write("Enter YouTube URL: ");
- var ytUrl = Console.ReadLine();
- if (ytUrl == null) {
- Console.WriteLine("ERR: Provide an Youtube URL!");
- return;
- }
- Log("Downloading the source video...");
- var videoName = DownloadYouTubeVideo(ytUrl, filename);
- DoSomeFfmpeg(filename, videoName);
- }
- private static string DownloadYouTubeVideo(string url, string outputFile) {
- var proc = Process.Start(new ProcessStartInfo {
- FileName = "youtube-dl.exe",
- Arguments = $"{url} -o {outputFile}",
- WorkingDirectory = Directory.GetCurrentDirectory(),
- RedirectStandardOutput = true,
- RedirectStandardError = true
- });
- var result = proc.StandardOutput.ReadToEnd();
- return new Regex("Merging formats into \"(.*\\..*)\"").Match(result).Groups[1].Value;
- }
- private static void DoSomeFfmpeg(string filename, string source) {
- var proc = Process.Start(new ProcessStartInfo {
- FileName = "ffprobe.exe",
- Arguments = source,
- WorkingDirectory = Directory.GetCurrentDirectory(),
- RedirectStandardError = true
- });
- if (proc == null) throw new Exception("Something happened with ffprobe!");
- var output = proc.StandardError.ReadToEnd();
- var regex = new Regex(@"DURATION.+(\d\d:\d\d:\d\d.\d{9})");
- var match = regex.Match(output);
- var duration = TimeSpan.Parse(match.Groups[1].Value[..match.Groups[1].Value.IndexOf('.')]);
- var framerate = int.Parse(new Regex(@"(\d*) fps").Match(output).Groups[1].Value);
- Log("Getting frames...");
- proc = Process.Start(new ProcessStartInfo {
- FileName = "ffmpeg.exe",
- Arguments = $"-i \"{source}\" -ss {new Random().Next((int) duration.TotalSeconds - 60)} -t 15 -r {framerate / 12} {filename}_%03d.png",
- WorkingDirectory = Directory.GetCurrentDirectory()
- });
- proc.WaitForExit();
- var filesToDelete = new List<string>();
- var files = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), $"{filename}_*.png").ToList();
- Log("Processing images through Face API. This might take a while...");
- for (var i = 0; i < files.Count; i++) {
- Console.WriteLine("Processing {0} of {1}...", i + 1, files.Count);
- var path = files[i];
- var facePos = GetFacePositions(path).ToList();
- if (facePos.Count == 0) {
- filesToDelete.Add(path);
- Thread.Sleep(4000);
- continue;
- }
- Bitmap cropped;
- using (var bmp = new Bitmap(path)) cropped = bmp.Clone(facePos[0], PixelFormat.Format24bppRgb);
- cropped.Save(path);
- Thread.Sleep(4000);
- }
- foreach (var file in filesToDelete) File.Delete(file);
- Log("Downloading funny audio...");
- // download audio
- var audioFromYT = DownloadYouTubeVideo(FunnyTracksIGuess[new Random().Next(FunnyTracksIGuess.Length)], $"{filename}.audio");
- proc = Process.Start(new ProcessStartInfo {
- FileName = "ffmpeg.exe",
- Arguments = $"-i \"{audioFromYT}\" {filename}.mp3",
- WorkingDirectory = Directory.GetCurrentDirectory()
- });
- proc.WaitForExit();
- Log("Generating gif...");
- // generate gif (or yi-ff, whatever)
- proc = Process.Start(new ProcessStartInfo {
- FileName = "ffmpeg.exe",
- Arguments = $"-i {filename}_%03d.png -pix_fmt rgb24 {filename}.gif",
- WorkingDirectory = Directory.GetCurrentDirectory()
- });
- proc.WaitForExit();
- Log("Generating the result...");
- // generate result
- proc = Process.Start(new ProcessStartInfo {
- FileName = "ffmpeg.exe",
- Arguments = $"-stream_loop -1 -i {filename}.gif -i {filename}.mp3 -shortest {filename}.mp4",
- WorkingDirectory = Directory.GetCurrentDirectory()
- });
- proc.WaitForExit();
- Log("Cleaning after ourselves...");
- foreach (var path in Directory.GetFiles(Directory.GetCurrentDirectory(), $"{filename}*"))
- if (!path.EndsWith($"{filename}.mp4")) File.Delete(path);
- }
- private static void Log(string log) {
- var oldColor = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.DarkGreen;
- Console.WriteLine(log);
- Console.ForegroundColor = oldColor;
- }
- private static string RandomString() {
- var bytes = new byte[16];
- new Random().NextBytes(bytes);
- return bytes.Aggregate("", (s, b) => $"{s}{b:x2}");
- }
- private static bool IsItInstalled(string program) {
- try {
- Process.Start(new ProcessStartInfo {
- FileName = program,
- RedirectStandardOutput = true,
- RedirectStandardError = true
- });
- return true;
- } catch { return false; }
- }
- static IEnumerable<Rectangle> GetFacePositions(string path) {
- var req = WebRequest.Create("https://westeurope.api.cognitive.microsoft.com/face/v1.0/detect");
- req.Method = "POST";
- req.ContentType = "application/octet-stream";
- req.Headers["Ocp-Apim-Subscription-Key"] = "some_key";
- using (var stream = req.GetRequestStream())
- using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
- fs.CopyTo(stream);
- var res = req.GetResponse();
- var resStream = res.GetResponseStream();
- if (resStream == null) yield break;
- using (var sr = new StreamReader(resStream, Encoding.UTF8)) {
- if (JsonValue.Parse(sr.ReadToEnd()) is not JsonArray json) yield break;
- foreach (var face in json.OfType<JsonObject>()) {
- if (face["faceRectangle"] is not JsonObject faceRectangle) continue;
- yield return new Rectangle(faceRectangle["left"], faceRectangle["top"], faceRectangle["width"],
- faceRectangle["height"]);
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement