mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-20 16:54:25 +00:00
WIP
This commit is contained in:
parent
fdc1ad463e
commit
243d547632
4 changed files with 132 additions and 14 deletions
83
main.go
83
main.go
|
|
@ -19,7 +19,9 @@ import (
|
|||
"github.com/gorilla/websocket"
|
||||
pionRTC "github.com/pion/webrtc"
|
||||
|
||||
"gopkg.in/hraban/opus.v2"
|
||||
// "gopkg.in/hraban/opus.v2"
|
||||
"github.com/xlab/opus-go/opus"
|
||||
"github.com/gordonklaus/portaudio"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -311,22 +313,68 @@ func fanoutScreen(imageChannel chan *image.RGBA, roomID string) {
|
|||
}
|
||||
|
||||
|
||||
var cc chan float32 = make(chan float32, 100000)
|
||||
|
||||
func Callback(out []float32) {
|
||||
var output float32
|
||||
for i := range out {
|
||||
if i % 2 == 0 {
|
||||
select {
|
||||
case sample := <-cc:
|
||||
output = sample
|
||||
default:
|
||||
output = 0
|
||||
}
|
||||
out[i] = output
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fanoutAudio fanout outputs to all webrtc in the same room
|
||||
func fanoutAudio(audioChannel chan float32, roomID string) {
|
||||
var output float32
|
||||
pcm := make([]float32, 240)
|
||||
|
||||
enc, err := opus.NewEncoder(48000, 2, opus.AppVoIP)
|
||||
// ix, _ := enc.DTX() //false
|
||||
// ix1, _ := enc.Bitrate() //120000
|
||||
// ix2, _ := enc.Complexity() //9
|
||||
// ix3, _ := enc.MaxBandwidth() //1105
|
||||
// ix4, _ := enc.PacketLossPerc() //0
|
||||
portaudio.Initialize()
|
||||
defer portaudio.Terminate()
|
||||
|
||||
host, err := portaudio.DefaultHostApi()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
parameters := portaudio.HighLatencyParameters(nil, host.DefaultOutputDevice)
|
||||
stream, err := portaudio.OpenStream(parameters, Callback)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
log.Println(parameters.SampleRate, parameters.Output.Channels)
|
||||
stream.Start()
|
||||
|
||||
|
||||
|
||||
// dec, err := opus.NewDecoder(48000, 2)
|
||||
|
||||
|
||||
// enc, err := opus.NewEncoder(48000, 2, opus.AppAudio)
|
||||
// // ix, _ := enc.DTX() //false
|
||||
// // ix1, _ := enc.Bitrate() //120000
|
||||
// // ix2, _ := enc.Complexity() //9
|
||||
// // ix3, _ := enc.MaxBandwidth() //1105
|
||||
// // ix4, _ := enc.PacketLossPerc() //0
|
||||
|
||||
// enc.SetMaxBandwidth(opus.Fullband)
|
||||
// enc.SetBitrateToAuto()
|
||||
// enc.SetComplexity(10)
|
||||
|
||||
var err2 int32
|
||||
dec := opus.DecoderCreate(48000, 2, &err2)
|
||||
enc := opus.EncoderCreate(48000, 2, opus.ApplicationAudio, &err2)
|
||||
|
||||
enc.SetMaxBandwidth(opus.Fullband)
|
||||
enc.SetBitrateToAuto()
|
||||
enc.SetComplexity(10)
|
||||
|
||||
|
||||
if err != nil {
|
||||
log.Println("[!] Cannot create audio encoder")
|
||||
return
|
||||
|
|
@ -346,12 +394,13 @@ func fanoutAudio(audioChannel chan float32, roomID string) {
|
|||
|
||||
}
|
||||
pcm[i] = output
|
||||
// pcm[i] = <- audioChannel
|
||||
}
|
||||
}
|
||||
|
||||
data := make([]byte, 1000)
|
||||
n, err := enc.EncodeFloat32(pcm, data)
|
||||
// n, err := enc.EncodeFloat32(pcm, data)
|
||||
|
||||
n := opus.EncodeFloat(enc, pcm, 120, data, 1000)
|
||||
|
||||
if err != nil {
|
||||
log.Println("[!] Failed to decode")
|
||||
|
|
@ -359,6 +408,16 @@ func fanoutAudio(audioChannel chan float32, roomID string) {
|
|||
}
|
||||
data = data[:n]
|
||||
|
||||
pcm2 := make([]float32, 1000)
|
||||
// n2, err := dec.DecodeFloat32(data, pcm2)
|
||||
n2 := opus.DecodeFloat(dec, string(data), n, pcm2, 1000, 0)
|
||||
pcm2 = pcm2[:n2]
|
||||
for i := 0; i < int(n2); i++ {
|
||||
cc <- pcm2[i]
|
||||
}
|
||||
log.Println(n, n2)
|
||||
|
||||
|
||||
isRoomRunning := false
|
||||
for _, webRTC := range rooms[roomID].rtcSessions {
|
||||
// Client stopped
|
||||
|
|
|
|||
BIN
static/sinewave.raw
Normal file
BIN
static/sinewave.raw
Normal file
Binary file not shown.
59
static/test.html
Normal file
59
static/test.html
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<html>
|
||||
<body>
|
||||
<button onclick="play()">hihi</button>
|
||||
<script>
|
||||
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||
|
||||
// Stereo
|
||||
var channels = 1;
|
||||
var sampleRate = 16000;
|
||||
var bitDepth = 16;
|
||||
|
||||
// Create an empty two second stereo buffer at the
|
||||
// sample rate of the AudioContext
|
||||
var req = new XMLHttpRequest();
|
||||
var sound;
|
||||
req.open('GET', "/static/sinewave.raw", false);
|
||||
req.overrideMimeType('text\/plain; charset=x-user-defined');
|
||||
req.onreadystatechange = function (aEvt) {
|
||||
if (req.readyState == 4) {
|
||||
if(req.status == 200) {
|
||||
sound = req.responseText;
|
||||
console.log("loaded");
|
||||
} else {
|
||||
alert('failed loading audio');
|
||||
}
|
||||
}
|
||||
};
|
||||
req.send(null);
|
||||
|
||||
function play(){
|
||||
frameCount = sound.length / 2;
|
||||
myAudioBuffer = audioCtx.createBuffer(channels, frameCount, sampleRate);
|
||||
|
||||
for (var channel = 0; channel < channels; channel++) {
|
||||
var nowBuffering = myAudioBuffer.getChannelData(channel, bitDepth, sampleRate);
|
||||
for (var i = 0; i < frameCount; i++) {
|
||||
// audio needs to be in [-1.0; 1.0]
|
||||
// for this reason I also tried to divide it by 32767
|
||||
// as my pcm sample is in 16-Bit. It plays still the
|
||||
// same creepy sound less noisy.
|
||||
var word = (sound.charCodeAt(i * 2) & 0xff) + ((sound.charCodeAt(i * 2 + 1) & 0xff) << 8);
|
||||
nowBuffering[i] = ((word + 32768) % 65536 - 32768) / 32768.0;
|
||||
}
|
||||
}
|
||||
// Get an AudioBufferSourceNode.
|
||||
// This is the AudioNode to use when we want to play an AudioBuffer
|
||||
var source = audioCtx.createBufferSource();
|
||||
// set the buffer in the AudioBufferSourceNode
|
||||
source.buffer = myAudioBuffer;
|
||||
// connect the AudioBufferSourceNode to the
|
||||
// destination so we can hear the sound
|
||||
source.connect(audioCtx.destination);
|
||||
// start the source playing
|
||||
source.start();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -281,8 +281,8 @@ func (w *WebRTC) startStreaming(vp8Track *webrtc.Track, opusTrack *webrtc.Track)
|
|||
go func() {
|
||||
for w.isConnected {
|
||||
data := <-w.AudioChannel
|
||||
// opusTrack.Write(data)
|
||||
opusTrack.WriteSample(media.Sample{Data: data, Samples: uint32(len(data))})
|
||||
opusTrack.Write(data)
|
||||
// opusTrack.WriteSample(media.Sample{Data: data, Samples: uint32(len(data))})
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue