Skip to content

Commit

Permalink
add go streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
SandraRodgers committed Jul 19, 2024
1 parent 2202a29 commit 4b032d7
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 1 deletion.
2 changes: 1 addition & 1 deletion documentation/update_languages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ languages:
# - "c"
# - "cpp"
# - "csharp"
# - "go"
- "go"
# - "java"
# - "javascript"
# - "php"
Expand Down
8 changes: 8 additions & 0 deletions languages/go/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Go

## Install Dependencies

Navigate to the root of the `go` folder and run the following command:

```bash
go mod tidy
```

## Update the Code

Replace the placeholder code such as `DEEPGRAM_API_KEY` with your own information.
Expand Down
2 changes: 2 additions & 0 deletions languages/go/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/deepgram-devs/code-samples/go

go 1.20

require github.com/gorilla/websocket v1.5.3
2 changes: 2 additions & 0 deletions languages/go/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
130 changes: 130 additions & 0 deletions languages/go/speech-to-text/streaming/remote/gorilla-websocket/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package main

import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"github.com/gorilla/websocket"
)

const (
authToken = "YOUR_DEEPGRAM_API_KEY" // Replace 'YOUR_DEEPGRAM_API_KEY' with your actual authorization token
wsURL = "wss://api.deepgram.com/v1/listen"
audioURL = "http://stream.live.vc.bbcmedia.co.uk/bbc_world_service"
)

type Response struct {
Type string `json:"type"`
Channel struct {
Alternatives []struct {
Transcript string `json:"transcript"`
} `json:"alternatives"`
} `json:"channel"`
}

func main() {
// Create HTTP headers with the authorization token
headers := http.Header{}
headers.Set("Authorization", "Token "+authToken)

// Set up a channel to capture interrupt signals for graceful shutdown
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)

// Establish a WebSocket connection to the Deepgram API
conn, _, err := websocket.DefaultDialer.Dial(wsURL, headers)
if err != nil {
log.Fatal("Dial:", err)
}
defer conn.Close()

// Create a channel to signal when the WebSocket connection is done
done := make(chan struct{})

// Start a goroutine to read messages from the WebSocket
go func() {
defer close(done)
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Println("Read:", err)
return
}
var response Response
if err := json.Unmarshal(message, &response); err != nil {
log.Printf("Error decoding JSON message: %v", err)
continue
}
if response.Type == "Results" && len(response.Channel.Alternatives) > 0 {
transcript := response.Channel.Alternatives[0].Transcript
if transcript != "" {
fmt.Println("Transcript:", transcript)
}
}
}
}()

// Start a goroutine to stream audio to the WebSocket
go func() {
if err := streamAudio(conn); err != nil {
log.Printf("Error streaming audio: %v", err)
conn.Close()
}
}()

// Wait for interrupt signal to gracefully close the WebSocket connection
for {
select {
case <-done:
return
case <-interrupt:
log.Println("Interrupt received, closing connection")
err := conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("Write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}

}
}

// streamAudio streams audio from a URL to the Deepgram API using a WebSocket connection
func streamAudio(conn *websocket.Conn) error {
resp, err := http.Get(audioURL)
if err != nil {
return fmt.Errorf("failed to open audio stream: %w", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to open audio stream: status code %d", resp.StatusCode)
}

buf := make([]byte, 4096)
for {
n, err := resp.Body.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return fmt.Errorf("failed to read audio stream: %w", err)
}
if err := conn.WriteMessage(websocket.BinaryMessage, buf[:n]); err != nil {
return fmt.Errorf("failed to send audio data: %w", err)
}
}
return nil
}

0 comments on commit 4b032d7

Please sign in to comment.