Heim > Backend-Entwicklung > Golang > Golang implementiert Voice-Chat

Golang implementiert Voice-Chat

WBOY
Freigeben: 2023-05-13 09:37:06
Original
1155 Leute haben es durchsucht

Mit der kontinuierlichen Weiterentwicklung der Technologie ist Sprachkommunikation zu einem unverzichtbaren Bestandteil des Lebens der Menschen geworden. Heute ist Voice-Chat zu einer der häufigsten Kommunikationsmethoden im Internet geworden. Daher ist es notwendig, die Voice-Chat-Funktionalität in die Anwendung zu integrieren, damit Benutzer problemlos per Sprache kommunizieren können. Golang ist eine sehr gute Programmiersprache. Sie ist effizient, schnell und zuverlässig, daher ist die Verwendung von Golang zur Implementierung der Voice-Chat-Funktion eine sehr gute Wahl. In diesem Artikel stellen wir vor, wie man Golang zur Implementierung der Voice-Chat-Funktion verwendet.

1. Umgebungseinstellungen

Bevor Sie mit der Implementierung der Voice-Chat-Funktion beginnen, müssen Sie die Golang-Sprachentwicklungsumgebung auf Ihrem Computer installieren. Nach der Installation müssen Sie den Befehl go get verwenden, um einige sprachbezogene Bibliotheken zu installieren, darunter:

  1. github.com/gordonklaus/portaudio: PortAudio-Audiobibliothek
  2. github.com/faiface/beep: Beep-Audiobibliothek
  3. github.com/faiface/gui: GUI-Benutzeroberflächenbibliothek
  4. github.com/gordonklaus/audiowaveform: Waveform-Wellenformbibliothek

Verwenden Sie den Befehl go get, um diese Bibliotheken schnell zu installieren. Mit dem Befehl go get github.com/gordonklaus/portaudio kann beispielsweise die PortAudio-Audiobibliothek installiert werden.

2. Implementierungsprozess

Nachdem die Umgebungseinstellung abgeschlossen ist, ist der nächste Schritt der spezifische Prozess der Implementierung der Voice-Chat-Funktion. Zunächst müssen Sie einen Client und einen Server erstellen, damit Benutzer miteinander kommunizieren können. Nachdem die Verbindung hergestellt wurde, kann der Client Audiodaten an den Server senden, der diese empfängt und an andere Clients weiterleitet. Anschließend können andere Clients die Audiodaten vom Client empfangen und abspielen.

  1. Erstellen eines Servers

Der erste Schritt beim Erstellen eines Servers besteht darin, den HTTP-Dienst zu starten und eine WebSocket-Verbindung zu erstellen. Der Code lautet wie folgt:

func main() {

    // 1. 启动HTTP服务
    http.HandleFunc("/", handleWebsocket)
    go http.ListenAndServe(":8080", nil)
    
}

func handleWebsocket(w http.ResponseWriter, r *http.Request) {

    // 2. 创建WebSocket连接
    ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
    if err != nil {
        log.Fatal(err)
    }
    
    // 3. 处理音频数据传输
    for {
        msgType, msg, err := ws.ReadMessage()
        if err != nil {
            log.Fatal(err)
        }
        ws.WriteMessage(msgType, msg)
    }
    
}
Nach dem Login kopieren

Im obigen Code wird zunächst ein HTTP-Dienst gestartet und lauscht auf 8080 am Port. Als nächstes wird in der Funktion handleWebsocket eine WebSocket-Verbindung erstellt, die jedes Mal aufgerufen wird, wenn eine Anfrage an den Server gesendet wird. Um die Übertragung von Audiodaten abzuwickeln, werden schließlich einige einfache WebSocket-Lese- und Schreibvorgänge verwendet.

  1. Erstellen Sie einen Client

Der erste Schritt zum Erstellen eines Clients besteht darin, dem Server beizutreten. Der Code lautet wie folgt:

func main() {

    // ...启动HTTP服务

    // 1. 创建WebSocket连接
    conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080", nil)
    if err != nil {
        log.Fatal(err)
    }

    // 2. 加入服务器
    message := []byte("join")
    conn.WriteMessage(websocket.TextMessage, message)

    // 3. 处理音频数据传输
    for {
        _, message, err := conn.ReadMessage()
        if err != nil {
            log.Fatal(err)
        }
        // 处理接收到的音频数据
        // ...
    }

}
Nach dem Login kopieren

Im obigen Code verwenden Sie zunächst die Funktion DefaultDialer.Dial, um eine WebSocket-Verbindung zu erstellen und eine Verbindung herzustellen es Link zum Server. Als nächstes nutzt der Client eine einfache Beitrittsnachricht, um dem Server mitzuteilen, dass der Client dem Chatroom beigetreten ist. Schließlich durchläuft der Client eine Schleife, um die vom Server gesendeten Audiodaten zu lesen und die Daten zu verarbeiten.

  1. Audio aufnehmen und abspielen

