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:
Cree una cuenta de servicio en Yandex con el rol de editor
Cree un depósito en Yandex Object Storage
Ahora puede proceder a la elaboración de un plan de trabajo:
Conversión de un archivo de formato mp4 a audio con la utilidad ffmpeg
Envíe el archivo resultante al depósito de objetos de servicio de Yandex
Envíe la respuesta recibida con la dirección del archivo en el depósito a SpeechKit
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- 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.