mirror of
https://github.com/facefusion/facefusion.git
synced 2026-07-15 06:27:21 +02:00
5f403ada65
* remove opus frame size * improve naming, follow audio.py
68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
from functools import partial
|
|
from queue import Queue
|
|
from typing import Optional, Tuple
|
|
|
|
import numpy
|
|
|
|
from facefusion import rtc
|
|
from facefusion.apis.stream_event import create_receive_event
|
|
from facefusion.codecs import opus_decoder, opus_encoder
|
|
from facefusion.types import AudioCodec, AudioFrame, Buffer, OpusDecoder, RtcPeer, RtcPeerAudio, Time
|
|
|
|
|
|
def run_audio_encode_loop(rtc_peer : RtcPeer, audio_queue : Queue[Tuple[Time, AudioFrame]]) -> None:
|
|
audio_codec = rtc_peer.get('audio').get('codec')
|
|
temp_audio_time, temp_audio_frame = audio_queue.get()
|
|
audio_encoder = opus_encoder.create(48000, 2)
|
|
|
|
while numpy.any(temp_audio_frame):
|
|
audio_buffer = opus_encoder.encode(audio_encoder, temp_audio_frame.tobytes(), 2)
|
|
|
|
if audio_buffer:
|
|
audio_timestamp = rtc.convert_time_to_timestamp(audio_codec, temp_audio_time)
|
|
rtc.send_audio(rtc_peer, audio_buffer, audio_timestamp)
|
|
|
|
temp_audio_time, temp_audio_frame = audio_queue.get()
|
|
|
|
opus_encoder.destroy(audio_encoder)
|
|
|
|
|
|
def receive_audio_frames(rtc_peer_audio : RtcPeerAudio, audio_queue : Queue[Tuple[Time, AudioFrame]]) -> None:
|
|
audio_track = rtc_peer_audio.get('receiver_track')
|
|
audio_codec = rtc_peer_audio.get('codec')
|
|
audio_decoder = create_audio_decoder(audio_codec)
|
|
|
|
audio_frame_handler = partial(handle_audio_frame, audio_codec, audio_decoder, audio_queue)
|
|
receive_event = create_receive_event(audio_track, audio_frame_handler)
|
|
receive_event.wait()
|
|
|
|
empty_audio_frame = numpy.empty(0)
|
|
audio_queue.put((0.0, empty_audio_frame))
|
|
destroy_audio_decoder(audio_codec, audio_decoder)
|
|
|
|
|
|
def decode_audio_frame(audio_codec : AudioCodec, audio_decoder : OpusDecoder, input_buffer : Buffer) -> Optional[Buffer]:
|
|
if audio_codec == 'opus':
|
|
return opus_decoder.decode(audio_decoder, input_buffer, 2)
|
|
return None
|
|
|
|
|
|
def create_audio_decoder(audio_codec : AudioCodec) -> Optional[OpusDecoder]:
|
|
if audio_codec == 'opus':
|
|
return opus_decoder.create(48000, 2)
|
|
return None
|
|
|
|
|
|
def destroy_audio_decoder(audio_codec : AudioCodec, audio_decoder : OpusDecoder) -> None:
|
|
if audio_codec == 'opus':
|
|
opus_decoder.destroy(audio_decoder)
|
|
|
|
|
|
def handle_audio_frame(audio_codec : AudioCodec, audio_decoder : OpusDecoder, audio_queue : Queue[Tuple[Time, AudioFrame]], audio_buffer : Buffer, audio_timestamp : int) -> None:
|
|
audio_frame = decode_audio_frame(audio_codec, audio_decoder, audio_buffer)
|
|
|
|
if audio_frame:
|
|
audio_frame = numpy.frombuffer(audio_frame, dtype = numpy.float32)
|
|
audio_time = rtc.convert_timestamp_to_time(audio_codec, audio_timestamp)
|
|
audio_queue.put((audio_time, audio_frame))
|