1

J'essaie de lire un fichier audio avec un format de chaîne binaire renvoyé par Amazon Polly. Pour cela, j'utilise 'react-native-fetch-blob' et je lis un flux, mais j'obtiens toujours des erreurs du pont en disant 'Invalid data message - tout doit être de longueur: 8'. Il arrive quand je tente d'ouvrir le flux:Réagir Native. MP3 Binary String (Uint8Array (9549)) pour diffuser ou enregistrer

Voici le code:

//polly config 
const params = { 
    LexiconNames: [], 
    OutputFormat: "mp3", 
    SampleRate: "8000", 
    Text: "All Gaul is divided into three parts", 
    TextType: "text", 
    VoiceId: "Joanna" 
}; 

Polly.synthesizeSpeech(params, function(err, data) { 
    let _data = ""; 
    RNFetchBlob.fs.readStream(
     // file path 
     data.AudioStream, 
     // encoding, should be one of `base64`, `utf8`, `ascii` 
     'ascii' 
    ) 
    .then((ifstream) => { 
     ifstream.open() 
     ifstream.onData((chunk) => { 
      _data += chunk 
     }) 
     ifstream.onError((err) => { 
      console.log('oops', err.toString()) 
     }) 
     ifstream.onEnd(() => { 
      //pasing _data to streaming player or normal audio player 
      ReactNativeAudioStreaming.play(_data, {showIniOSMediaCenter: true, showInAndroidNotifications: true}); 
     }) 
    }) 
}); 

Une autre solution, j'ai aussi essayé est d'enregistrer le flux dans un fichier pour le charger plus tard, mais je eu des bugs similaires. RNFetchBlob.fs.createFile("myfile.mp3", dataG.AudioStream, 'ascii');

merci énormes à l'avance

+0

Où '_data' est-il défini? Pouvez-vous inclure le chemin d'accès complet au fichier audio à Question? – guest271314

+0

Pourquoi demandez-vous un 'Blob' si vous attendez de lire un flux de' Uint8Array's en morceaux? – guest271314

+0

@ guest271314 Merci de votre aide à ce sujet. – user2956369

Répondre

0

Vous pouvez utiliser fetch() pour demander une ou plusieurs ressources, le retour des médias Response.body.getReader() de .then() pour obtenir un ReadableStream de la réponse. Lire les Uint8Array valeurs renvoyées en tant que flux lu avec la méthode .read() du ReadableStream, ajouter à valeur à SourceBuffer de MediaSource pour diffuser le média à HTMLMediaElement.

Par exemple, la sortie audio de deux ressources audio demandées, dans l'ordre

window.addEventListener("load",() => { 

    const audio = document.createElement("audio"); 

    audio.controls = "controls"; 

    document.body.appendChild(audio); 

    audio.addEventListener("canplay", e => { 
    audio.play(); 
    }); 

    const words = ["hello", "world"]; 

    const mediaSource = new MediaSource(); 

    const mimeCodec = "audio/mpeg"; 

    const mediaType = ".mp3"; 

    const url = "https://ssl.gstatic.com/dictionary/static/sounds/de/0/"; 

    Promise.all(
     words.map(word => 
     fetch(`https://query.yahooapis.com/v1/public/yql?q=select * from data.uri where url="${url}${word}${mediaType}"&format=json&callback=`) 
     .then(response => response.json()) 
     .then(({ 
      query: { 
       results: { 
       url 
       } 
      } 
      }) => 
      fetch(url).then(response => response.body.getReader()) 
      .then(readers => readers) 
     ) 
    ) 
    ) 
    .then(readers => { 

     audio.src = URL.createObjectURL(mediaSource); 
     mediaSource.addEventListener("sourceopen", sourceOpen); 

     async function sourceOpen() { 
     var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec); 
     // set `sourceBuffer` `.mode` to `"sequence"` 
     sourceBuffer.mode = "segments"; 

     const processStream = ({ 
      done, 
      value 
     }) => { 
      if (done) { 
      return; 
      } 
      // append chunk of stream to `sourceBuffer` 
      sourceBuffer.appendBuffer(value); 
     } 
     // at `sourceBuffer` `updateend` call `reader.read()`, 
     // to read next chunk of stream, append chunk to 
     // `sourceBuffer` 
     for (let [index, reader] of Object.entries(readers)) { 
      sourceBuffer.addEventListener("updateend", function() { 
      reader.read().then(processStream); 
      }); 

      let stream = await reader.read().then(processStream) 
      .then(() => reader.closed) 
      .then(() => "done reading stream " + index); 

      console.log(stream); 
     } 

     } 
    }) 
}) 

plnkr http://plnkr.co/edit/9zHwmcdG3UKYMghD0w3q?p=preview

+0

Malheureusement, ce code ne fonctionnera pas sur React Native en raison de l'absence de 'SourceBuffer' et de la prise en charge de' Uint8Array' – user2956369

+0

@ user2956369 Pourquoi avez-vous besoin d'utiliser React Native? – guest271314

+0

Ceci est le code est une application native mobile, que React Native le compile dans un ensemble JS, ce n'est pas standard JS. – user2956369

0

Vous pouvez utiliser la méthode getSynthesizeSpeechUrl de AWS.Polly.Presigner. Je fais cela et j'utilise le son natif de la réaction pour jouer le mp3. J'ai rencontré un problème où le mp3 ne jouerait pas parce que mon URL prédéfinie contenait des caractères spéciaux, mais il y a un fix here.