MCPcopy Create free account
hub / github.com/Recordscript/recordscript / decode_audio

Function decode_audio

src-tauri/src/transcriber.rs:314–380  ·  view source on GitHub ↗

Decode any media for whisper

(media_data: Arc<[u8]>)

Source from the content-addressed store, hash-verified

312
313/// Decode any media for whisper
314fn decode_audio(media_data: Arc<[u8]>) -> anyhow::Result<Vec<f32>> {
315 use gst::prelude::*;
316
317 let media_data_len = media_data.len();
318 let media_data = Arc::new(Mutex::new(Cursor::new(media_data)));
319
320 let pipeline =
321 gst::parse::launch(&format!("appsrc name=audio-in stream-type=2 size={media_data_len} ! decodebin ! audioconvert ! audio/x-raw,format=F32LE,channels=1 ! audioresample ! audio/x-raw,rate=16000 ! appsink name=pcm-out sync=false"))?
322 .dynamic_cast::<gst::Pipeline>().unwrap();
323
324 pipeline.by_name("audio-in").unwrap().dynamic_cast::<gst_app::AppSrc>().unwrap()
325 .set_callbacks(gst_app::AppSrcCallbacks::builder()
326 .need_data({
327 let media_data = media_data.clone();
328
329 move |source, length| {
330 let mut buffer = vec![0u8; length as _];
331 let position = media_data.lock().unwrap().position();
332 let _ = media_data.lock().unwrap().read(&mut buffer).unwrap();
333
334 if position as usize >= media_data_len {
335 println!("Ending stream");
336 source.end_of_stream().unwrap();
337 return;
338 }
339
340 let buffer = gst::Buffer::from_slice(buffer);
341 let _ = source.push_buffer(buffer);
342 }
343 })
344 .seek_data({
345 let media_data = media_data.clone();
346
347 move |_, location| {
348 media_data.lock().unwrap().set_position(location);
349
350 true
351 }
352 })
353 .build());
354
355 let pcm_data = Arc::new(Mutex::new(Vec::new()));
356
357 pipeline.by_name("pcm-out").unwrap().dynamic_cast::<gst_app::AppSink>().unwrap()
358 .set_callbacks(gst_app::AppSinkCallbacks::builder()
359 .new_sample({
360 let pcm_data = pcm_data.clone();
361
362 move |sink| {
363 let Ok(sample) = sink.pull_sample() else { return Err(gst::FlowError::Error) };
364
365 let buffer = sample.buffer().unwrap();
366 let mapped_buffer = buffer.map_readable().unwrap();
367
368 let samples = mapped_buffer.as_slice_of::<f32>().unwrap();
369
370 pcm_data.lock().unwrap().extend_from_slice(samples);
371

Callers 1

transcribeMethod · 0.85

Calls 4

gstreamer_loopFunction · 0.85
buildMethod · 0.80
cloneMethod · 0.45
readMethod · 0.45

Tested by

no test coverage detected