Der nächste Schritt ist der kritischste Schritt: Audio aufnehmen und abspielen. Golang verwendet für die Audioverarbeitung die Beep-Audiobibliothek, die eine große Anzahl von Audioprozessoren und Effekten bereitstellt. Hier ist ein Codebeispiel für die Aufnahme von Audio mithilfe der Bibliothek:

func main() {

    // ...创建WebSocket连接并加入服务器

    // 1. 配置recorder
    format := beep.Format{
        SampleRate:  44100, //采样率
        NumChannels: 1,     //通道数
        Precision:   2,     //数据精度
    }
    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))

    streamer := &audioStreamer{}
    streamer.buf = new(bytes.Buffer)
    streamer.stream = beep.NewMixedStreamer(beep.StreamerFunc(streamer.Sample), beep.Callback(func() {}))

    resampler, err := resample.New(resample.SincMediumQuality, streamer.stream, streamer)

    // 2. 创建recorder
    stream, format, err := portaudio.OpenDefaultStream(1, 0, format.SampleRate, 0, resampler.Process)

    if err != nil {
        log.Fatal(err)
    }

    // 3. 启动recorder
    err = stream.Start()
    if err != nil {
        log.Fatal(err)
    }

    // 4. 启动播放器
    speaker.Play(beep.Seq(streamer, beep.Callback(func() {})))

    // 5. 处理音频数据传输
    for {
        _, message, err := conn.ReadMessage()
        if err != nil {
            log.Fatal(err)
        }
        // 处理接收到的音频数据
        // ...
    }

}

type audioStreamer struct {
    buf    *bytes.Buffer
    stream beep.Streamer
}

func (a *audioStreamer) Stream(samples [][2]float64) (n int, ok bool) {
    d := make([]byte, len(samples)*4)
    if a.buf.Len() >= len(d) {
        a.buf.Read(d)
        ok = true
    }

    for i, s := range samples {
        s[0] = float64(int16(binary.LittleEndian.Uint16(d[i*4 : i*4+2]))) / 0x8000
    }
    n = len(samples)
    return
}

func (a *audioStreamer) Err() error {
    return nil
}

func (a *audioStreamer) Sample(samples [][2]float64) (n int, ok bool) {
    n, ok = a.stream.Stream(samples)
    a.buf.Write(make([]byte, n*4))
    for i, s := range samples[:n] {
        x := int16(s[0] * 0x8000)
        binary.LittleEndian.PutUint16(a.buf.Bytes()[i*4:i*4+2], uint16(x))
    }
    return
}
Nach dem Login kopieren

Im obigen Code wird zunächst ein Beep-Audiostream erstellt und ein Audioeingabestream mithilfe der Portaudio-Bibliothek erstellt, der vom Standard-Audioeingang übernommen wird Gerät Audioeingang abrufen. Als nächstes verwenden Sie die Resample-Bibliothek, um die aus dem Eingabestream erhaltenen Audiodaten erneut abzutasten, um sie an die während der Wiedergabe verwendete Audio-Abtastrate anzupassen. Abschließend starten Sie über die Lautsprecherbibliothek den Player, der die Audiodaten puffert und abspielt. Lesen Sie die Audiodaten in einer Schleife und schreiben Sie sie mithilfe der Sample-Funktion in den Audiostream.

  1. Audiodaten an den Server senden

Als nächstes verwenden Sie die WriteMessage-Funktion, um die aufgezeichneten Audiodaten an den Server zu senden, die Daten in mehrere Teile aufzuteilen und jeden Teil an andere Clients zu senden.

func main() {

    // ...录制音频并加入服务器

    // 1. 将音频数据分包(长度为4096)
    packSize := 4096
    maxPackCount := len(buf) / packSize
    for i := 0; i < maxPackCount+1; i++ {
        n := i * packSize
        l := min(len(buf)-n, packSize)
        if l > 0 {
            bufToWrite := buf[n : n+l]
            conn.WriteMessage(websocket.BinaryMessage, bufToWrite)
        }
    }

}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}
Nach dem Login kopieren

Teilen Sie im obigen Code zunächst die Audiodaten in der Buf-Variablen in mehrere Teile auf, und die Länge jedes Teils beträgt 4096. Anschließend wird jedes Audiodatenstück separat an andere Clients gesendet.

Zu diesem Zeitpunkt ist ein einfaches Voice-Chat-Programm fertiggestellt. Wenn Sie dieses Programm jedoch vollständiger und stabiler machen möchten, sind detailliertere Debugging- und Testarbeiten erforderlich. Die Verwendung von Golang zur Implementierung der Voice-Chat-Funktion ist jedoch ein interessantes und lohnenswertes Lernprojekt, und das obige Codebeispiel kann Anfängern einige grundlegende Referenzen bieten.

Das obige ist der detaillierte Inhalt vonGolang implementiert Voice-Chat. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage