From 7a3943ae4c80ff129aa270f0e1a7520ddac48789 Mon Sep 17 00:00:00 2001 From: trichimtrich Date: Tue, 23 Apr 2019 04:49:43 +0800 Subject: [PATCH] audio channel unordered + unreliable buffer --- main.go | 69 +++++++++++++++++++++++++++++++- static/index_ws.html | 8 +--- static/js/ws.js | 94 +++++++++++++++++++++----------------------- webrtc/webrtc.go | 60 ++++++++++++++++------------ 4 files changed, 147 insertions(+), 84 deletions(-) diff --git a/main.go b/main.go index 5a428bdc..d8fb70ba 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,8 @@ import ( "github.com/gorilla/websocket" pionRTC "github.com/pion/webrtc" uuid "github.com/satori/go.uuid" + + "gopkg.in/hraban/opus.v2" ) const ( @@ -142,7 +144,8 @@ func initRoom(roomID, gameName string) string { } rooms[roomID] = room - go room.start() + go room.startVideo() + go room.startAudio() go director.Start([]string{"games/" + gameName}) return roomID @@ -326,7 +329,7 @@ func generateRoomID() string { return roomID } -func (r *Room) start() { +func (r *Room) startVideo() { // fanout Screen for { select { @@ -357,6 +360,68 @@ func (r *Room) start() { } } +func (r *Room) startAudio() { + log.Println("Enter fan audio") + + enc, err := opus.NewEncoder(ui.SampleRate, ui.Channels, opus.AppAudio) + + maxBufferSize := ui.TimeFrame * ui.SampleRate / 1000 + pcm := make([]float32, maxBufferSize) // 640 * 1000 / 16000 == 40 ms + idx := 0 + + if err != nil { + log.Println("[!] Cannot create audio encoder") + return + } + + var count byte = 0 + + // fanout Audio + for { + select { + case <-r.Done: + r.remove() + return + case sample := <-r.audioChannel: + pcm[idx] = sample + idx ++ + if idx == len(pcm) { + data := make([]byte, 640) + + n, err := enc.EncodeFloat32(pcm, data) + + if err != nil { + log.Println("[!] Failed to decode") + continue + } + data = data[:n] + data = append(data, count) + + r.sessionsLock.Lock() + for _, webRTC := range r.rtcSessions { + // Client stopped + if webRTC.IsClosed() { + continue + } + + // encode frame + // fanout audioChannel + if webRTC.IsConnected() { + // NOTE: can block here + webRTC.AudioChannel <- data + } + //isRoomRunning = true + } + r.sessionsLock.Unlock() + + idx = 0 + count = (count + 1) & 0xff + + } + } + } +} + func (r *Room) remove() { log.Println("Closing room", r) r.director.Done <- struct{}{} diff --git a/static/index_ws.html b/static/index_ws.html index e8592a47..ac08af69 100644 --- a/static/index_ws.html +++ b/static/index_ws.html @@ -12,7 +12,6 @@ textarea { -

Your current room:
You can join a remote game by roomID.
Room ID: @@ -25,7 +24,7 @@ Play as player(1,2):