Skip to content

Commit efb5473

Browse files
committed
ruff format
1 parent 9b2f466 commit efb5473

File tree

5 files changed

+58
-23
lines changed

5 files changed

+58
-23
lines changed

examples/local-audio/full_duplex.py

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ async def main() -> None:
1111

1212
# Load environment variables from a .env file if present
1313
load_dotenv(find_dotenv())
14-
14+
1515
url = os.getenv("LIVEKIT_URL")
1616
token = os.getenv("LIVEKIT_TOKEN")
1717
if not url or not token:
1818
raise RuntimeError("LIVEKIT_URL and LIVEKIT_TOKEN must be set in env")
1919

2020
room = rtc.Room()
21-
21+
2222
devices = rtc.MediaDevices()
2323

2424
# Open microphone with AEC and prepare a player for remote audio feeding AEC reverse stream
@@ -32,7 +32,9 @@ async def main() -> None:
3232
streams_by_pub: dict[str, rtc.AudioStream] = {}
3333
streams_by_participant: dict[str, set[rtc.AudioStream]] = {}
3434

35-
async def _remove_stream(stream: rtc.AudioStream, participant_sid: str | None = None, pub_sid: str | None = None) -> None:
35+
async def _remove_stream(
36+
stream: rtc.AudioStream, participant_sid: str | None = None, pub_sid: str | None = None
37+
) -> None:
3638
try:
3739
mixer.remove_stream(stream)
3840
except Exception:
@@ -48,25 +50,50 @@ async def _remove_stream(stream: rtc.AudioStream, participant_sid: str | None =
4850
if pub_sid is not None:
4951
streams_by_pub.pop(pub_sid, None)
5052

51-
def on_track_subscribed(track: rtc.Track, publication: rtc.RemoteTrackPublication, participant: rtc.RemoteParticipant):
53+
class _FrameOnlyStream:
54+
def __init__(self, inner: rtc.AudioStream) -> None:
55+
self._inner = inner
56+
57+
def __aiter__(self):
58+
return self
59+
60+
async def __anext__(self) -> rtc.AudioFrame:
61+
event = await self._inner.__anext__()
62+
return event.frame
63+
64+
async def aclose(self) -> None:
65+
await self._inner.aclose()
66+
67+
def on_track_subscribed(
68+
track: rtc.Track,
69+
publication: rtc.RemoteTrackPublication,
70+
participant: rtc.RemoteParticipant,
71+
):
5272
if track.kind == rtc.TrackKind.KIND_AUDIO:
53-
stream = rtc.AudioStream(track, sample_rate=48000, num_channels=1)
54-
streams_by_pub[publication.sid] = stream
55-
streams_by_participant.setdefault(participant.sid, set()).add(stream)
56-
mixer.add_stream(stream)
73+
event_stream = rtc.AudioStream(track, sample_rate=48000, num_channels=1)
74+
frame_stream = _FrameOnlyStream(event_stream)
75+
streams_by_pub[publication.sid] = frame_stream
76+
streams_by_participant.setdefault(participant.sid, set()).add(frame_stream)
77+
mixer.add_stream(frame_stream)
5778
logging.info("subscribed to audio from %s", participant.identity)
5879

5980
room.on("track_subscribed", on_track_subscribed)
6081

61-
def on_track_unsubscribed(track: rtc.Track, publication: rtc.RemoteTrackPublication, participant: rtc.RemoteParticipant):
82+
def on_track_unsubscribed(
83+
track: rtc.Track,
84+
publication: rtc.RemoteTrackPublication,
85+
participant: rtc.RemoteParticipant,
86+
):
6287
stream = streams_by_pub.get(publication.sid)
6388
if stream is not None:
6489
asyncio.create_task(_remove_stream(stream, participant.sid, publication.sid))
6590
logging.info("unsubscribed from audio of %s", participant.identity)
6691

6792
room.on("track_unsubscribed", on_track_unsubscribed)
6893

69-
def on_track_unpublished(publication: rtc.RemoteTrackPublication, participant: rtc.RemoteParticipant):
94+
def on_track_unpublished(
95+
publication: rtc.RemoteTrackPublication, participant: rtc.RemoteParticipant
96+
):
7097
stream = streams_by_pub.get(publication.sid)
7198
if stream is not None:
7299
asyncio.create_task(_remove_stream(stream, participant.sid, publication.sid))
@@ -119,5 +146,3 @@ def on_participant_disconnected(participant: rtc.RemoteParticipant):
119146

120147
if __name__ == "__main__":
121148
asyncio.run(main())
122-
123-

examples/local-audio/publish_mic.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from livekit import rtc
77

8+
89
async def main() -> None:
910
logging.basicConfig(level=logging.INFO)
1011

@@ -47,5 +48,3 @@ async def main() -> None:
4748

4849
if __name__ == "__main__":
4950
asyncio.run(main())
50-
51-

livekit-rtc/livekit/rtc/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@
9090
from .audio_resampler import AudioResampler, AudioResamplerQuality
9191
from .audio_mixer import AudioMixer
9292
from .apm import AudioProcessingModule
93+
9394
try:
9495
from .media_devices import MediaDevices as MediaDevices
96+
9597
_HAS_MEDIA_DEVICES = True
9698
except Exception: # pragma: no cover - optional dependency (sounddevice)
9799
_HAS_MEDIA_DEVICES = False

livekit-rtc/livekit/rtc/audio_mixer.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,6 @@ async def _get_contribution(
184184
except StopAsyncIteration:
185185
exhausted = True
186186
break
187-
# AudioStream may yield either AudioFrame or AudioFrameEvent; unwrap if needed
188-
if hasattr(frame, "frame"):
189-
frame = frame.frame # type: ignore[assignment]
190187

191188
new_data = np.frombuffer(frame.data.tobytes(), dtype=np.int16).reshape(
192189
-1, self._num_channels

livekit-rtc/livekit/rtc/media_devices.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class MicrophoneCapture:
9696
instance to `open_output_player` so reverse frames are provided.
9797
delay_estimator: Internal helper used to combine capture and render delays.
9898
"""
99+
99100
source: AudioSource
100101
input_stream: sd.InputStream
101102
task: asyncio.Task
@@ -124,6 +125,7 @@ class OutputPlayer:
124125
renders (in 10 ms frames) into the APM reverse path so that echo
125126
cancellation can correlate mic input with speaker output.
126127
"""
128+
127129
def __init__(
128130
self,
129131
*,
@@ -343,21 +345,27 @@ def open_microphone(
343345
high_pass_filter=high_pass_filter,
344346
auto_gain_control=auto_gain_control,
345347
)
346-
delay_estimator: Optional[_APMDelayEstimator] = _APMDelayEstimator() if apm is not None else None
348+
delay_estimator: Optional[_APMDelayEstimator] = (
349+
_APMDelayEstimator() if apm is not None else None
350+
)
347351
# Store the shared estimator on the device helper so the output player can reuse it
348352
self._delay_estimator = delay_estimator
349353

350354
# Queue from callback to async task
351355
q: asyncio.Queue[AudioFrame] = asyncio.Queue(maxsize=queue_capacity)
352356

353-
def _input_callback(indata: np.ndarray, frame_count: int, time_info: Any, status: Any) -> None:
357+
def _input_callback(
358+
indata: np.ndarray, frame_count: int, time_info: Any, status: Any
359+
) -> None:
354360
# Slice into 10 ms frames, optionally APM, enqueue for async capture
355361
# Compute input (capture) delay using PortAudio timing; combine with last
356362
# measured output delay to provide APM stream delay in milliseconds.
357363
if apm is not None:
358364
try:
359365
input_delay_sec = float(time_info.currentTime - time_info.inputBufferAdcTime)
360-
output_delay_sec = float(delay_estimator.get_output_delay()) if delay_estimator else 0.0
366+
output_delay_sec = (
367+
float(delay_estimator.get_output_delay()) if delay_estimator else 0.0
368+
)
361369
total_delay_ms = int(max((input_delay_sec + output_delay_sec) * 1000.0, 0.0))
362370
try:
363371
apm.set_stream_delay_ms(total_delay_ms)
@@ -444,7 +452,13 @@ async def _pump() -> None:
444452
pass
445453

446454
task = asyncio.create_task(_pump())
447-
return MicrophoneCapture(source=source, input_stream=input_stream, task=task, apm=apm, delay_estimator=delay_estimator)
455+
return MicrophoneCapture(
456+
source=source,
457+
input_stream=input_stream,
458+
task=task,
459+
apm=apm,
460+
delay_estimator=delay_estimator,
461+
)
448462

449463
def open_output_player(
450464
self,
@@ -466,5 +480,3 @@ def open_output_player(
466480
output_device=output_device,
467481
delay_estimator=self._delay_estimator,
468482
)
469-
470-

0 commit comments

Comments
 (0)