|
| 1 | +using System; |
| 2 | +using System.Drawing; |
| 3 | +using System.Diagnostics; |
| 4 | +using System.IO; |
| 5 | +using System.Text; |
| 6 | +using System.Collections.Generic; |
| 7 | +using NAudio; |
| 8 | +using NAudio.Wave; |
| 9 | + |
| 10 | +namespace CmdPlay |
| 11 | +{ |
| 12 | + class Program |
| 13 | + { |
| 14 | + const string brightnessLevels = " .-+*wGHM#&%"; |
| 15 | + |
| 16 | + static void Main(string[] args) |
| 17 | + { |
| 18 | + string inputFilename; |
| 19 | + if (args.Length == 0) /* Ask user manually if no parameters specified */ |
| 20 | + { |
| 21 | + Console.Write("Input File: "); |
| 22 | + inputFilename = Console.ReadLine().Replace("\"", ""); |
| 23 | + } |
| 24 | + else /* Otherwise use first argument */ |
| 25 | + { |
| 26 | + inputFilename = args[0]; |
| 27 | + } |
| 28 | + |
| 29 | + Console.WriteLine( "------------------------------\n" + |
| 30 | + " Controls \n" + |
| 31 | + " Space - Play / Pause \n" + |
| 32 | + " Esc - Exit \n" + |
| 33 | + "------------------------------\n"); |
| 34 | + ConsoleColor originalForegroundColor = Console.ForegroundColor; /* Preserve the old old colours to print warning message */ |
| 35 | + ConsoleColor originalBackgroundColor = Console.BackgroundColor; |
| 36 | + |
| 37 | + Console.ForegroundColor = ConsoleColor.Red; |
| 38 | + Console.BackgroundColor = ConsoleColor.Black; /* Contrast: Red on black */ |
| 39 | + Console.WriteLine("NOTE: Do not resize the window starting from now! (Resize before program init)"); |
| 40 | + Console.ForegroundColor = originalForegroundColor; /* Reset old colours */ |
| 41 | + Console.BackgroundColor = originalBackgroundColor; |
| 42 | + |
| 43 | + Console.WriteLine("[INFO] Please wait.. Processing.."); |
| 44 | + Console.WriteLine("[INFO] Step 1 / 4: Cleaning up..."); |
| 45 | + |
| 46 | + if(Directory.Exists("tmp")) |
| 47 | + { |
| 48 | + if(Directory.Exists("tmp\\frames\\")) |
| 49 | + { |
| 50 | + Directory.Delete("tmp\\frames\\", true); |
| 51 | + } |
| 52 | + Directory.CreateDirectory("tmp\\frames\\"); |
| 53 | + if(File.Exists("tmp\\audio.wav")) |
| 54 | + { |
| 55 | + File.Delete("tmp\\audio.wav"); |
| 56 | + } |
| 57 | + } |
| 58 | + else |
| 59 | + { |
| 60 | + Directory.CreateDirectory("tmp\\"); |
| 61 | + Directory.CreateDirectory("tmp\\frames\\"); |
| 62 | + } |
| 63 | + |
| 64 | + int targetFrameWidth = Console.WindowWidth - 1; |
| 65 | + int targetFrameHeight = Console.WindowHeight - 2; |
| 66 | + |
| 67 | + Console.WriteLine("[INFO] Step 2 / 4: Extracting frames..."); |
| 68 | + Process ffmpegProcess = new Process(); /* Launch ffmpeg process to extract the frames */ |
| 69 | + ffmpegProcess.StartInfo.FileName = "ffmpeg.exe"; |
| 70 | + ffmpegProcess.StartInfo.Arguments = "-i \"" + inputFilename + "\" -vf scale=" + |
| 71 | + targetFrameWidth + ":" + targetFrameHeight + " tmp\\frames\\%0d.bmp"; |
| 72 | + |
| 73 | + ffmpegProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; |
| 74 | + ffmpegProcess.Start(); |
| 75 | + Console.WriteLine("[INFO] Waiting for ffmpeg.exe to finish..."); |
| 76 | + ffmpegProcess.WaitForExit(); |
| 77 | + |
| 78 | + Console.WriteLine("[INFO] Step 3 / 4: Extracting audio..."); |
| 79 | + ffmpegProcess = new Process(); |
| 80 | + ffmpegProcess.StartInfo.FileName = "ffmpeg.exe"; |
| 81 | + ffmpegProcess.StartInfo.Arguments = "-i \"" + inputFilename + "\" tmp\\audio.wav"; |
| 82 | + ffmpegProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; |
| 83 | + ffmpegProcess.Start(); |
| 84 | + Console.WriteLine("[INFO] Waiting for ffmpeg.exe to finish..."); |
| 85 | + ffmpegProcess.WaitForExit(); |
| 86 | + |
| 87 | + Console.WriteLine("[INFO] Step 4 / 4: Converting to ascii... (This can take some time!)"); |
| 88 | + Console.Write("-> [PROGRESS] [0 %] [ ]"); |
| 89 | + int currentCursorHeight = Console.CursorTop; |
| 90 | + List<string> frames = new List<string>(); |
| 91 | + |
| 92 | + int frameCount = Directory.GetFiles("tmp\\frames", "*.bmp").Length; |
| 93 | + int frameIndex = 1; |
| 94 | + while(true) |
| 95 | + { |
| 96 | + string filename = "tmp\\frames\\" + frameIndex.ToString() + ".bmp"; |
| 97 | + if(!File.Exists(filename)) |
| 98 | + { |
| 99 | + break; |
| 100 | + } |
| 101 | + StringBuilder frameBuilder = new StringBuilder(); |
| 102 | + using (Bitmap b = new Bitmap(filename)) |
| 103 | + { |
| 104 | + for(int y = 0; y < b.Height; y++) |
| 105 | + { |
| 106 | + for(int x = 0; x < b.Width; x++) |
| 107 | + { |
| 108 | + int dIndex = (int)(b.GetPixel(x, y).GetBrightness() * brightnessLevels.Length); |
| 109 | + if(dIndex < 0) |
| 110 | + { |
| 111 | + dIndex = 0; |
| 112 | + } |
| 113 | + else if(dIndex >= brightnessLevels.Length) |
| 114 | + { |
| 115 | + dIndex = brightnessLevels.Length - 1; |
| 116 | + } |
| 117 | + frameBuilder.Append(brightnessLevels[dIndex]); |
| 118 | + } |
| 119 | + frameBuilder.Append("\n"); |
| 120 | + } |
| 121 | + } |
| 122 | + frames.Add(frameBuilder.ToString()); |
| 123 | + frameIndex++; |
| 124 | + |
| 125 | + int percentage = (int)(frameIndex / (float)frameCount * 100); |
| 126 | + Console.SetCursorPosition(15, currentCursorHeight); |
| 127 | + Console.Write(percentage.ToString()); |
| 128 | + Console.SetCursorPosition(22, currentCursorHeight); |
| 129 | + for(int i = 0; i < percentage / 5; i++) |
| 130 | + { |
| 131 | + Console.Write("#"); |
| 132 | + } |
| 133 | + } |
| 134 | + |
| 135 | + AudioFileReader reader = new AudioFileReader("tmp\\audio.wav"); |
| 136 | + WaveOutEvent woe = new WaveOutEvent(); |
| 137 | + woe.Init(reader); |
| 138 | + Console.WriteLine("\n\nPress return to play!"); |
| 139 | + Console.ReadLine(); |
| 140 | + woe.Play(); |
| 141 | + |
| 142 | + while(true) |
| 143 | + { |
| 144 | + float percentage = woe.GetPosition() / (float)reader.Length; |
| 145 | + int frame = (int)(percentage * frameCount); |
| 146 | + if(frame >= frames.Count) |
| 147 | + break; |
| 148 | + |
| 149 | + Console.SetCursorPosition(0, 0); |
| 150 | + Console.WriteLine(frames[frame]); |
| 151 | + |
| 152 | + if(Console.KeyAvailable) |
| 153 | + { |
| 154 | + ConsoleKey pressed = Console.ReadKey().Key; |
| 155 | + switch(pressed) |
| 156 | + { |
| 157 | + case ConsoleKey.Spacebar: |
| 158 | + { |
| 159 | + if (woe.PlaybackState == PlaybackState.Playing) |
| 160 | + woe.Pause(); |
| 161 | + else woe.Play(); |
| 162 | + |
| 163 | + break; |
| 164 | + } |
| 165 | + case ConsoleKey.Escape: |
| 166 | + { |
| 167 | + Console.WriteLine("Done. Press any key to close"); |
| 168 | + Console.ReadKey(); |
| 169 | + |
| 170 | + return; |
| 171 | + } |
| 172 | + } |
| 173 | + } |
| 174 | + } |
| 175 | + Console.WriteLine("Done. Press any key to close"); |
| 176 | + Console.ReadKey(); |
| 177 | + } |
| 178 | + } |
| 179 | +} |
0 commit comments