Wie umgeht man den Befehlsfehler „say“ beim Einstellen der Lautstärke?

Kontext:

Ich habe eine AppleScript .scpt-Datei, die den ausgewählten Text in der Systemstimme spricht. Der markierte Text wird in die Zwischenablage kopiert und dann über den Befehl gesprochen say. Das Skript wird per Tastendruck über FastScripts ausgelöst.

Da die macOS Text-to-Speech-Lautstärke standardmäßig zu laut ist (und es keine globale Lautstärkeregelung für die Sprache gibt), verwende ich AppleScript, um die Lautstärke als Bruchteil der aktuellen Lautstärke festzulegen. Ich habe aus diesem Beitrag gelernt, wie man dies erreicht:

Wie ändere ich die Lautstärke von „Sag“ in AppleScript?

Hier ist der Teil meines Codes, der für meine Frage relevant ist:

set the clipboard to ("[[volm 0.35]] " & (the clipboard))
set this_say_Pid to do shell script "LANG=en_US.UTF-8 pbpaste -Prefer txt | say > /dev/null 2>&1 & echo $!"

Der obige Code spricht den Text der Zwischenablage mit einer Lautstärke, die 35 % der aktuellen Systemlautstärke beträgt, was ich mir wünsche. (Ja, die hörbare Sprache ist standardmäßig wirklich so laut.)

Der Code funktioniert gut, außer ich habe einen Fehler entdeckt.


So reproduzieren Sie den Fehler:

Um diesen Fehler zu beobachten, kopieren Sie den folgenden Text in die Zwischenablage und führen Sie dann den obigen Code aus:

 

- This is a test.

Der Problemtext ist in Markdown (was Stack Exchange verwendet) schwierig zu formatieren, da 1) leere Zeilenumbrüche automatisch entfernt werden und 2) eine Bindestrich-Leerzeichen-Kombination in einen Aufzählungspunkt umgewandelt wird. Aus diesem Grund sieht die obige Textformatierung wackelig aus; Ich musste ein Blockquote verwenden, um Problem eins zu umgehen, und ich musste einen Codeblock hinzufügen, um Problem zwei zu umgehen.

Hier ist der Problemtext, buchstäblich in Worten ausgeschrieben (wenn Sie eine Textdatei öffnen und den Text neu erstellen möchten):

newline
hyphen space Text

Stellen Sie sicher, dass Sie den leeren Zeilenumbruch einfügen, wenn Sie den Text in die Zwischenablage kopieren. Achten Sie darauf, dass zwischen dem Bindestrich und dem ersten Wort des Textes ein Leerzeichen steht. Andernfalls taucht der Fehler nicht auf.

Der Problemtext muss ganz am Anfang des Zwischenablagetextes stehen. Das heißt, wenn sich der Problemtext in der Mitte oder am Ende des Zwischenablagetexts befindet, taucht der Fehler nicht auf.


Weitere Möglichkeiten, den Fehler zu reproduzieren:

Der Bindestrich (-) kann durch einen Bindestrich (–) ( ⌥ option+ -) oder einen Bindestrich (—) ( ⌥ option+ ⇧ shift+ -) ersetzt werden, und der Fehler taucht immer noch auf. Soweit ich in meinen Tests festgestellt habe, gibt es keine anderen Satzzeichen, die den Bindestrich ersetzen können, der den Fehler auslöst.


Es gibt eine andere Möglichkeit, den Fehler auszulösen, die keinen Bindestrich oder Gedankenstrich beinhaltet. Wenn dem Text mindestens 2 Zeilenumbrüche vorangestellt sind, taucht der Fehler auf.

Zum Beispiel:

  • Wenn es 1 Zeilenumbruchzeichen gibt, taucht der Fehler nicht auf.

  • Wenn sich über dem Text 47 Zeilenumbruchzeichen befinden, taucht der Fehler auf.

Ob zwischen den 2+ Zeilenumbruchzeichen und dem Text Leerzeichen stehen, spielt keine Rolle; der Fehler taucht so oder so auf.


Die Wirkung des Fehlers:

  • Wenn Sie den AppleScript-Code mit dem Problemtext in Ihrer Zwischenablage ausführen, wird die Lautstärke kein bisschen verringert; die Zwischenablage wird mit der Systemlautstärke gesprochen.

  • Außerdem gibt es eine merkliche Verzögerung, bevor der Text gesprochen wird.


