save audio to mp3

This commit is contained in:
bretello 2020-10-23 22:08:06 +02:00
parent a8a867e4f9
commit 0550462b4e
4 changed files with 73 additions and 17 deletions

37
broadcast/audio.go Normal file
View File

@ -0,0 +1,37 @@
package main
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"os"
lame "github.com/sunicy/go-lame"
)
func PcmToMp3(audioBuffer *bytes.Buffer, mp3FileName string) {
mp3File, _ := os.OpenFile(mp3FileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
defer mp3File.Close()
wr, err := lame.NewWriter(mp3File)
if err != nil {
panic("cannot create lame writer, err: " + err.Error())
}
wr.InSampleRate = 48000 // input sample rate
wr.InNumChannels = 1 // number of channels: 1
wr.OutMode = lame.MODE_STEREO // common, 2 channels
wr.OutQuality = 0 // 0: highest; 9: lowest
wr.OutSampleRate = 44100 // output sample rate
io.Copy(wr, audioBuffer)
wr.Close()
}
func bufWriter(stuff []byte) {
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.LittleEndian, stuff)
if err != nil {
fmt.Println("binary.Write failed:", err)
}
fmt.Printf("% x", buf.Bytes())
}

View File

@ -4,5 +4,6 @@ go 1.15
require (
github.com/golang/protobuf v1.4.2 // indirect
github.com/sunicy/go-lame v0.0.0-20200422031049-1c192eaafa39
layeh.com/gumble v0.0.0-20200818122324-146f9205029b
)

View File

@ -12,6 +12,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/sunicy/go-lame v0.0.0-20200422031049-1c192eaafa39 h1:P/6L4pZMkHutxyefALLAiXCPkcD+5NcvJRGayZmtBmY=
github.com/sunicy/go-lame v0.0.0-20200422031049-1c192eaafa39/go.mod h1:H5mJP3sFKpUGaeckgSaMVXcTgnSgImhx54qyQXbpTVY=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=

View File

@ -1,6 +1,7 @@
package main
import (
"bytes"
"os"
"time"
@ -17,25 +18,37 @@ import (
)
type AudioListener struct {
name string
buffer *bytes.Buffer
}
func (audiolistener AudioListener) OnAudioStream(e *gumble.AudioStreamEvent) {
fmt.Printf("Received AudioStreamEvent from %s\n", e.User.Name)
go ReadPacket(e.C)
}
func ReadPacket(ch <-chan *gumble.AudioPacket) {
outFile := "pcm_out.raw"
fmt.Printf("Saving out to %s", outFile) // debug
pcm_out, _ := os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
defer pcm_out.Close()
for packet := range ch {
// log.Printf("Message from %s", packet.Sender.Name) // debug
buf := packet.AudioBuffer
pcm_out.Write(UnsafeCastInt16sToBytes(buf))
func (listener AudioListener) OnAudioStream(e *gumble.AudioStreamEvent) {
// One AudioStreamEvent for person speaking on the channel
// fmt.Printf("Received AudioStreamEvent from %s\n", e.User.Name) // debug
go func(ch <-chan *gumble.AudioPacket) {
outside:
for {
select {
case packet := <-ch:
fmt.Printf(".")
listener.buffer.Write(UnsafeCastInt16sToBytes(packet.AudioBuffer))
case <-time.After(100 * time.Millisecond):
fmt.Println("timeout")
break outside
}
}
// fmt.Println("\nFinished processing audio packets") // debug
SaveBufToMP3(listener.buffer)
listener.buffer.Reset()
}(e.C)
}
func SaveBufToMP3(buffer *bytes.Buffer) {
outFileName := "recording.mp3"
fmt.Printf("Saving out to %s", outFileName) // debug
// outFile, _ := os.OpenFile(outFileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
// defer outFile.Close()
PcmToMp3(buffer, outFileName) // TODO: check output, err
}
func main() {
@ -45,12 +58,16 @@ func main() {
config.Attach(gumbleutil.Listener{
TextMessage: func(e *gumble.TextMessageEvent) {
fmt.Printf("Received text message: %s\n", e.Message)
log.Printf("Received text message: %s\n", e.Message)
if e.Message == "/quit" {
e.Client.Disconnect()
}
},
})
l := AudioListener{name: "Eventprinter"}
var l AudioListener
l.buffer = new(bytes.Buffer)
config.AttachAudio(l)
mumbleServer := os.Getenv("MUMBLE_SERVER")
if len(mumbleServer) == 0 {
@ -60,7 +77,6 @@ func main() {
client, err := gumble.DialWithDialer(&net.Dialer{}, mumbleServer, config, &tls.Config{InsecureSkipVerify: true}) // TODO: fix cert or make it an option
if err != nil {
panic(err)
}
// Print available channels on the server