libobs_wrapper\encoders/
audio.rs

1use libobs::audio_output;
2use std::{borrow::Borrow, ptr, sync::Arc};
3
4use crate::{
5    data::ObsData,
6    impl_obs_drop, run_with_obs,
7    runtime::ObsRuntime,
8    unsafe_send::Sendable,
9    utils::{AudioEncoderInfo, ObsError, ObsString},
10};
11
12#[derive(Debug)]
13#[allow(dead_code)]
14pub struct ObsAudioEncoder {
15    pub(crate) encoder: Sendable<*mut libobs::obs_encoder_t>,
16    pub(crate) id: ObsString,
17    pub(crate) name: ObsString,
18    pub(crate) settings: Option<ObsData>,
19    pub(crate) hotkey_data: Option<ObsData>,
20    pub(crate) runtime: ObsRuntime,
21}
22
23impl ObsAudioEncoder {
24    /// Info: the handler attribute is no longer needed and kept for compatibility. The `handler` parameter will be removed in a future release.
25    pub fn new_from_info(
26        info: AudioEncoderInfo,
27        mixer_idx: usize,
28        runtime: ObsRuntime,
29    ) -> Result<Arc<Self>, ObsError> {
30        let settings_ptr = match info.settings.borrow() {
31            Some(x) => x.as_ptr(),
32            None => Sendable(ptr::null_mut()),
33        };
34
35        let hotkey_data_ptr = match info.hotkey_data.borrow() {
36            Some(x) => x.as_ptr(),
37            None => Sendable(ptr::null_mut()),
38        };
39
40        let id_ptr = info.id.as_ptr();
41        let name_ptr = info.name.as_ptr();
42
43        let encoder = run_with_obs!(
44            runtime,
45            (hotkey_data_ptr, settings_ptr, id_ptr, name_ptr),
46            move || unsafe {
47                let ptr = libobs::obs_audio_encoder_create(
48                    id_ptr,
49                    name_ptr,
50                    settings_ptr,
51                    mixer_idx,
52                    hotkey_data_ptr,
53                );
54                Sendable(ptr)
55            }
56        )?;
57
58        if encoder.0.is_null() {
59            return Err(ObsError::NullPointer);
60        }
61
62        Ok(Arc::new(Self {
63            encoder,
64            id: info.id,
65            name: info.name,
66            settings: info.settings,
67            hotkey_data: info.hotkey_data,
68            runtime,
69        }))
70    }
71
72    /// This is only needed once for global audio context
73    pub fn set_audio_context(
74        &mut self,
75        handler: Sendable<*mut audio_output>,
76    ) -> Result<(), ObsError> {
77        let encoder_ptr = self.encoder.clone();
78
79        run_with_obs!(self.runtime, (handler, encoder_ptr), move || unsafe {
80            libobs::obs_encoder_set_audio(encoder_ptr, handler)
81        })
82    }
83}
84
85impl_obs_drop!(ObsAudioEncoder, (encoder), move || unsafe {
86    libobs::obs_encoder_release(encoder)
87});