テクノロジーの絶え間ない進歩に伴い、音声コミュニケーションは人々の生活に欠かせないものとなり、現在、ボイスチャットはインターネット上で最も一般的なコミュニケーション方法の 1 つとなっています。したがって、ユーザーが音声で簡単にコミュニケーションできるように、アプリケーションにボイスチャット機能を統合する必要があります。 Golang は非常に優れたプログラミング言語であり、効率、速度、信頼性の特性を備えているため、ボイスチャット機能を実装するのに golang を使用することは非常に良い選択となります。この記事ではgolangを使ってボイスチャット機能を実装する方法を紹介します。
1. 環境設定
ボイスチャット機能を実装する前に、お使いのコンピュータに golang 言語の開発環境をインストールする必要があります。インストール後、 go get コマンドを使用して、次のような音声関連ライブラリをインストールする必要があります。
これらのライブラリは、 go get コマンドを使用してすぐにインストールできます。たとえば、コマンド go get github.com/gordonklaus/portaudio を使用すると、PortAudio オーディオ ライブラリをインストールできます。
2. 導入プロセス
環境設定が完了したら、次はボイスチャット機能の具体的な実装プロセスです。まず、ユーザーが相互に通信できるようにクライアントとサーバーを作成する必要があります。接続が確立されると、クライアントはオーディオ データをサーバーに送信できるようになり、サーバーはそれを受信して他のクライアントに転送します。その後、他のクライアントはそのクライアントから音声データを受信して再生することができます。
サーバーを作成する最初のステップは、HTTP サービスを開始し、WebSocket 接続を作成することです。コードは次のとおりです:
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) } }
上記のコードでは、HTTP サービスが最初に開始され、ポート 8080 でリッスンされます。次に、WebSocket 接続が handleWebsocket 関数で作成されます。この関数は、リクエストがサーバーに送信されるたびに呼び出されます。最後に、オーディオ データの送信を処理するために、いくつかの単純な WebSocket 読み取りおよび書き込み操作が使用されます。
クライアントを作成する最初のステップはサーバーに参加することです。コードは次のとおりです:
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) } // 处理接收到的音频数据 // ... } }
上記のコードでは, まず、DefaultDialer.Dial 関数を使用して WebSocket 接続を作成し、サーバーにリンクします。次に、クライアントは単純な参加メッセージを使用して、クライアントがチャット ルームに参加したことをサーバーに伝えます。最後に、クライアントはループしてサーバーから送信された音声データを読み取り、データを処理します。
次のステップは最も重要なステップで、オーディオの録音と再生です。 Golang は、オーディオ処理に beep オーディオ ライブラリを使用し、多数のオーディオ プロセッサとエフェクトを提供します。ライブラリを使用してオーディオを録音する方法のコード例を次に示します。
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 }
上記のコードでは、最初にビープ音オーディオ ストリームが作成され、portaudio ライブラリを使用してオーディオ入力ストリームが作成されます。デフォルトはオーディオ入力デバイスからオーディオ入力を取得します。次に、リサンプル ライブラリを使用して入力ストリームから取得したオーディオ データをリサンプリングし、再生中に使用されるオーディオ サンプル レートに適応させます。最後に、スピーカー ライブラリを使用してプレーヤーを起動し、オーディオ データをバッファリングして再生します。ループ内でオーディオ データを読み取り、Sample 関数を使用してオーディオ ストリームに書き込みます。
次に、WriteMessage 関数を使用して、録音された音声データをサーバーに送信し、データを複数の部分に分割します。各パートはそれぞれ他のクライアントに送信されます。
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 }
上記のコードでは、まず buf 変数内の音声データを複数の部分に分割します。各部分の長さは 4096 です。その後、各音声データが他のクライアントに個別に送信されます。
これで、簡単なボイスチャットプログラムが完成しました。ただし、このプログラムをより完全で安定したものにしたい場合は、より詳細なデバッグとテストが必要です。ただし、golang を使用してボイス チャット機能を実装することは興味深く、試してみる価値のある学習プロジェクトであり、上記のコード サンプルは初心者向けの基本的なリファレンスとなります。
以上がGolangがボイスチャットを実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。