|
1 | | -Public Class Form1 |
| 1 | +Imports System.IO.Pipes |
| 2 | + |
| 3 | +Public Class Form1 |
2 | 4 | Private opusenc_version As String = String.Empty |
3 | 5 | Private ffmpeg_version As String = String.Empty |
4 | 6 | Public Running As Boolean = False |
|
53 | 55 | If Not String.IsNullOrEmpty(OutputFolder) Then |
54 | 56 | outputPath = OutputTxt.Text + "\" + IO.Path.GetFileNameWithoutExtension(Item) + ".opus" |
55 | 57 | Else |
56 | | - outputPath = IO.Path.GetDirectoryName(Item) + "\" + IO.Path.GetFileNameWithoutExtension(Item) + ".opus" |
| 58 | + outputPath = IO.Path.ChangeExtension(Item, ".opus") |
57 | 59 | End If |
58 | 60 | Return outputPath |
59 | 61 | End Function |
|
64 | 66 | Dim FileAlreadyExist As List(Of String) = New List(Of String) |
65 | 67 | Dim ErrorList As List(Of String) = New List(Of String) |
66 | 68 | Dim IgnoreFilesWithExtensions As String = String.Empty |
| 69 | + Dim Item_Type As Integer = 0 |
67 | 70 | If IO.File.Exists("ignore.txt") Then IgnoreFilesWithExtensions = My.Computer.FileSystem.ReadAllText("ignore.txt") |
68 | 71 | If IO.Directory.Exists(InputTxt.Text) Or GoogleDrive Then |
69 | 72 | Dim Items As Object |
70 | 73 | If Not GoogleDrive Then |
| 74 | + Item_Type = 0 |
71 | 75 | Items = IO.Directory.GetFiles(InputTxt.Text) |
72 | 76 | Else |
| 77 | + Item_Type = 1 |
73 | 78 | Items = GDriveItemsToProcess |
74 | | - ItemsToDelete = GDriveItemsToProcess |
75 | 79 | End If |
76 | 80 | For Each File In Items |
77 | | - If (IO.Path.GetExtension(File) = ".wav" Or IO.Path.GetExtension(File) = ".flac" Or IO.Path.GetExtension(File) = ".opus" And EncOpusenc.Checked) Or EncFfmpeg1.Checked Or EncFFmpeg2.Checked Then |
78 | | - ItemsToProcess.Add(File) |
79 | | - ElseIf IO.Path.GetExtension(File) = ".mp3" Or IO.Path.GetExtension(File) = ".m4a" And EncOpusenc.Checked Then |
80 | | - If Not ffmpeg_version = String.Empty Then |
81 | | - ffmpeg_preprocess(File, IO.Path.GetFileNameWithoutExtension(File)) |
82 | | - ItemsToProcess.Add(IO.Path.GetFileNameWithoutExtension(File) + ".flac") |
83 | | - ItemsToDelete.Add(IO.Path.GetFileNameWithoutExtension(File) + ".flac") |
84 | | - Else |
85 | | - ErrorList.Add(File) |
86 | | - End If |
87 | | - Else |
88 | | - If Not String.IsNullOrEmpty(OutputTxt.Text) Then |
89 | | - If Not IO.File.Exists(OutputTxt.Text + "\" + My.Computer.FileSystem.GetName(File)) Then |
90 | | - If Not IgnoreFilesWithExtensions.Contains(IO.Path.GetExtension(File)) Then My.Computer.FileSystem.CopyFile(File, OutputTxt.Text + "\" + My.Computer.FileSystem.GetName(File)) |
| 81 | + If Not String.IsNullOrEmpty(OutputTxt.Text) Then |
| 82 | + If Not IO.File.Exists(OutputTxt.Text + "\" + My.Computer.FileSystem.GetName(File)) Then |
| 83 | + If Not IgnoreFilesWithExtensions.Contains(IO.Path.GetExtension(File)) Then |
| 84 | + ItemsToProcess.Add(File) |
| 85 | + Else |
| 86 | + My.Computer.FileSystem.CopyFile(File, OutputTxt.Text + "\" + My.Computer.FileSystem.GetName(File)) |
91 | 87 | End If |
92 | 88 | End If |
93 | 89 | End If |
|
96 | 92 | ItemsToProcess.Add(InputTxt.Text) |
97 | 93 | End If |
98 | 94 | ProgressBar1.BeginInvoke(Sub() |
99 | | - If Not GoogleDrive Then |
100 | | - ProgressBar1.Maximum = ItemsToProcess.Count |
101 | | - Else |
102 | | - ProgressBar1.Maximum = ItemsToProcess.Count * 2 |
103 | | - End If |
| 95 | + ProgressBar1.Maximum = ItemsToProcess.Count |
104 | 96 | ProgressBar1.Value = 0 |
105 | 97 | End Sub) |
106 | | - If GoogleDrive Then |
107 | | - Dim download_tasks = New List(Of Action) |
108 | | - For Counter As Integer = 0 To GDriveItemIDs.Count - 1 |
109 | | - Dim i As Integer = Counter |
110 | | - download_tasks.Add(Function() Download_Files(GDriveItemsToProcess(i), GDriveItemIDs(i))) |
111 | | - Next |
112 | | - Parallel.Invoke(New ParallelOptions With {.MaxDegreeOfParallelism = My.Settings.MaxDriveDownloads}, download_tasks.ToArray()) |
113 | | - End If |
114 | 98 | Dim tasks = New List(Of Action) |
115 | 99 | If enableMultithreading.Checked Then |
116 | 100 | For Counter As Integer = 0 To ItemsToProcess.Count - 1 |
117 | | - Dim args As Array = {ItemsToProcess(Counter), GetOutputPath(OutputTxt.Text, ItemsToProcess(Counter)), My.Settings.Bitrate} |
| 101 | + Dim args As Array |
| 102 | + If GoogleDrive Then |
| 103 | + args = {GDriveItemIDs(Counter), 1, GetOutputPath(OutputTxt.Text, ItemsToProcess(Counter)), IO.Path.GetExtension(ItemsToProcess(Counter)), My.Settings.Bitrate} |
| 104 | + Else |
| 105 | + args = {ItemsToProcess(Counter), 0, GetOutputPath(OutputTxt.Text, ItemsToProcess(Counter)), IO.Path.GetExtension(ItemsToProcess(Counter)), My.Settings.Bitrate} |
| 106 | + End If |
118 | 107 | If Not IO.File.Exists(args(1)) Then |
119 | 108 | If EncOpusenc.Checked Then |
120 | 109 | tasks.Add(Function() Run_opus(args, "opusenc", "opusenc")) |
|
175 | 164 | End If |
176 | 165 | MsgBox(MessageToShow) |
177 | 166 | End Sub |
178 | | - Private Function Download_Files(Filename As String, Id As String) |
179 | | - Dim fileStream As New IO.FileStream(Filename, IO.FileMode.Create) |
180 | | - GoogleDriveForm.drive.DownloadFile(Id, fileStream) |
181 | | - fileStream.Close() |
182 | | - ProgressBar1.BeginInvoke(Sub() ProgressBar1.PerformStep()) |
183 | | - Return True |
| 167 | + Private Function Download_Files(id As String) As IO.MemoryStream |
| 168 | + Using memoryStream As New IO.MemoryStream |
| 169 | + GoogleDriveForm.drive.DownloadFile(id, memoryStream) |
| 170 | + Return memoryStream |
| 171 | + End Using |
184 | 172 | End Function |
185 | | - Private Function Run_opus(args As Array, encoder As String, encoderExe As String) |
| 173 | + Private Function Run_opus(args As Array, encoder As String, encoderExe As String) As Boolean |
186 | 174 | Dim Input_File As String = args(0) |
187 | | - Dim Output_File As String = args(1) |
188 | | - Dim Bitrate As String = args(2) |
| 175 | + Dim Input_Type As Integer = args(1) |
| 176 | + Dim Output_File As String = args(2) |
| 177 | + Dim FileExtension As String = args(3) |
| 178 | + Dim Bitrate As String = args(4) |
189 | 179 | Dim opusProcessInfo As New ProcessStartInfo |
190 | 180 | Dim opusProcess As Process |
191 | 181 | opusProcessInfo.FileName = encoderExe + ".exe" |
| 182 | + Dim Data As Byte() |
| 183 | + If Input_Type = 0 Then |
| 184 | + Data = IO.File.ReadAllBytes(Input_File) |
| 185 | + Else |
| 186 | + Data = Download_Files(Input_File).ToArray() |
| 187 | + End If |
192 | 188 | Select Case encoder |
193 | 189 | Case "opusenc" |
194 | | - opusProcessInfo.Arguments = "--music --bitrate " & Bitrate & " """ + Input_File + """ """ + Output_File + """" |
| 190 | + If Not (FileExtension = ".wav" Or FileExtension = ".flac" Or FileExtension = ".opus") Then |
| 191 | + If Not ffmpeg_version = String.Empty Then |
| 192 | + Data = ffmpeg_preprocess(Data) |
| 193 | + Else |
| 194 | + Return False |
| 195 | + End If |
| 196 | + End If |
| 197 | + opusProcessInfo.Arguments = "--music --bitrate " & Bitrate & " - """ + Output_File + """" |
195 | 198 | Case "ffmpeg1" |
196 | | - opusProcessInfo.Arguments = "-i """ + Input_File + """ -c:a libopus -application audio -b:a " & Bitrate & "K """ + Output_File + """" |
| 199 | + opusProcessInfo.Arguments = "-i - -c:a libopus -application audio -b:a " & Bitrate & "K -c:v copy """ + Output_File + """" |
197 | 200 | Case "ffmpeg2" |
198 | | - opusProcessInfo.Arguments = "-i """ + Input_File + """ -c:a opus -strict -2 -b:a " & Bitrate & "K """ + Output_File + """" |
| 201 | + opusProcessInfo.Arguments = "-i - -c:a opus -strict -2 -b:a " & Bitrate & "K -c:v copy """ + Output_File + """" |
199 | 202 | End Select |
200 | 203 | opusProcessInfo.WorkingDirectory = IO.Path.GetDirectoryName(Input_File) |
201 | 204 | opusProcessInfo.CreateNoWindow = True |
202 | 205 | opusProcessInfo.RedirectStandardOutput = False |
| 206 | + opusProcessInfo.RedirectStandardInput = True |
203 | 207 | opusProcessInfo.UseShellExecute = False |
204 | 208 | opusProcess = Process.Start(opusProcessInfo) |
| 209 | + Dim ffmpegIn As IO.Stream = opusProcess.StandardInput.BaseStream |
| 210 | + ffmpegIn.Write(Data, 0, Data.Length) |
| 211 | + ffmpegIn.Flush() |
| 212 | + ffmpegIn.Close() |
205 | 213 | opusProcess.WaitForExit() |
206 | 214 | ProgressBar1.BeginInvoke(Sub() ProgressBar1.PerformStep()) |
207 | 215 | Return True |
208 | 216 | End Function |
209 | | - Private Function ffmpeg_preprocess(Input As String, Output As String) |
| 217 | + Private Function ffmpeg_preprocess(Input As Byte()) As Byte() |
| 218 | + Dim InputPipe As New NamedPipeServerStream("ffin", PipeDirection.Out, -1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 16384, 0) |
| 219 | + Dim OutputPipe As New NamedPipeServerStream("ffout.flac", PipeDirection.In, -1, PipeTransmissionMode.Byte, PipeOptions.WriteThrough, 0, 16384) |
210 | 220 | Dim ffmpegProcessInfo As New ProcessStartInfo |
211 | 221 | Dim ffmpegProcess As Process |
212 | 222 | ffmpegProcessInfo.FileName = "ffmpeg.exe" |
213 | | - ffmpegProcessInfo.Arguments = "-i """ + Input + """ -c:a flac """ + Output + ".flac"" -y" |
| 223 | + ffmpegProcessInfo.Arguments = "-i \\.\pipe\ffin -c:a flac -c:v copy \\.\pipe\ffout.flac -y" |
214 | 224 | ffmpegProcessInfo.CreateNoWindow = True |
215 | | - ffmpegProcessInfo.RedirectStandardOutput = False |
| 225 | + ffmpegProcessInfo.RedirectStandardInput = True |
| 226 | + ffmpegProcessInfo.RedirectStandardOutput = True |
216 | 227 | ffmpegProcessInfo.UseShellExecute = False |
217 | 228 | ffmpegProcess = Process.Start(ffmpegProcessInfo) |
| 229 | + WriteByteAsync(InputPipe, Input) |
| 230 | + Dim lastRead As Integer |
| 231 | + OutputPipe.WaitForConnection() |
| 232 | + Dim PipedOutput As Byte() |
| 233 | + Using ms As New IO.MemoryStream |
| 234 | + Dim buffer As Byte() = New Byte(16384) {} |
| 235 | + Do |
| 236 | + lastRead = OutputPipe.Read(buffer, 0, 16384) |
| 237 | + ms.Write(buffer, 0, lastRead) |
| 238 | + Loop While lastRead > 0 |
| 239 | + PipedOutput = ms.ToArray() |
| 240 | + OutputPipe.Close() |
| 241 | + End Using |
218 | 242 | ffmpegProcess.WaitForExit() |
219 | | - Return True |
| 243 | + Return PipedOutput |
220 | 244 | End Function |
| 245 | + Private Async Sub WriteByteAsync(InputPipe As NamedPipeServerStream, Input As Byte()) |
| 246 | + InputPipe.WaitForConnection() |
| 247 | + Dim ChunkSize As Integer = 16384 |
| 248 | + For Bytes As Long = 0 To Input.Length Step 16384 |
| 249 | + If Input.Length - Bytes < ChunkSize Then |
| 250 | + ChunkSize = Input.Length - Bytes |
| 251 | + End If |
| 252 | + Await InputPipe.WriteAsync(Input, Bytes, ChunkSize) |
| 253 | + Next |
221 | 254 |
|
| 255 | + InputPipe.Flush() |
| 256 | + InputPipe.Dispose() |
| 257 | + End Sub |
222 | 258 | Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load |
223 | 259 | BitrateNumberBox.Value = My.Settings.Bitrate |
224 | 260 | enableMultithreading.Checked = My.Settings.Multithreading |
|
0 commit comments