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:
Crie uma conta de serviço no Yandex com a função de editor
Crie um intervalo no armazenamento de objeto Yandex
Agora você pode prosseguir com a elaboração de um plano de trabalho:
Converter um arquivo do formato mp4 em áudio usando o utilitário ffmpeg
Envie o arquivo resultante para o depósito Yandex Service Object
Envie a resposta recebida com o endereço do arquivo no intervalo para o SpeechKit
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- 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.