RecorderIO: option to encode at a constant bit rate (and set the bit rate)
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- python
調査の方向性
Start with the RecorderIO implementation and its encoding thread, then review the open pull request #7740 and related issue #4052 to understand the current work. The proposal names codec_context.bit_rate and the Opus vbr option; completion means exposing both settings with defaults preserved and tests covering constant packet sizes, defaults, and invalid bit rates.
索引モデルが issue の本文から書いたものです。
説明
Feature Type
Would make my life easier
Feature Description
RecorderIO encodes the session recording with the encoder's defaults: libopus, variable bit rate, 96 kb/s target for stereo. There is no way to change this.
Two examples of consequences:
- Recorded lengths display wrong on macOS. A session almost always opens on silence, which VBR packs into 3-byte packets. Players that estimate an Ogg Opus length from the file size over the bit rate of the first pages then overshoot badly. AVFoundation's quick duration, which Finder, QuickLook and Preview use, showed a 211 s recording as 6:53 and 7:09 (two recordings of the same session, before and after noise cancellation). The files are correct: ffprobe, CoreAudio (
afinfo) and AVFoundation's precise duration all read 211.8 s. The same session recorded by LiveKit Egress, which is constant 128 kb/s, showed 3:34. - Quality and size cannot be matched to Egress (#4042 asked for the bit rate for this reason).
I measured what fixes the length estimate, re-encoding the same recording:
| Change | AVFoundation estimate (real length 3:32) |
|---|---|
Ogg page layout (page_duration 20 ms or 260 ms) |
8:02 / 6:24 |
| Drop the silent opening | 5:07 |
| Constrained VBR | 7:45 |
vbr=off at 96 kb/s |
3:33 |
vbr=off at 128 kb/s |
3:33 |
Only a constant bit rate works, so a bit rate alone (the scope of #4052) does not cover it.
Proposal
Two keyword arguments on RecorderIO, with defaults that keep today's behaviour:
RecorderIO(agent_session=session, bit_rate=128_000, constant_bit_rate=True)
bit_rate: int | None = None: setscodec_context.bit_rate;Nonekeeps the encoder default.constant_bit_rate: bool = False: sets the Opusvbr=offoption.Truewithbit_rate=128_000matches Egress recordings byte for byte per second (320-byte packets).
Both libopus and ffmpeg's native opus encoder honour the two settings (checked with PyAV 18).
Workarounds / Alternatives
- Subclassing
RecorderIOand overriding_encode_threadwith a copy that sets the two values. That is what we run today, with a test that pins the SDK method's source hash so an upgrade tells us to re-sync the copy. It works, but it freezes a method that has had three fixes since August (#6921, #7047, #7079). - Re-encoding the file after the session: lossy twice and too slow at shutdown for long sessions.
- Changing the Ogg page layout: tested, does not help (table above).
- #4052 (open since November 2025, approved twice) adds
bitrateonly and now conflicts with the rewritten module; withoutvbr=offit does not fix the length estimate.
Additional Context
Additional Context:
- Related: #4042 (closed as completed, but #4052 never merged).
- Agents 1.8.4; PyAV 18.0.0; macOS 26. Measured with
AVURLAsset.durationwith and withoutAVURLAssetPreferPreciseDurationAndTimingKey. - I have a PR ready with the two arguments, docstrings, and unit tests (constant packet sizes at 64 and 128 kb/s, defaults unchanged, invalid bit rate rejected). If you would rather expose these through
AgentSession.start(record=...)/RecordingOptionsas well, happy to add that.
- 主要言語
- Python
- スター
- 14.6k
- フォーク
- 3.9k
- 平均マージ
- 3日 1時間
- マージ済み PR(30日)
- 173
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
livekit/agents のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
Assistant markup is stripped from chat history when expressive mode is off対応中かも @ShivamSharma43 が 8 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
docs: openai.LLM vs openai.responses.LLM for HTTP OpenAI-compat hosts再び着手できるかも @AbarnaaSree が 47 日前に担当しましたが、オープン中のプルリクエストはありません。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
livekit/agents#7022 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
メンテナーはふだん 1 日以内に返信
-
DuplexRealtimeAdapter: transcript fragment for audio that is never sent anchors the next burst, shifting transcripts by one utterance対応中かも @dyyfk が今日担当しました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
huggingface/sentence-transformers#4186 ·
メンテナーはふだん 5 日以内に返信
-
documentation
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
QuantEcon/QuantEcon.py#988 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
fabriziosalmi/certmate#1247 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 1 日以内に返信
-
documentation good first issue
難易度 2/5 半日 初心者へのやさしさ 72/100
sujithputta02/Esapay#13 ·