2017-10-09 86 views
8

Git'i kullanarak, bir RTMP akışı alıyorum, FLAC (ffmpeg kullanarak) kodlamasını yapıyorum ve sesi yazmak için Google'ın Konuşma API'sine akış yapmaya çalışıyorum. Ancak, verileri gönderirken EOF hatalarını almaya devam ediyorum. Bu hata hakkında dokümanlardaki hiçbir bilgiyi bulamıyorum, bu yüzden neden kaynaklandığından emin değilim.Google Speech - Akış İsteği İadeler EOF Hatası

Alınan verileri 3'lü kliplere ayırıyorum (uzunluk, bir akış tanıma isteğinin maksimum uzunluğundan daha az olduğu sürece alakalı değildir). İşte

benim kod çekirdeğidir: tüm Send s başarısız

2017/10/09 16:05:00 Received 191704 bytes 
2017/10/09 16:05:00 Saving 191704 bytes 
2017/10/09 16:05:00 Sending 191704 bytes 
2017/10/09 16:05:00 Could not send audio: EOF 

2017/10/09 16:05:03 Received 193192 bytes 
2017/10/09 16:05:03 Saving 193192 bytes 
2017/10/09 16:05:03 Sending 193192 bytes 
2017/10/09 16:05:03 Could not send audio: EOF 

2017/10/09 16:05:06 Received 193188 bytes 
2017/10/09 16:05:06 Saving 193188 bytes 
2017/10/09 16:05:06 Sending 193188 bytes // Notice that this doesn't error 

2017/10/09 16:05:09 Received 191704 bytes 
2017/10/09 16:05:09 Saving 191704 bytes 
2017/10/09 16:05:09 Sending 191704 bytes 
2017/10/09 16:05:09 Could not send audio: EOF 

Bildirimi:

func main() { 

    done := make(chan os.Signal) 
    received := make(chan []byte) 

    go receive(received) 
    go transcribe(received) 

    signal.Notify(done, os.Interrupt, syscall.SIGTERM) 

    select { 
    case <-done: 
     os.Exit(0) 
    } 
} 

func receive(received chan<- []byte) { 
    var b bytes.Buffer 
    stdout := bufio.NewWriter(&b) 

    cmd := exec.Command("ffmpeg", "-i", "rtmp://127.0.0.1:1935/live/key", "-f", "flac", "-ar", "16000", "-") 
    cmd.Stdout = stdout 

    if err := cmd.Start(); err != nil { 
     log.Fatal(err) 
    } 

    duration, _ := time.ParseDuration("3s") 
    ticker := time.NewTicker(duration) 

    for { 
     select { 
     case <-ticker.C: 
      stdout.Flush() 
      log.Printf("Received %d bytes", b.Len()) 
      received <- b.Bytes() 
      b.Reset() 
     } 
    } 
} 

func transcribe(received <-chan []byte) { 
    ctx := context.TODO() 

    client, err := speech.NewClient(ctx) 
    if err != nil { 
     log.Fatal(err) 
    } 

    stream, err := client.StreamingRecognize(ctx) 
    if err != nil { 
     log.Fatal(err) 
    } 

    // Send the initial configuration message. 
    if err = stream.Send(&speechpb.StreamingRecognizeRequest{ 
     StreamingRequest: &speechpb.StreamingRecognizeRequest_StreamingConfig{ 
      StreamingConfig: &speechpb.StreamingRecognitionConfig{ 
       Config: &speechpb.RecognitionConfig{ 
        Encoding:  speechpb.RecognitionConfig_FLAC, 
        LanguageCode: "en-GB", 
        SampleRateHertz: 16000, 
       }, 
      }, 
     }, 
    }); err != nil { 
     log.Fatal(err) 
    } 

    for { 
     select { 
     case data := <-received: 
      if len(data) > 0 { 
       log.Printf("Sending %d bytes", len(data)) 
       if err := stream.Send(&speechpb.StreamingRecognizeRequest{ 
        StreamingRequest: &speechpb.StreamingRecognizeRequest_AudioContent{ 
         AudioContent: data, 
        }, 
       }); err != nil { 
        log.Printf("Could not send audio: %v", err) 
       } 
      } 
     } 
    } 
} 

Bu kod çalıştırma bu çıktıyı verir.

Buraya kimse bana doğru yönde işaret edebilir mi? FLAC başlıklarıyla veya başka bir şeyle ilgisi var mı? Ayrıca, arabelleği sıfırlamanın bazı verilerin düşmesine neden olup olmadığına da merak ediyorum (yani, gerçekten bitmesi biraz zaman alan, önemsiz bir işlemdir) ve bu eksik bilgileri beğenmiyor mu?

Herhangi bir yardım gerçekten takdir edilecektir.

+1

Bu tamamen rastgele bir yoldur, ancak yarış dedektörü ile çalıştırmayı denediniz mi? Muhtemelen hiçbir şey göstermeyecek, ama asla bilemezsiniz ... –

+0

@MiloChristiansen iyi bir çağrı! Bir yarış durumu var. 'Bufio.Writer' parçacığı için güvenli bir sürüm oluşturmaya çalıştım ancak kitaplık sürekli okuyucuyu okuyan 'ReadFrom' işlevini kullanıyor. Sadece her şey okunduğunda kilidi serbest bırakır: - / – Josh

cevap

7

Bu nedenle, akışın durumu hakkında daha fazla bilgi edinmenin bir yolu olduğu için, yalnızca döndürülen hataya güvenmek zorunda kalmıyoruz.

if err := stream.Send(&speechpb.StreamingRecognizeRequest{ 
    StreamingRequest: &speechpb.StreamingRecognizeRequest_AudioContent{ 
     AudioContent: data, 
    }, 
}); err != nil { 
    resp, err := stream.Recv() 
    log.Printf("Could not send audio: %v", resp.GetError()) 
} 

Bu baskılar:

çok daha yararlı hata mesajı
2017/10/16 17:14:53 Could not send audio: code:3 message:"Invalid audio content: too long." 

!