Skip to main content

ffmpeg_pipeline/audio/
transcode.rs

1use std::io::Cursor;
2
3use super::*;
4
5pub fn transcode_audio_buffer(
6    input_bytes: Vec<u8>,
7    output_extension: &str,
8    codec_id: CodecId,
9    bitrate: usize,
10) -> FFmpegResult<Vec<u8>> {
11    let mut input = input_buffer(input_bytes)?;
12    let mut output = output_buffer(output_extension)?;
13    {
14        let stream_index = input
15            .as_ref()
16            .streams()
17            .find(|stream| stream.parameters().medium() == MediaType::Audio)
18            .map(|stream| stream.index())
19            .ok_or(FFmpegError::StreamNotFound(0))?;
20        let decoder = Decoder::new_with_audio(input.as_mut(), stream_index, FrameProcess::Decode)?;
21        let params = EncodeParams::from(&decoder)
22            .with_bitrate(bitrate)
23            .with_compression((codec_id == CodecId::OPUS).then_some(10))
24            .with_vbr(true);
25        let mut encoder = Encoder::new(output.as_mut(), codec_id, params)?;
26        encoder.set_metadata("encoder", env!("CARGO_PKG_NAME"))?;
27        encoder.write_header()?;
28
29        let mut buffer = AutoAudioBuffer::new(&decoder, &encoder)?;
30        let mut encode = |frame: AudioFrame| -> FFmpegResult<()> {
31            encoder.send_frame(&StreamFrame::Audio(frame))?;
32            encoder.encode_frame()
33        };
34        for frame in decoder {
35            let frame = frame?;
36            if let Frame::Frame(StreamFrame::Audio(frame)) = frame {
37                buffer.add_frame(&frame)?;
38                buffer.recv_frames(&mut encode)?;
39            }
40        }
41        buffer.flush()?;
42        buffer.recv_frames(&mut encode)?;
43        encoder.send_frame(&StreamFrame::Eof)?;
44        encoder.encode_frame()?;
45    }
46    Ok(output.into_inner::<Cursor<Vec<u8>>>()?.into_inner())
47}