1

Je développe un bot qui recevra de la voix (à partir du canal facebook) et le convertira en .wav.Comment convertir la voix au format .wav et comment l'utiliser

J'utilise un échantillon de: How can a bot receive a voice file from Facebook Messenger (MP4) and convert it to a format that is recognized by speech engines like Bing or Google?

J'ai eu un problème lors de la conversion, je pense.

Voici mon code:

messagescontroller.cs:

namespace SpeechToText.Controllers 
{ 
using System; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Threading.Tasks; 
using System.Web.Http; 
using Microsoft.Bot.Connector; 
using Services; 
using System.Web.Configuration; 
using System.IO; 

[BotAuthentication] 
public class MessagesController : ApiController 
{ 
    private readonly MicrosoftCognitiveSpeechService speechService = new MicrosoftCognitiveSpeechService(); 

    /// <summary> 
    /// POST: api/Messages 
    /// Receive a message from a user and reply to it 
    /// </summary> 
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity) 
    { 
     if (activity.Type == ActivityTypes.Message) 
     { 
      var connector = new ConnectorClient(new Uri(activity.ServiceUrl)); 

      string message = string.Empty; 
      IncomingFacebookVoiceMessage voice = null; 

      try 
      { 
       voice = new IncomingFacebookVoiceMessage(activity); 
       //await SendReply(activity, "The type of your voice file is " + voice.ContentType); 
      } 
      catch 
      { 
       message = "Send me a voice message instead!"; // no voice file found 
      } 

      try 
      { 
       if (voice != null) 
       { 
        //Download original MP4 voice message 
        voice.DownloadFile(); 
        var mp4 = voice.GetLocalPathAndFileName(); 

        //Convert MP4 to WAV 
        // var wavFolder = Utils.GetHomeFolder() + WebConfigurationManager.AppSettings["WAVFilesFolder"]; 

        var wavFolder = "C:" + @"\" + "Teste" ; 
        var converter = new AudioFileFormatConverter(mp4, wavFolder); 
        var wav = converter.ConvertMP4ToWAV(); 

        //Convert .WAV file to text 
        var bing = new MicrosoftCognitiveSpeechService(); //gets the path + filename 
                     // var text = await bing.GetTextFromAudioAsync(wav); //takes path+filename to WAV file, returns text 

        // convert string to stream 
        byte[] data = File.ReadAllBytes(wav); 
        //byte[] byteArray = Encoding.ASCII.GetBytes(contents); 
        MemoryStream stream = new MemoryStream(data); 

        var text = await this.speechService.GetTextFromAudioAsync(stream); 

        if (string.IsNullOrWhiteSpace(text)) 
        { 
         message = "Looks like you didn't say anything."; 
        } 
        else 
        { 
         message = text; 
        } 

        //Clean up files from disk 
        voice.RemoveFromDisk(); 
        converter.RemoveTargetFileFromDisk(); 
       } 
      } 
      catch (Exception ex) 
      { 
       message = "Woah! " + ex.Message.Trim().Trim('.') + "!"; 
      } 

      Activity reply = activity.CreateReply(message); 
      await connector.Conversations.ReplyToActivityAsync(reply); 
     } 
     else 
     { 
      await this.HandleSystemMessage(activity); 
     } 

     return Request.CreateResponse(HttpStatusCode.OK); 
    } 



    /// <summary> 
    /// Gets the JwT token of the bot. 
    /// </summary> 
    /// <param name="connector"></param> 
    /// <returns>JwT token of the bot</returns> 


