עצירת תהליך שמופעל באירוע לחיצה
-
@dovid כתב בעצירת תהליך שמופעל באירוע לחיצה:
כי בדקתי אצלי וקיבלתי שגיאה אחרת לחלוטין, של מופע ריק.
System.IO.IOException: אין אפשרות לתהליך לגשת לקובץ 'C:\Users\abaye\source\repos\AA\AA\bin\Debug\text_test.wav' כיוון שתהליך אחר משתמש בקובץ. ב- System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) ב- System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) ב- System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access) ב- tts_by_Google.Form1.TextToSpeech(String text) ב- C:\Users\abaye\source\repos\`AA\`AA\Form1.vb:שורה 131 ב- tts_by_Google.Form1.Button1_Click(Object sender, EventArgs e) ב- C:\Users\abaye\source\repos\AA\`AA\Form1.vb:שורה 177 ב- System.Windows.Forms.Control.OnClick(EventArgs e) ב- System.Windows.Forms.Button.OnClick(EventArgs e) ב- System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) ב- System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) ב- System.Windows.Forms.Control.WndProc(Message& m) ב- System.Windows.Forms.ButtonBase.WndProc(Message& m) ב- System.Windows.Forms.Button.WndProc(Message& m) ב- System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) ב- System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) ב- System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
-
Dim request As HttpWebRequest = DirectCast(WebRequest.Create($"https://aaa"), HttpWebRequest) request.Method = "POST" request.ContentType = "application/json" Using streamWriter As StreamWriter = New StreamWriter(request.GetRequestStream()) Dim jsonPayload As String = JsonSerializer.Serialize(payload) streamWriter.Write(jsonPayload) streamWriter.Flush() End Using Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse) Using streamReader As StreamReader = New StreamReader(response.GetResponseStream()) Dim jsonResponse As String = streamReader.ReadToEnd() Dim json_data As JsonElement = JsonSerializer.Deserialize(Of JsonElement)(jsonResponse) Dim audio_content As String = json_data.GetProperty("audioContent").ToString() If Not String.IsNullOrEmpty(audio_content) Then Dim file_name As String = "test" Dim audio_file_path As String = Path.Combine(t_dir, $"{file_name}.wav") Dim audio_blob As Byte() = Convert.FromBase64String(audio_content) Using audio_file As FileStream = New FileStream(audio_file_path, FileMode.Create, FileAccess.Write) audio_file.Write(audio_blob, 0, audio_blob.Length) End Using PlayAudioFile(audio_file_path)
-
@אביי אם הבעיה ש-NAudio נועל את הקובץ גם אחרי ההשמעה (לא יודע למה) אז זמנית יש לי ב' פתרונות חלופיים:
א. לכתוב כל פעם לקובץ חדש (לא לדרוס את הישן) ובסיום התוכנית למחוק הכל.
ב. אם אתה צריך להשמיע קובץ שיורד מהרשת אז לא חייב לשמור לקובץ, אפשר להשמיע ישירות עםRawSourceWaveStream
. -
נו @אביי, אתה מנסה לכתוב על הקובץ הרבה לפני שאתה עוצר את ההשמעה!
היית צריך לשים לפני ההורדה בדיקה אם הplayer בפעולה ואז לעצור (וזה אולי פחות נחמד כי אז בזמן ההורדה יש שקט...).
הפתרונות הם מה שקומפיונט אמר. גם אתה חייב לשמור את הקובץ אתה לא חייב להשמיע עם AudioFileReader, אתה יכול מייד לקרוא את תוכן הקובץ ולהשמיע עם RawSourceWaveStream.
אכתוב לך את הדרך הב' שהציע קומפיונט, אני שכתבתי את כל ההורדה מהאינטרנט כי היא כתובה מאוד מסורבל (משהו בסגנון של chatGPT).Async Function DownloadFromUrl(url As String, payload As Object) As Task(Of String) Using wc As New HttpClient() Dim content = New StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json") Dim taskRes = Await wc.PostAsync(url, content) Return Await taskRes.Content.ReadAsStringAsync() End Using End Function Function GetBytesWavFromJson(strJson As String) As Byte() Dim jsonData = JsonSerializer.Deserialize(Of JsonElement)(strJson) Dim audioContent = jsonData.GetProperty("audioContent").ToString() If String.IsNullOrEmpty(audioContent) Then Return Convert.FromBase64String(audioContent) Else Return Nothing End If End Function Async Function DownloadAndPlay() As Task Dim text = Await DownloadFromUrl("", payload) Dim audio = GetBytesWavFromJson(text) player?.Dispose() player = New WaveOutEvent() player.Init(New RawSourceWaveStream(audio, 0, audio.Length, New WaveFormat())) player.Play() 'playnig = True מיותר לכאורה End Function
יש בקוד הזה סגנון מודרני של async await, אם זה חדש לך מידי הנה אותו קוד בגירסה אחרת:
Function DownloadFromUrl(url As String, payload As Object) As String Using wc As New WebClient() Dim content = New StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json") wc.Headers(HttpRequestHeader.ContentType) = "application/json" Return wc.UploadString(url, JsonSerializer.Serialize(payload)) End Using End Function Function GetBytesWavFromJson(strJson As String) As Byte() Dim jsonData = JsonSerializer.Deserialize(Of JsonElement)(strJson) Dim audioContent = jsonData.GetProperty("audioContent").ToString() If String.IsNullOrEmpty(audioContent) Then Return Convert.FromBase64String(audioContent) Else Return Nothing End If End Function Sub DownloadAndPlay() Dim text = DownloadFromUrl("", payload) Dim audio = GetBytesWavFromJson(text) player?.Dispose() player = New WaveOutEvent() player.Init(New RawSourceWaveStream(audio, 0, audio.Length, New WaveFormat())) player.Play() 'playnig = True מיותר לכאורה End Sub
-
@dovid שיניתי את השיטה לRawSourceWaveStream וזה פתר את הבעיה, אבל לא הבנתי למה טענת
נו @אביי, אתה מנסה לכתוב על הקובץ הרבה לפני שאתה עוצר את ההשמעה!
אני עשיתי סטופ לפני הקריאה לפונקציה בכלל. ToA זה הפונקציה שמורידה את השמע ובסיום קוראת לפונקציה PlayAudioFile.
If playnig = True Then player.Stop() End If ToA(r)
.
ו@אביי כיון שאני יודע שאתה עם רקע של קוד JS בגוגל סקריפט
אני מאוד ממליץ לך להגר לC#, זה בהתחלה נראה קשוח ומרובע יותר, אבל זה מנסיוני שווה.אני אכן שם, רק בפרויקט הזה יש אילוצים שלא תלויים בי שמחייבים אותי לvb (נראה לי שכבר כתבתי בעבר כמה אני שונא אותה..) אגב, לgs עברתי אחרי זה, בגלל שהוא מאפשר להריץ באופן קבוע ועצמאי עם אמינות גבוהה ללא צורך להחזיק שרת (ויש גם את העניין של המשחק בתוך האקו-סיסטם של גוגל ללא מפתחות וכו')..
-
@אביי כתבתי לך כבר שהPlayer_PlaybackStopped לא קורה מיידית בקריאה לstop אלא רק כשנגמר הקוד להריץ, כי זה טבעו של אירוע.
ממילא אם לפני הכתיבה על הקובץ עצרת את האודיו אך לא קראת מפורשות לdispose, הקוד של Player_PlaybackStopped לא יעזור כי הוא יקרה אחרי שתנסה לכתוב על הקובץ.