use std::pin::Pin;
use crate::packet::{Audio, AudioCodec};
use anyhow::{Result, bail};
use bytes::Bytes;
use th_rs::define::{TH_AUDIOCODECTYPE_TH_ACT_G711, TH_DATATYPE_TH_DT_AUDIO, TH_ESStreamInfo};
use tokio::task::block_in_place;
#[cfg(feature = "enable_codec")]
use xodec_rs::encoder_aac::EncoderAAC;
pub(crate) struct AACEncoder {
#[cfg(feature = "enable_codec")]
encoder: Pin<Box<EncoderAAC>>,
}
impl AACEncoder {
pub fn new() -> Self {
#[cfg(feature = "enable_codec")]
{
Self {
encoder: EncoderAAC::new(),
}
}
#[cfg(not(feature = "enable_codec"))]
{
Self {}
}
}
#[allow(unused_variables)]
pub fn write(&mut self, audio: &Audio, payload: Bytes) -> Result<Bytes> {
#[cfg(feature = "enable_codec")]
{
let encoder = &mut self.encoder;
match audio.codec {
AudioCodec::Aac => Ok(payload),
AudioCodec::G711A => {
let o_aac = block_in_place(move || {
let sp = tracing::span!(tracing::Level::ERROR, "aac_encode");
let _enter = sp.enter();
encoder.write(
&payload,
&TH_ESStreamInfo {
streamType: TH_DATATYPE_TH_DT_AUDIO as _,
aCodecType: TH_AUDIOCODECTYPE_TH_ACT_G711 as _,
aSampleRate: audio.sample_rate,
aChannels: audio.channels,
aSampleBits: audio.bits,
..Default::default()
},
)
});
let Ok(aac) = o_aac else { bail!("Encode aac fail") };
Ok(Bytes::copy_from_slice(aac))
},
other => bail!("No support audio codec({:?}) encode to aac", other),
}
}
#[cfg(not(feature = "enable_codec"))]
{
const ERR_MSG: &str = "enable_codec feature is not enabled, cannot encode audio";
tracing::error!("{ERR_MSG}");
bail!(ERR_MSG)
}
}
}