package main import ( "bytes" "encoding/binary" "log" "os/exec" "github.com/kkdai/youtube/v2" ) const ( ItagM4AAudio = 140 SizeOfInt16 = 2 ) // TODO: process as stream to avoid loading full buffer in memory func main() { var client youtube.Client videoID := "s_oJYdRlrv0" video, err := client.GetVideo(videoID) if err != nil { log.Fatal(err) } format := video.Formats.FindByItag(ItagM4AAudio) stream, _, err := client.GetStream(video, format) if err != nil { log.Fatal(err) } // TODO: force 44.1khz cmd := exec.Command("ffmpeg", "-i", "-", "-f", "s16le", "-acodec", "pcm_s16le", "-") cmd.Stdin = stream var out bytes.Buffer cmd.Stdout = &out var errOut bytes.Buffer cmd.Stderr = &errOut if err = cmd.Run(); err != nil { log.Fatalf("err = %v, stdErr = %s", err, errOut.String()) } log.Printf("byteLen = %d", out.Len()) // TODO: reflect.Slice to avoid copying? data := make([]uint16, 0, out.Len()/SizeOfInt16) for i := 0; i < out.Len(); i += SizeOfInt16 { v := binary.LittleEndian.Uint16(out.Bytes()[i : i+SizeOfInt16]) data = append(data, v) } log.Printf("intLen = %d", len(data)) log.Printf("ints = %+v", data[0:8192]) }