Search code examples
rshinywatson

Shiny Watson text to speech real time


library(shiny)
library(cognizer)


#' the required api keys 
username_TTS <-""
password_TTS <- ""
TEXT_TO_SPEECH_USERNAME_PASSWORD = paste(username_TTS,":",password_TTS,sep="")

ui <- fluidPage(

   # Application title
   titlePanel("Just some text to speech example"),

   fluidRow(textInput("caption","Enter the caption"),actionButton("gobutton","submit")),
   fluidRow(verbatimTextOutput("answer"), width = 4),

  # plays from www/  
  fluidRow(tags$audio(src = "1.wav", type = "audio/wav", controls = NA), helpText("Key in any sentences, wait and press F5. Then you can play your audio"))


  )



server <- function(input, output) {

textfunction <- eventReactive(input$gobutton, {
    thetext <- input$caption
    text_audio(thetext, TEXT_TO_SPEECH_USERNAME_PASSWORD, directory = 'www', accept = "audio/wav")
    "Done!"

        })


output$answer <- renderText({textfunction()})


}

# Run the application 
shinyApp(ui = ui, server = server)

I created an app using Watson to convert text to speech. The user input a text sentence. Click submit and watson will convert the to audio file. HOWEVER, the audio file played is is always the previous text, unless you refresh the app via F5. How can i make the audio player take the latest audio file?

example: text1: hello submit and play will be "hello" text2: bye submit and play, still "hello" until i F5, then when i click play, its "bye"


Solution

  • The problem is related to Shiny's caching of the audio file. A workaround, as described here, can help you:

    Rename the wav file after it is queried and pass it into a reactive UI component using renderUI() on the server side and uiOutput() in the UI.

    Please see a working example below:

    library(shiny)
    library(cognizer)
    
    # the required api keys
    username_TTS <-""
    password_TTS <- ""
    TEXT_TO_SPEECH_USERNAME_PASSWORD = paste(username_TTS,":",password_TTS,sep="")
    
    ui <- fluidPage(
    
      # Application title
      titlePanel("Just some text to speech example"),
    
      fluidRow(textInput("caption","Enter the caption"),actionButton("gobutton","submit")),
      fluidRow(verbatimTextOutput("answer"), width = 4),
    
      # plays from www/
      fluidRow(
        uiOutput("play")
      )
    )
    
    server <- function(input, output) {
      observeEvent(input$gobutton, {
        unlink("www/*.wav")
        thetext <- input$caption
        text_audio(thetext, TEXT_TO_SPEECH_USERNAME_PASSWORD, directory = 'www', accept = "audio/wav")
        file.rename("www/1.wav", paste0("www/number",input$gobutton,".wav"))
        "Done!"
        output$play <- renderUI(
          tags$audio(src = paste0("temp.wav"), type = "audio/wav", controls = NA)
        )
        output$play <- renderUI(
          tags$audio(src = paste0("number", input$gobutton,".wav"), type = "audio/wav", controls = NA)
        )
        output$answer <- renderText(paste("Done!", input$gobutton))
      })
    }
    
    # Run the application
    shinyApp(ui = ui, server = server)