    /// <summary> 
    /// Handles the system activity. 
    /// </summary> 
    /// <param name="activity">The activity.</param> 
    /// <returns>Activity</returns> 
    private async Task<Activity> HandleSystemMessage(Activity activity) 
    { 
     switch (activity.Type) 
     { 
      case ActivityTypes.DeleteUserData: 
       // Implement user deletion here 
       // If we handle user deletion, return a real message 
       break; 
      case ActivityTypes.ConversationUpdate: 
       // Greet the user the first time the bot is added to a conversation. 
       if (activity.MembersAdded.Any(m => m.Id == activity.Recipient.Id)) 
       { 
        var connector = new ConnectorClient(new Uri(activity.ServiceUrl)); 

        var response = activity.CreateReply(); 
        response.Text = "Hi! I am SpeechToText Bot. I can understand the content of any audio and convert it to text. Try sending me a wav file."; 

        await connector.Conversations.ReplyToActivityAsync(response); 
       } 

       break; 
      case ActivityTypes.ContactRelationUpdate: 
       // Handle add/remove from contact lists 
       break; 
      case ActivityTypes.Typing: 
       // Handle knowing that the user is typing 
       break; 
      case ActivityTypes.Ping: 
       break; 
     } 

     return null; 
    } 
    } 
    } 

IncomingFacebookVoiceMessage.cs --------------------

using Microsoft.Bot.Connector; 
using System; 
    using System.Collections.Generic; 
    using System.IO; 
using System.Linq; 
    using System.Net; 
using System.Web; 
    using System.Web.Configuration; 


namespace SpeechToText 
{ 
/// <summary> 
/// Represents an incoming voice message from facebook messenger, 
/// where the voice data is in an MP4 file (the message contains a link to 
download it). 
/// </summary> 
public class IncomingFacebookVoiceMessage 
{ 
    #region Properties 
    /// <summary> 
    /// URL of the MP4 file sent by user and stored on facebook's servers. 
    /// </summary> 
    public Uri MP4FileUrl { get; private set; } 

    /// <summary> 
    /// Local filename of the MP4 file after it has been downloaded from Facebook. 
    /// </summary> 
    private string MP4LocalFileName { get; set; } 

    /// <summary> 
    /// Path to the folder on local disk containing the downloaded voice messages from Facebook. 
    /// This is configured in Web.config using the FacebookDownloadedVoiceMessagesFolder key. 
    /// The path in the Web.config will be relative to the site's root folder. 
    /// </summary> 
    public string VoiceMessageFolder { get; private set; } 

    /// <summary> 
    /// Content-type of the attachment (for debugging - it's not always MP4). 
    /// </summary> 
    public string ContentType { get; private set; } 
    #endregion 

    #region Constructors 
    /// <summary> 
    /// Constructor that uses an MP4 file link that is 
    /// received in activity.Attachments by bot framework. 
    /// </summary> 
    /// <param name="MP4FileUrl">URL of the MP4 file sent by user and stored on facebook's servers.</param> 
    public IncomingFacebookVoiceMessage(string MP4FileUrl) 
    { 
     if (string.IsNullOrWhiteSpace(MP4FileUrl)) 
     { 
      throw new Exception("The MP4 file URL was empty."); 
     } 

     this.MP4FileUrl = new Uri(MP4FileUrl); 
     this.VoiceMessageFolder = GetVoiceMessagesFolderFromWebConfig(); 
    } 

    /// <summary> 
    /// A shortcut constructor that extracts the URL of the MP4 voice message file 
    /// from the Activity object received by the controller in the Bot Framework. 
    /// </summary> 
    /// <param name="activity">The Activity object that contains an attachment of type video/mp4. If no attachment, throws an exception.</param> 
    public IncomingFacebookVoiceMessage(IMessageActivity activity) 
    { 
     var mp4Attachment = activity.Attachments?.FirstOrDefault(a => a.ContentType.Equals("video/mp4") || a.ContentType.Contains("audio") || a.ContentType.Contains("video")); 
     if (mp4Attachment == null) 
     { 
      throw new Exception("The message didn't have a voice attachment."); 
     } 
     else 
     { 
      this.MP4FileUrl = new Uri(mp4Attachment.ContentUrl); 
      this.VoiceMessageFolder = GetVoiceMessagesFolderFromWebConfig(); 
      this.ContentType = mp4Attachment.ContentType; //for debugging. Different devices send different content-types, e.g. audio/aac and video/mp4 
     } 
    } 
    #endregion 

