package speech import ( "context" "github.com/flowy-live/llink/internal/utils/flog" dgapi "github.com/deepgram/deepgram-go-sdk/v3/pkg/api/listen/v1/rest" interfaces "github.com/deepgram/deepgram-go-sdk/v3/pkg/client/interfaces" client "github.com/deepgram/deepgram-go-sdk/v3/pkg/client/listen" ) type TranscriptWord struct { Word string Start float64 End float64 } type TranscriptSentence struct { Text string Start float64 End float64 } type TranscriptParagraph struct { Sentences []TranscriptSentence Start float64 End float64 } type TranscriptResult struct { Transcript string Words []TranscriptWord Paragraphs []TranscriptParagraph } type SpeechService interface { Transcribe(ctx context.Context, mediaUrl string) (*TranscriptResult, error) } type speechServiceImpl struct { deepgramClient *dgapi.Client } func NewSpeechService(ctx context.Context) SpeechService { return &speechServiceImpl{ deepgramClient: dgapi.New(client.NewRESTWithDefaults()), } } func (s *speechServiceImpl) Transcribe(ctx context.Context, mediaUrl string) (*TranscriptResult, error) { options := &interfaces.PreRecordedTranscriptionOptions{ Model: "nova-3", SmartFormat: true, Paragraphs: true, } response, err := s.deepgramClient.FromURL(ctx, mediaUrl, options) if err != nil { flog.Error("failed to transcribe prerecorded media", "error", err) return nil, err } alt := response.Results.Channels[0].Alternatives[0] words := make([]TranscriptWord, len(alt.Words)) for i, w := range alt.Words { words[i] = TranscriptWord{ Word: w.PunctuatedWord, Start: w.Start, End: w.End, } } var paragraphs []TranscriptParagraph if alt.Paragraphs != nil { paragraphs = make([]TranscriptParagraph, len(alt.Paragraphs.Paragraphs)) for i, p := range alt.Paragraphs.Paragraphs { sentences := make([]TranscriptSentence, len(p.Sentences)) for j, s := range p.Sentences { sentences[j] = TranscriptSentence{ Text: s.Text, Start: s.Start, End: s.End, } } paragraphs[i] = TranscriptParagraph{ Sentences: sentences, Start: p.Start, End: p.End, } } } return &TranscriptResult{ Transcript: alt.Transcript, Words: words, Paragraphs: paragraphs, }, nil }