mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-06-14 03:32:00 +08:00
refactor: 删除部分多余的代码和注释
This commit is contained in:
@@ -1,26 +1,19 @@
|
||||
//! Opus audio encoder for WebRTC
|
||||
//! Opus encoder.
|
||||
|
||||
use audiopus::coder::GenericCtl;
|
||||
use audiopus::{coder::Encoder, Application, Bitrate, Channels, SampleRate};
|
||||
use bytes::Bytes;
|
||||
use std::time::Instant;
|
||||
use tracing::info;
|
||||
|
||||
use super::capture::AudioFrame;
|
||||
use crate::error::{AppError, Result};
|
||||
|
||||
/// Opus encoder configuration
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OpusConfig {
|
||||
/// Sample rate (must be 8000, 12000, 16000, 24000, or 48000)
|
||||
pub sample_rate: u32,
|
||||
/// Channels (1 or 2)
|
||||
pub channels: u32,
|
||||
/// Target bitrate in bps
|
||||
pub bitrate: u32,
|
||||
/// Application mode
|
||||
pub application: OpusApplication,
|
||||
/// Enable forward error correction
|
||||
pub fec: bool,
|
||||
}
|
||||
|
||||
@@ -29,7 +22,7 @@ impl Default for OpusConfig {
|
||||
Self {
|
||||
sample_rate: 48000,
|
||||
channels: 2,
|
||||
bitrate: 64000, // 64 kbps
|
||||
bitrate: 64000,
|
||||
application: OpusApplication::Audio,
|
||||
fec: true,
|
||||
}
|
||||
@@ -37,7 +30,6 @@ impl Default for OpusConfig {
|
||||
}
|
||||
|
||||
impl OpusConfig {
|
||||
/// Create config for voice (lower latency)
|
||||
pub fn voice() -> Self {
|
||||
Self {
|
||||
application: OpusApplication::Voip,
|
||||
@@ -46,7 +38,6 @@ impl OpusConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create config for music (higher quality)
|
||||
pub fn music() -> Self {
|
||||
Self {
|
||||
application: OpusApplication::Audio,
|
||||
@@ -82,30 +73,18 @@ impl OpusConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// Opus application mode
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum OpusApplication {
|
||||
/// Voice over IP
|
||||
Voip,
|
||||
/// General audio
|
||||
Audio,
|
||||
/// Low delay mode
|
||||
LowDelay,
|
||||
}
|
||||
|
||||
/// Encoded Opus frame
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OpusFrame {
|
||||
/// Encoded Opus data
|
||||
pub data: Bytes,
|
||||
/// Duration in milliseconds
|
||||
pub duration_ms: u32,
|
||||
/// Sequence number
|
||||
pub sequence: u64,
|
||||
/// Timestamp
|
||||
pub timestamp: Instant,
|
||||
/// RTP timestamp (samples)
|
||||
pub rtp_timestamp: u32,
|
||||
}
|
||||
|
||||
impl OpusFrame {
|
||||
@@ -118,20 +97,14 @@ impl OpusFrame {
|
||||
}
|
||||
}
|
||||
|
||||
/// Opus encoder
|
||||
pub struct OpusEncoder {
|
||||
config: OpusConfig,
|
||||
encoder: Encoder,
|
||||
/// Output buffer
|
||||
output_buffer: Vec<u8>,
|
||||
/// Frame counter for RTP timestamp
|
||||
frame_count: u64,
|
||||
/// Samples per frame
|
||||
samples_per_frame: u32,
|
||||
}
|
||||
|
||||
impl OpusEncoder {
|
||||
/// Create a new Opus encoder
|
||||
pub fn new(config: OpusConfig) -> Result<Self> {
|
||||
let sample_rate = config.to_audiopus_sample_rate();
|
||||
let channels = config.to_audiopus_channels();
|
||||
@@ -140,7 +113,6 @@ impl OpusEncoder {
|
||||
let mut encoder = Encoder::new(sample_rate, channels, application)
|
||||
.map_err(|e| AppError::AudioError(format!("Failed to create Opus encoder: {:?}", e)))?;
|
||||
|
||||
// Configure encoder
|
||||
encoder
|
||||
.set_bitrate(Bitrate::BitsPerSecond(config.bitrate as i32))
|
||||
.map_err(|e| AppError::AudioError(format!("Failed to set bitrate: {:?}", e)))?;
|
||||
@@ -151,9 +123,6 @@ impl OpusEncoder {
|
||||
.map_err(|e| AppError::AudioError(format!("Failed to enable FEC: {:?}", e)))?;
|
||||
}
|
||||
|
||||
// Calculate samples per frame (20ms at sample_rate)
|
||||
let samples_per_frame = config.sample_rate / 50;
|
||||
|
||||
info!(
|
||||
"Opus encoder created: {}Hz {}ch {}bps",
|
||||
config.sample_rate, config.channels, config.bitrate
|
||||
@@ -162,18 +131,11 @@ impl OpusEncoder {
|
||||
Ok(Self {
|
||||
config,
|
||||
encoder,
|
||||
output_buffer: vec![0u8; 4000], // Max Opus frame size
|
||||
output_buffer: vec![0u8; 4000],
|
||||
frame_count: 0,
|
||||
samples_per_frame,
|
||||
})
|
||||
}
|
||||
|
||||
/// Create with default configuration
|
||||
pub fn default_config() -> Result<Self> {
|
||||
Self::new(OpusConfig::default())
|
||||
}
|
||||
|
||||
/// Encode PCM audio data (S16LE interleaved)
|
||||
pub fn encode(&mut self, pcm_data: &[i16]) -> Result<OpusFrame> {
|
||||
let encoded_len = self
|
||||
.encoder
|
||||
@@ -182,7 +144,6 @@ impl OpusEncoder {
|
||||
|
||||
let samples = pcm_data.len() as u32 / self.config.channels;
|
||||
let duration_ms = (samples * 1000) / self.config.sample_rate;
|
||||
let rtp_timestamp = (self.frame_count * self.samples_per_frame as u64) as u32;
|
||||
|
||||
self.frame_count += 1;
|
||||
|
||||
@@ -190,27 +151,18 @@ impl OpusEncoder {
|
||||
data: Bytes::copy_from_slice(&self.output_buffer[..encoded_len]),
|
||||
duration_ms,
|
||||
sequence: self.frame_count - 1,
|
||||
timestamp: Instant::now(),
|
||||
rtp_timestamp,
|
||||
})
|
||||
}
|
||||
|
||||
/// Encode from AudioFrame
|
||||
///
|
||||
/// Uses zero-copy conversion from bytes to i16 samples via bytemuck.
|
||||
pub fn encode_frame(&mut self, frame: &AudioFrame) -> Result<OpusFrame> {
|
||||
// Zero-copy: directly cast bytes to i16 slice
|
||||
// AudioFrame.data is S16LE format, which matches native little-endian i16
|
||||
let samples: &[i16] = bytemuck::cast_slice(&frame.data);
|
||||
self.encode(samples)
|
||||
}
|
||||
|
||||
/// Get encoder configuration
|
||||
pub fn config(&self) -> &OpusConfig {
|
||||
&self.config
|
||||
}
|
||||
|
||||
/// Reset encoder state
|
||||
pub fn reset(&mut self) -> Result<()> {
|
||||
self.encoder
|
||||
.reset_state()
|
||||
@@ -219,7 +171,6 @@ impl OpusEncoder {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set bitrate dynamically
|
||||
pub fn set_bitrate(&mut self, bitrate: u32) -> Result<()> {
|
||||
self.encoder
|
||||
.set_bitrate(Bitrate::BitsPerSecond(bitrate as i32))
|
||||
@@ -228,15 +179,6 @@ impl OpusEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Audio encoder statistics
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct EncoderStats {
|
||||
pub frames_encoded: u64,
|
||||
pub bytes_output: u64,
|
||||
pub avg_frame_size: usize,
|
||||
pub current_bitrate: u32,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -261,13 +203,12 @@ mod tests {
|
||||
let config = OpusConfig::default();
|
||||
let mut encoder = OpusEncoder::new(config).unwrap();
|
||||
|
||||
// 20ms of stereo silence at 48kHz
|
||||
let silence = vec![0i16; 960 * 2];
|
||||
let result = encoder.encode(&silence);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let frame = result.unwrap();
|
||||
assert!(!frame.is_empty());
|
||||
assert!(frame.len() < silence.len() * 2); // Should be compressed
|
||||
assert!(frame.len() < silence.len() * 2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user