    #region Public methods 
    /// <summary> 
    /// Downloads the MP4 file containing the voice message from Facebook. 
    /// </summary> 
    /// <returns>The filename (without path) of the MP4 file stored on local disk.</returns> 
    public string DownloadFile() 
    { 
     var filename = GetRandomFileName(); 
     var filenameWithPath = VoiceMessageFolder + @"\" + filename; 

     //if folder doesn't exist, create it 
     if (!Directory.Exists(VoiceMessageFolder)) 
     { 
      Directory.CreateDirectory(VoiceMessageFolder); 
     } 

     using (var client = new WebClient()) 
     { 
      client.DownloadFile(this.MP4FileUrl, filenameWithPath); 
     } 

     MP4LocalFileName = filename; 

     return filename; 
    } 

    /// <summary> 
    /// Removes the downloaded MP4 file from the local disk to clean up space. 
    /// </summary> 
    /// <returns>True if successfully removed, false otherwise.</returns> 
    public bool RemoveFromDisk() 
    { 
     try 
     { 
      File.Delete(GetLocalPathAndFileName()); 
      return true; 
     } 
     catch 
     { 
      return false; 
     } 
    } 

    /// <summary> 
    /// Returns the full local path and filename to the downloaded MP4 voice message. 
    /// </summary> 
    /// <returns>E.g. D:\home\site\wwwroot\abc.mp4</returns> 
    public string GetLocalPathAndFileName() 
    { 
     if (string.IsNullOrWhiteSpace(MP4LocalFileName)) 
     { 
      throw new Exception("The voice message has not been downloaded yet."); 
     } 

     return VoiceMessageFolder + @"\" + MP4LocalFileName; 
    } 

    #endregion 

    #region Private methods 
    /// <summary> 
    /// Reads Web.config and returns the path to the folder which will store downloaded messages. 
    /// The folder in the config must be relative to the site's root. 
    /// </summary> 
    /// <returns>Full path to the folder that will be used to store MP4 voice messages.</returns> 
    private string GetVoiceMessagesFolderFromWebConfig() 
    { 
     //return Utils.GetHomeFolder() + WebConfigurationManager.AppSettings["FacebookDownloadedVoiceMessagesFolder"]; 
     return "C:" + @"\" + "Teste" ; 
    } 

    /// <summary> 
    /// Generates a random filename using a new GUID. 
    /// </summary> 
    /// <returns>A random file name in the format "msg-GUID.mp4".</returns> 
    private string GetRandomFileName() 
    { 
     return "msg-" + Guid.NewGuid() + ".mp4"; 
    } 
    #endregion 
    } 
    } 

AudioFileFormatConverter.cs ---------------

using MediaToolkit; 
using MediaToolkit.Model; 
using System; 
    using System.IO; 
