Un script ruby ​​que reconoce texto en un archivo de video usando el servicio Yandex SpeechKit Yandex (audio largo)

Para empezar, recientemente comencé a sumergirme en TI en general y Ruby en particular, y me dieron esta tarea como prueba para conseguir un lugar para una pasantía. Diré de antemano que todavía hay algo que suavizar y mejorar, pero en general el código funciona.





Sin embargo, tal vez mi experiencia pueda ser útil para alguien, por lo que presento a su atención una descripción detallada de la creación de este script. IMPORTANTE: Mi sistema operativo es Fedora 32, también utilizo el empaquetado preinstalado en el sistema. Entonces, si también usa sistemas similares a Linux, siga leyendo.





La esencia de la tarea: hay un archivo de video en formato mp4, debe escribir un script en ruby ​​puro, que convertirá este archivo en audio, lo enviará al servicio Yandex SpeechKit Yandex y, después de recibir la respuesta, creará un archivo de texto.





Antes de comenzar a trabajar, debe estudiar cuidadosamente la documentación de Yandex en busca de dificultades y matices como el formato de audio leído por Yandex (y, por cierto, solo hay dos de ellos: OggOpus y LPCM).





Etapa preparatoria:





Ahora puede proceder a la elaboración de un plan de trabajo:





  1. Conversión de un archivo de formato mp4 a audio con la utilidad ffmpeg





  2. Envíe el archivo resultante al depósito de objetos de servicio de Yandex





  3. Envíe la respuesta recibida con la dirección del archivo en el depósito a SpeechKit





  4. Obtenga la respuesta y conviértala en un archivo de texto





A continuación, nos moveremos por los puntos con explicaciones de lugares interesantes (y no siempre obvios)





1. Conversión de un archivo de formato mp4 a audio con la utilidad ffmpeg





Para formatear el archivo de video, instale ffmpeg en nuestro sistema





sudo dnf install ffmpeg







Y, si aún no lo ha hecho, coloque el archivo de video que requiere formatear en la carpeta de nuestro pequeño proyecto (en mi caso será test_task)





En la misma carpeta, cree un archivo rubish (por ejemplo, run.rb), en el que escribiremos un script:





touch run.rb







ruby (bash-, : system, exec, popen, ` `) (https://www.rubyguides.com/2018/12/ruby-system/)





` `:





`ffmpeg -i test.mp4 -vn -acodec libopus audio.ogg`





:





test.mp4 – .





‘-vn’ , , ( ).





libopus , SpeechKit OggOpus .





audio.ogg – , ( ogg)





, , .





2. Yandex Service Object





.





, , Yandex Object Storage ( ) .





Yandex Object Storage HTTP API, Amazon S3, , Amazon S3.





Amazon S3 aws-sdk-s3, Yandex Object Storage.





aws-sdk-s3. Gemfile :





 source 'https://rubygems.org'
 gem 'aws-sdk-s3'
      
      



gem 'aws-sdk-s3' :





bundle install







run.rb, :





require 'aws-sdk-s3'







.





API- .





: Object Storage Message Queue.





, - , dotenv. , .env , .





, Gemfile:





gem 'dotenv'







:





bundle install







:





require 'dotenv/load'







.env , :





AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXX

AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXX
      
      



. C aws, :





 Aws.config.update(

   region: 'ru-central1',

   credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])

 )
      
      



:





region: 'ru-central1',

   credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], 
   ENV['AWS_SECRET_ACCESS_KEY'])

 s3 = Aws::S3::Client.new(endpoint: "https://storage.yandexcloud.net")
      
      



, , . (, (puts pp), )





 File.open('audio.ogg', 'r') do |file|

   pp = s3.put_object({

     bucket: 'teststask',

     key: 'audio.ogg',

     body: file

   })

     puts pp

 end
      
      



run.rb ( ).





3. SpeechKit





http httparty (https://github.com/jnunemaker/httparty/blob/master/examples/basic.rb)





.





, Gemfile:





gem 'httparty'







:





bundle install







:





require 'httparty'







.





, , . , , : https://storage.yandexcloud.net/<->/<-->





, :





https://storage.yandexcloud.net/teststask/audio.ogg







, , )) !





post SpeechKit.





, API- , . .





: API- (API- IAM-)





options.





 options = {

   headers: {"Authorization" => "Api-Key #{ENV['API_KEY']}"},

   body: {

     "config" => {

         "specification" => {

             "languageCode" => "ru-RU"

         }

     },

     "audio" => {

         "uri" => "https://storage.yandexcloud.net/teststask/audio.ogg"

     }

   }.to_json

 }
      
      







 response = HTTParty.post('https://transcribe.api.cloud.yandex.net/speech/stt/v2/longRunningRecognize', options).to_h
      
      







, .





.





:





 option = {

    headers: {"Authorization" => "Api-Key #{ENV['API_KEY']}"}

 }
      
      



, , , . ( #{response['id']} "https://operation.api.cloud.yandex.net/operations/#{response['id']}").





2 , , )





 done = false

 until done

   yandex_answer = HTTParty.get("https://operation.api.cloud.yandex.net/operations/#{response['id']}", option).to_h

   puts yandex_answer

   done = yandex_answer['done']

   sleep 2

 end
      
      







4.





ruby, . :





 yandex_array = yandex_answer["response"]["chunks"]

 yandex_text = [] 

 yandex_array.each do |elem|

   yandex_text << elem["alternatives"].first["text"]

 end
      
      







pp yandex_text.uniq!







bash- :





`touch test.txt`







:





File.open("test.txt", 'w') { |file| file.write(":#{yandex_text.join(' ')}") }







En total, tenemos tres archivos: .env (con variables de entorno), Gemfile (con tres gemas: httparty, aws-sdk-s3, dotenv), run.rb (con código).





Listo, tienes un pequeño guión para formatear tu video a texto.








All Articles