Я создаю небольшое аудио-приложение для личного использования, и мне нужно подключиться к некоторым внешним инструментам.
Я хочу структурировать свою программу вокруг io.ReadCloser
s, которую я преобразую, и передать в PulseAudios paplay
command.
Упрощенный пример:
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
.
Документы go на exec.Cmd
указывают, что мне нужно вызывать Wait
для каждой команды, чтобы убедиться, что ресурсы, выделенные для выполнения команды, очищены:
Wait освобождает любые ресурсы, связанные с Cmd.
Но в то же время неясно, нужно ли мне вызывать это при использовании StdoutPipe
.
Удастся ли очистить команду после исчерпания канала stdout и выхода из команды, или мне нужно переосмыслить мои абстракции здесь?