using System.Web.Configuration; 

    namespace SpeechToText 
    { 
/// <summary> 
/// Converts audio files between various formats using the open-source 
    FFMPEG software. 
/// </summary> 
public class AudioFileFormatConverter 
{ 
    #region Properties 
    /// <summary> 
    /// Path + filename to the source file. 
    /// </summary> 
    public string SourceFileNameAndPath { get; private set; } 

    /// <summary> 
    /// Path + filename to the file which is the result of the conversion. 
    /// </summary> 
    public string ConvertedFileNameAndPath { get; private set; } 

    /// <summary> 
    /// The folder where the converted files will be stored. 
    /// </summary> 
    public string TargetPath { get; private set; } 

    #endregion 

    #region Constructors 
    /// <summary> 
    /// Default constructor. 
    /// </summary> 
    /// <param name="sourceFileNameAndPath">Filename and path to the source 
     file.</param> 
    /// <param name="targetPath">The folder where the converted files will 
     be stored.</param> 
    public AudioFileFormatConverter(string sourceFileNameAndPath, string 
    targetPath) 
    { 
     if (string.IsNullOrWhiteSpace(sourceFileNameAndPath)) 
     { 
      throw new Exception("Empty source filename."); 
     } 
     else if (string.IsNullOrWhiteSpace(targetPath)) 
     { 
      throw new Exception("Empty target path."); 
     } 
     else 
     { 
      this.SourceFileNameAndPath = sourceFileNameAndPath; 
      this.TargetPath = targetPath; 

      //create folder if it's not there 
      if (!Directory.Exists(TargetPath)) 
      { 
       Directory.CreateDirectory(TargetPath); 
      } 
     } 
    } 
    #endregion 

    #region Public methods 
    /// <summary> 
    /// Converts a source MP4 file to a target WAV file and returns the path 
    and filename of the converted file. 
    /// </summary> 
    /// <returns>The path and filename of the converted file.</returns> 
    public string ConvertMP4ToWAV() 
    { 
     ConvertedFileNameAndPath = TargetPath + @"\" + 
     Path.GetFileNameWithoutExtension(SourceFileNameAndPath) + ".wav"; 
     //use the same 
    file name as original, but different folder and extension 

     var inputFile = new MediaFile { Filename = SourceFileNameAndPath }; 
     var outputFile = new MediaFile { Filename = ConvertedFileNameAndPath 
     }; 
     using (var engine = new Engine(GetFFMPEGBinaryPath())) 
     { 
      engine.Convert(inputFile, outputFile); 
     } 

     return ConvertedFileNameAndPath; 
    } 

    /// <summary> 
    /// Removes the converted file from disk to free up space. 
    /// Doesn't remove the source file. 
    /// </summary> 
    /// <returns>True if file deleted successfully, false if cannot delete, 
    exception if filename is empty.</returns> 
    public bool RemoveTargetFileFromDisk() 
    { 
     if (string.IsNullOrWhiteSpace(ConvertedFileNameAndPath)) 
     { 
      throw new Exception("The file has not been converted yet, so it cannot be deleted."); 
     } 

     try 
     { 
      File.Delete(ConvertedFileNameAndPath); 
      return true; 
     } 
     catch 
     { 
      return false; 
     } 
    } 
    #endregion 

    #region Private methods 
    /// <summary> 
    /// Reads the config to determine the location of ffmpeg.exe. 
    /// </summary> 
    /// <returns>The full path and filename to the ffmpeg.exe program. 
    </returns> 
    public string GetFFMPEGBinaryPath() 
    { 
     // return Utils.GetHomeFolder() + 
    WebConfigurationManager.AppSettings["FFMPEGBinaryLocation"]; 
     return "D:" + @"\" + "Teste"; 
    } 
    #endregion 
    } 
    } 

Voici mon message de sortie:

enter image description here

Pouvez-vous s'il vous plaît aidez-moi comment résoudre le problème ... où je dois stocker le registre audio dans messenger facebook?

+0

Avez-vous chroniqués: https://github.com/catcher-in-the-try/Facebook-Messenger-Voice-Message-Converter –

+0

double possible de [Comment convertir un fichier .wav .mp3 format dans botframework] (https://stackoverflow.com/questions/46492024/how-to-convert-a-wav-file-to-mp3-format-in-botframework) –

+0

Il pourrait être préférable de changer le nom de ' GetRandomFileName() 'et l'appelle' GetUniqueFileName() 'comme' NewGuid() 'ne produit pas de valeurs aléatoires, il produit des valeurs uniques. – Enigmativity

Répondre

0

Je pense que tout ce qui vous manque est ffmpeg.exe dans la méthode GetFFMPEGBinaryPath(). Une fois que j'ai ajouté cela à la fin du chemin, le code que vous avez fonctionne comme prévu.

public string GetFFMPEGBinaryPath() 
{ 
    return "D:" + @"\Teste\ffmpeg-20170921-183fd30-win64-static\bin\ffmpeg.exe"; 
}