Um es klar zu sagen, obwohl der Kontext meiner Frage eine .scpt-Datei ist, handelt es sich technisch gesehen nicht um einen AppleScript-Fehler. Der Fehler besteht bei der saydirekten Verwendung in Terminal.app. Geben Sie beispielsweise Folgendes in Terminal ein, um den Fehler zu reproduzieren:

say "[[volm 0.35]]
- This is a test."

Ist es möglich, diesen Fehler zu beheben, so dass, wenn der Inhalt der Zwischenablage mit irgendeiner Art von Problemtext beginnt, mein Skript für die benutzerdefinierte Lautstärke empfindlich bleibt und keine Verzögerung eingeführt wird?

Vielen Dank, dass Sie mich darauf aufmerksam gemacht haben. Das war ein Tippfehler, den ich gerade korrigiert habe. Ja, ich kann den Fehler in Script Editor.app reproduzieren, indem ich die erste Zeile durch die folgende Codezeile ersetze:set the clipboard to ("[[volm 0.35]] " & ("\n- This is a test."))
Während meine letzte Änderung veröffentlicht wurde, nachdem Sie Ihren Kommentar „Okay, nach einigen Tests …“ veröffentlicht hatten, habe ich tatsächlich an dieser Änderung gearbeitet und die Offenbarung des Zeilenumbruchs entdeckt, bevor ich Ihren Kommentar gelesen habe. Es war ein Zufall.
In Bezug auf Ihren zweiten Kommentar nimmt mein Skript den ausgewählten Text und legt ihn in die Zwischenablage. Es kommt nicht oft vor, dass der ausgewählte Text mit mehr als einem Zeilenumbruch oder einem beginnt newline + hyphen/dash + space. Aber es reicht oft aus, dass es lästig und die Energie wert ist, einen Beitrag zu erstellen, um das Problem zu lösen. Die Sprache bei voller Lautstärke ist sehr erschreckend. Ich bin es nicht unbedingt, der den Problemtext verwendet; es ist jede vorhandene Textauswahl, die den Problemtext enthält. Ich würde es vorziehen, wenn mein Skript diesen Fehler nicht hat, weil der Text, den ich auswähle, unvorhersehbar ist.

Antworten (2)

Am besten fügen Sie '[[volm 0.35]] ' in die Shell (nicht in die Zwischenablage) ein, etwa so:

set this_say_Pid to do shell script "say '[[volm 0.35]]\\ '$(LANG=en_US.UTF-8 pbpaste -Prefer txt) > /dev/null 2>&1 & echo $!"

Oder wenn Sie " [[volm 0.35]] " in die Zwischenablage legen möchten , verwenden Sie die einfachen Anführungszeichen wie folgt:

set the clipboard to ("'[[volm 0.35]] '" & (the clipboard))
set this_say_Pid to do shell script "LANG=en_US.UTF-8 pbpaste -Prefer txt | say > /dev/null 2>&1 & echo $!"
Ich habe tatsächlich festgestellt, dass Ihre erste Lösung einen neuen Fehler enthält. Wenn die Zwischenablage einen Bindestrich enthält, auf den kein Leerzeichen folgt, spricht Ihr Code den Text nicht. Versuchen Sie es beispielsweise mit diesem Text:-Speak this sentence.
Ich habe meine Antwort aktualisiert, ich habe ein entkommenes Leerzeichen nach '[[volm 0.35]] gesetzt
Ich habe einen Fehler in Ihrer zweiten Lösung gefunden. Wenn der Text einen Apostroph enthält, spricht der Code das Wort, das den Apostroph enthält, falsch aus. Wenn der Zwischenablagetext mehr als einen Apostroph enthält, wird nur das erste Wort, das einen Apostroph enthält, falsch ausgesprochen. Führen Sie beispielsweise den Code mit der folgenden Zeile in der Zwischenablage aus: They've been here and they've been here and they've been here.Sie werden feststellen, dass die erste They'veals „they vee“ ausgesprochen wird. Aber das ist keine große Sache; Ihre erste Lösung hat diesen Fehler nicht, also werde ich einfach die erste Lösung verwenden.

Fügen Sie einfach ein Komma nach dem [[volm 0.35]]-Teil Ihres Shell-Skripts hinzu. Ein Leerzeichen nach dem Komma ist wahrscheinlich nicht erforderlich.

set the clipboard to ("[[volm 0.35]], " & ("\n- This is a test."))

Damit entfällt auch der zweite Fehler (Bindestrich und Text ohne trennendes Leerzeichen).

Ihre Lösung funktioniert einwandfrei und ist auch fehlerfrei.