#![warn(missing_docs)]
#![deny(unsafe_op_in_unsafe_fn)]
#[cfg(doctest)]
#[doc = include_str!("../README.md")]
pub struct ReadmeDoctests;
mod decoder;
mod encoder;
mod error;
mod ffi;
mod metadata;
mod options;
mod resampler;
mod samples;
pub use decoder::{AudioDecoder, Frame};
pub use encoder::{save_audio, AudioEncoder};
pub use error::{Error, ErrorKind, Result};
pub use metadata::Metadata;
pub use options::{ResampleOptions, StreamOptions, WriteOptions};
pub use resampler::{resample, AudioResampler};
use std::ffi::CStr;
use crate::error::check;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeviceInfo {
pub name: String,
pub description: String,
pub is_output: bool,
}
pub fn set_log_level(level: Option<&str>) {
match level {
Some(value) => {
if let Ok(text) = std::ffi::CString::new(value) {
unsafe { ffi::avf_set_log_level(text.as_ptr()) };
}
}
None => unsafe { ffi::avf_set_log_level(std::ptr::null()) },
}
}
pub fn supported_decoders() -> Result<Vec<String>> {
string_list(|out| unsafe { ffi::avf_get_supported_decoders(out) })
}
pub fn supported_encoders() -> Result<Vec<String>> {
string_list(|out| unsafe { ffi::avf_get_supported_encoders(out) })
}
pub fn supported_input_formats() -> Result<Vec<String>> {
string_list(|out| unsafe { ffi::avf_get_supported_input_formats(out) })
}
pub fn supported_output_formats() -> Result<Vec<String>> {
string_list(|out| unsafe { ffi::avf_get_supported_output_formats(out) })
}
pub fn list_audio_devices() -> Result<Vec<DeviceInfo>> {
let mut handle: *mut ffi::AvfDeviceList = std::ptr::null_mut();
check(unsafe { ffi::avf_list_audio_devices(&mut handle) })?;
if handle.is_null() {
return Ok(Vec::new());
}
let devices = unsafe {
let count = ffi::avf_device_list_size(handle);
let mut devices = Vec::with_capacity(count);
for index in 0..count {
devices.push(DeviceInfo {
name: owned_string(ffi::avf_device_list_name(handle, index)),
description: owned_string(ffi::avf_device_list_description(handle, index)),
is_output: ffi::avf_device_list_is_output(handle, index) != 0,
});
}
ffi::avf_device_list_free(handle);
devices
};
Ok(devices)
}
fn string_list<F>(f: F) -> Result<Vec<String>>
where
F: FnOnce(*mut *mut ffi::AvfStringList) -> std::os::raw::c_int,
{
let mut handle: *mut ffi::AvfStringList = std::ptr::null_mut();
check(f(&mut handle))?;
if handle.is_null() {
return Ok(Vec::new());
}
let items = unsafe {
let count = ffi::avf_string_list_size(handle);
let mut items = Vec::with_capacity(count);
for index in 0..count {
items.push(owned_string(ffi::avf_string_list_get(handle, index)));
}
ffi::avf_string_list_free(handle);
items
};
Ok(items)
}
unsafe fn owned_string(raw: *const std::os::raw::c_char) -> String {
if raw.is_null() {
return String::new();
}
unsafe { CStr::from_ptr(raw).to_string_lossy().into_owned() }
}