Class: OllamaChat::ASR
- Inherits:
-
Object
- Object
- OllamaChat::ASR
- Defined in:
- lib/ollama_chat/asr.rb
Class Method Summary collapse
-
.multipart_form_data(file_path, **rest) ⇒ Hash
private
Builds a multipart/form-data request body for the ASR endpoint.
-
.transcribe(source_io, chat:, language: nil) ⇒ String?
Transcribes audio/video content via the audio.cpp ASR endpoint.
Class Method Details
.multipart_form_data(file_path, **rest) ⇒ Hash (private)
Builds a multipart/form-data request body for the ASR endpoint.
Constructs the wire format manually (boundary, text field parts, file part) so the result can be splatted directly into HTTPHandling#request_url_response.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/ollama_chat/asr.rb', line 83 def multipart_form_data(file_path, **rest) path = Pathname.new(file_path) body = '' boundary = SecureRandom.hex(8) rest.compact.each do |field_name, field_value| body << "--#{boundary}\r\n" body << "Content-Disposition: form-data; name=\"#{field_name}\"\r\n\r\n" body << "#{field_value}\r\n" end body << "--#{boundary}" << Excon::CR_NL body << %{Content-Disposition: form-data; name="file"; filename="#{path.basename}"} << Excon::CR_NL body << 'Content-Type: audio/wav' << Excon::CR_NL body << Excon::CR_NL body << path.binread body << Excon::CR_NL body << "--#{boundary}--" << Excon::CR_NL { headers: { 'Content-Type' => %{multipart/form-data; boundary="#{boundary}"} }, expects: 200, body: , } end |
.transcribe(source_io, chat:, language: nil) ⇒ String?
Transcribes audio/video content via the audio.cpp ASR endpoint.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/ollama_chat/asr.rb', line 26 def transcribe(source_io, chat:, language: nil) asr_url = OC::OLLAMA::CHAT::ASR::URL asr_model = OC::OLLAMA::CHAT::ASR::MODEL input = Tempfile.new(%w[ asr_in ]) wav = Tempfile.new(%w[ asr .wav ]) begin IO.copy_stream(source_io, input) input.flush cmd = OC::OLLAMA::CHAT::ASR::CONVERT_COMMAND % { input: input.path, output: wav.path } executable = Shellwords.split(cmd).first result = system(cmd, out: File::NULL, err: File::NULL) if result.nil? chat.feedback("ASR: #{executable} not found in PATH.", type: :warn) return end unless wav.size > 0 chat.feedback("ASR: #{executable} produced no output.", type: :warn) return end url = "#{asr_url}/v1/audio/transcriptions" form_data = multipart_form_data(wav.path, model: asr_model, language:) chat.request_url_response(:post, url, **form_data) do |response| return JSON.parse(response.body)['text'] end ensure input.close! wav&.close! end rescue JSON::ParserError, Excon::Error => e if response = e.ask_and_send(:response) status = response.status result = JSON.parse(response.body) rescue nil end chat.log(:error, e, data: { status:, result: }) chat.feedback("ASR transcription failed: #{e.}", type: :warn) nil end |