save audio to mp3
This commit is contained in:
parent
a8a867e4f9
commit
0550462b4e
37
broadcast/audio.go
Normal file
37
broadcast/audio.go
Normal 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())
|
||||||
|
}
|
|
@ -4,5 +4,6 @@ go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang/protobuf v1.4.2 // indirect
|
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
|
layeh.com/gumble v0.0.0-20200818122324-146f9205029b
|
||||||
)
|
)
|
||||||
|
|
|
@ -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.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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
@ -17,25 +18,37 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type AudioListener struct {
|
type AudioListener struct {
|
||||||
name string
|
buffer *bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (audiolistener AudioListener) OnAudioStream(e *gumble.AudioStreamEvent) {
|
func (listener AudioListener) OnAudioStream(e *gumble.AudioStreamEvent) {
|
||||||
fmt.Printf("Received AudioStreamEvent from %s\n", e.User.Name)
|
// One AudioStreamEvent for person speaking on the channel
|
||||||
go ReadPacket(e.C)
|
// 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 ReadPacket(ch <-chan *gumble.AudioPacket) {
|
func SaveBufToMP3(buffer *bytes.Buffer) {
|
||||||
outFile := "pcm_out.raw"
|
outFileName := "recording.mp3"
|
||||||
fmt.Printf("Saving out to %s", outFile) // debug
|
fmt.Printf("Saving out to %s", outFileName) // debug
|
||||||
pcm_out, _ := os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
|
// outFile, _ := os.OpenFile(outFileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
|
||||||
defer pcm_out.Close()
|
// defer outFile.Close()
|
||||||
|
|
||||||
for packet := range ch {
|
PcmToMp3(buffer, outFileName) // TODO: check output, err
|
||||||
// log.Printf("Message from %s", packet.Sender.Name) // debug
|
|
||||||
buf := packet.AudioBuffer
|
|
||||||
pcm_out.Write(UnsafeCastInt16sToBytes(buf))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -45,12 +58,16 @@ func main() {
|
||||||
|
|
||||||
config.Attach(gumbleutil.Listener{
|
config.Attach(gumbleutil.Listener{
|
||||||
TextMessage: func(e *gumble.TextMessageEvent) {
|
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)
|
config.AttachAudio(l)
|
||||||
mumbleServer := os.Getenv("MUMBLE_SERVER")
|
mumbleServer := os.Getenv("MUMBLE_SERVER")
|
||||||
if len(mumbleServer) == 0 {
|
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
|
client, err := gumble.DialWithDialer(&net.Dialer{}, mumbleServer, config, &tls.Config{InsecureSkipVerify: true}) // TODO: fix cert or make it an option
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print available channels on the server
|
// Print available channels on the server
|
||||||
|
|
Loading…
Reference in New Issue
Block a user