我正在构建一个供个人使用的小型音频应用程序,需要通过管道连接到某些外部工具。
我想围绕io.ReadCloser
构建程序,然后将其转换并通过管道传输到PulseAudios paplay
命令。
一个简化的示例:
package main
import (
"os/exec"
)
func main () {
speech, err := Say("Hello world!")
if err != nil {
log.Fatal(err)
}
err = Play(speech)
if err != nil {
log.Fatal(err)
}
}
// Say creates a stream containing text as a text-to-speech wav audio stream.
func Say(text string) (io.ReadCloser, error) {
speak := exec.Command("espeak", "--stdout", text)
out, err := speak.StdoutPipe()
if err != nil {
return nil, err
}
return out, speak.Start()
}
// Play a wav audio stream.
func Play(s io.ReadCloser) error {
play := exec.Command("paplay")
play.Stdin = s
play.Stderr = os.Stderr
return play.Run()
}
这是一个简化的示例,但是我想使用不同的命令来创建wav流,并将它们连接起来并通过管道传递到paplay
。
exec.Cmd
上的go docs指定我需要在每个命令上调用exec.Cmd
以确保清除分配给运行该命令的资源:
等待释放与Cmd相关的任何资源。
但是同时不清楚在使用Wait
时是否需要调用此。
stdout管道用完并且命令退出后,将清理命令吗?还是需要在这里重新考虑抽象?
但是同时不清楚在使用StdoutPipe时是否需要调用它。
是,您仍然需要StdoutPipe
来考虑cmd实例完全结束。
但是,通过管道传输标准输出流,其关闭信号足以检测复制结束。
医生说
StdoutPipe返回将连接到命令的管道的管道。命令启动时的标准输出。
等待命令退出后将关闭管道,因此大多数呼叫者不需要自己关闭管道;但是,这意味着在管道中的所有读取之前调用“等待”是不正确的完成。由于相同的原因,使用时调用Run是不正确的StdoutPipe。请参阅示例以了解惯用用法。
在stdout管道用完并且命令退出后将清理命令或
是。
我需要在这里重新思考我的抽象吗?
编号
您的代码还可以。