diff --git a/audio/audio.go b/audio/audio.go new file mode 100644 index 0000000..04e3a98 --- /dev/null +++ b/audio/audio.go @@ -0,0 +1,53 @@ +package audio + +import ( + "os/exec" + "fmt" + "regexp" +) + + +type MicStreamConfig struct { + Format string + Device string + Encoding string + Bitrate int + Channels int +} + +func StreamMic(config MicStreamConfig) *exec.Cmd { + cmd := exec.Command("ffmpeg", "-re", + "-f", config.Format, + "-i", config.Device, + "-f", config.Encoding, + "-ar", fmt.Sprintf("%d", config.Bitrate), + "-ac", fmt.Sprintf("%d", config.Channels), + "-", + ) + return cmd +} + +func GetMicDevice() (string, error) { + cmd := exec.Command("ffmpeg", + "-f", "avfoundation", + "-list_devices", "true", + "-i", "\"\"", + ) + // ignore error, this ffmpeg command returns exit status 1 + outputBytes, _ := cmd.CombinedOutput() + output := string(outputBytes) + parsedOutput := parseDeviceNumber(output) + if parsedOutput == "" { + return "", fmt.Errorf("Command: %s\nFailed to parse FFmpeg output:\n%s", cmd, output) + } + return parsedOutput, nil +} + +func parseDeviceNumber(ffmpegOutput string) string { + re := regexp.MustCompile(`\[(\d)\].*?[Mm]icrophone`) + matches := re.FindStringSubmatch(ffmpegOutput) + if (len(matches) == 2) { + return matches[1] + } + return "" +} diff --git a/main.go b/main.go index 8d71925..4d2cfb5 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,16 @@ package main import ( "fmt" + "os" + "io" "time" "remote-mic/socketops" "remote-mic/pulsectl" + "remote-mic/audio" ) -func nop() { +func socketExample() { fmt.Print("Listening for TCP connection on port 8080... ") conn, err := socketops.AcceptConn(":8080") if err != nil { @@ -24,7 +27,7 @@ func nop() { fmt.Println("Exiting.") } -func main() { +func pulsectlExample() { pulsectl.LoadPipeSource(pulsectl.PipeSourceConfig{ "remote-mic", "/dev/shm", @@ -35,3 +38,33 @@ func main() { time.Sleep(10 * time.Second) pulsectl.UnloadPipeSource() } + +func micStreamExample() { + cmd := audio.StreamMic(audio.MicStreamConfig{ + "avfoundation", + ":0", + "s16le", + 44100, + 2, + }) + + pipe, _ := cmd.StdoutPipe() + + cmd.Start() + + for { + io.Copy(os.Stdout, pipe) + } +} + +func getDeviceExample() { + device, err := audio.GetMicDevice() + if err != nil { + panic(err) + } + fmt.Println(device) +} + +func main() { + getDeviceExample() +}