Um script ruby ​​que reconhece texto em um arquivo de vídeo usando o serviço Yandex SpeechKit Yandex (áudio longo)

Para começar, recentemente comecei a mergulhar em TI em geral e Ruby em particular, e recebi essa tarefa como um teste para conseguir uma vaga para um estágio. Direi antecipadamente que ainda há algo para suavizar e melhorar, mas em geral o código funciona.





No entanto, talvez minha experiência possa ser útil para alguém, então apresento a sua atenção uma descrição detalhada da criação deste script. IMPORTANTE: Meu sistema operacional é o Fedora 32, também uso o bundler pré-instalado no sistema. Portanto, se você também usa sistemas semelhantes ao Linux, continue lendo.





A essência da tarefa: existe um arquivo de vídeo no formato mp4, você precisa escrever um script em rubi puro, que irá converter esse arquivo em áudio, enviá-lo para o serviço Yandex SpeechKit Yandex e, ao receber a resposta, criar um arquivo texto.





Antes de começar a trabalhar, você deve estudar cuidadosamente a documentação do Yandex para armadilhas e nuances como o formato de áudio lido pelo Yandex (e, a propósito, existem apenas dois deles: OggOpus e LPCM).





Estágio preparatório:





Agora você pode prosseguir com a elaboração de um plano de trabalho:





  1. Converter um arquivo do formato mp4 em áudio usando o utilitário ffmpeg





  2. Envie o arquivo resultante para o depósito Yandex Service Object





  3. Envie a resposta recebida com o endereço do arquivo no intervalo para o SpeechKit





  4. Obtenha a resposta e converta-a em um arquivo de texto





A seguir, iremos percorrer os pontos com explicações de lugares interessantes (e nem sempre óbvios)





1. Converter um arquivo do formato mp4 para áudio usando o utilitário ffmpeg





Para formatar o arquivo de vídeo, instale o ffmpeg em nosso sistema





sudo dnf install ffmpeg







E, se ainda não o fez, coloque o arquivo de vídeo que precisa ser formatado na pasta do nosso pequeno projeto (no meu caso será test_task)





Na mesma pasta, crie um arquivo rubish (por exemplo, run.rb), no qual escreveremos um 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(' ')}") }







No total, temos três arquivos: .env (com variáveis ​​de ambiente), Gemfile (com três gems: httparty, aws-sdk-s3, dotenv), run.rb (com código).





Voila, você tem um pequeno script para formatar seu vídeo em texto.








All Articles