//go:build linux && (386 || amd64 || arm || arm64 || mipsle) package alsa import ( "fmt" "net/http" "os" "strconv" "strings" "github.com/AlexxIT/go2rtc/internal/api" "github.com/AlexxIT/go2rtc/internal/streams" "github.com/AlexxIT/go2rtc/pkg/alsa" "github.com/AlexxIT/go2rtc/pkg/alsa/device" ) func Init() { streams.HandleFunc("alsa", alsa.Open) api.HandleFunc("api/alsa", apiAlsa) } func apiAlsa(w http.ResponseWriter, r *http.Request) { files, err := os.ReadDir("/dev/snd/") if err != nil { return } var sources []*api.Source for _, file := range files { if !strings.HasPrefix(file.Name(), "pcm") { continue } path := "/dev/snd/" + file.Name() dev, err := device.Open(path) if err != nil { continue } info, err := dev.Info() if err == nil { formats := formatsToString(dev.ListFormats()) r1, r2 := dev.RangeRates() c1, c2 := dev.RangeChannels() source := &api.Source{ Name: info.ID, Info: fmt.Sprintf("Formats: %s, Rates: %d-%d, Channels: %d-%d", formats, r1, r2, c1, c2), URL: "alsa:device?audio=" + path, } if !strings.Contains(source.Name, info.Name) { source.Name += ", " + info.Name } sources = append(sources, source) } _ = dev.Close() } api.ResponseSources(w, sources) } func formatsToString(formats []byte) string { var s string for i, format := range formats { if i > 0 { s += " " } switch format { case 2: s += "s16le" case 10: s += "s32le" default: s += strconv.Itoa(int(format)) } } return s }