modern-city-48224
09/11/2025, 6:17 PMlivekit.api.twirp_client.TwirpError: TwirpError(code=invalid_argument, message=no supported codec is compatible with all outputs, status=400)
Here is my code:
agent_req = lk_api.ParticipantEgressRequest(
room_name=ctx.room.name,
identity=agent_room_identity,
screen_share=False,
file_outputs=[
lk_api.EncodedFileOutput(
file_type=lk_api.EncodedFileType.OGG,
filepath=file_path_agent,
s3=lk_api.S3Upload(
# endpoint=S3_RECORDING_ENDPOINT,
bucket=S3_RECORDING_BUCKET_NAME,
region=S3_RECORDING_REGION,
access_key=S3_RECORDING_ACCESS_KEY,
secret=S3_RECORDING_SECRET_KEY,
),
)
],
)
res = await lkapi.egress.start_participant_egress(agent_req)
What is the issue? I would prefer to use an audio-only format for the recording, so I do not want to switch to MP4tall-airline-16756
09/11/2025, 6:17 PMtall-airline-16756
09/11/2025, 6:17 PMtall-airline-16756
09/11/2025, 6:18 PMmodern-city-48224
09/11/2025, 6:18 PMtall-airline-16756
09/11/2025, 6:20 PMaudio_only=True
and specify OGG as the file type in the file_outputs
configuration. Here's an example to guide you:
from livekit import api
req = api.RoomCompositeEgressRequest(
room_name="your-room-name",
audio_only=True,
file_outputs=[api.EncodedFileOutput(
file_type=api.EncodedFileType.OGG,
filepath="path/to/output.ogg",
s3=api.S3Upload(
bucket="your-bucket-name",
region="your-region",
access_key="your-access-key",
secret="your-secret-key",
),
)],
)
1. Configure the EncodedFileOutput: Double-check that file_type
is set to EncodedFileType.OGG
and the filepath
ends with .ogg
. Don’t forget to include your storage settings, like your S3 details.
2. Start the egress: Then, use the LiveKit API to kick off the recording process:
lkapi = api.LiveKitAPI()
res = await lkapi.egress.start_room_composite_egress(req)
await lkapi.aclose()
Just so you know, OGG uses the Opus codec, which works perfectly for audio-only egress. If you run into any questions or need a hand with anything else, feel free to reach out—I’m here to help!
Sources: Session recording and transcripts | LiveKit Docs | Session recording and transcripts | LiveKit Docs | livekit/livekit_egress.pb.go | pkg/config/output_file.gomodern-city-48224
09/11/2025, 6:23 PMaudio_only=True
The problem is NOT RoomCompositeEgressRequest
it is ParticipantEgressRequest
.
Here is the source code of ParticipantEgressRequest
:
class ParticipantEgressRequest(_message.Message):
__slots__ = ("room_name", "identity", "screen_share", "preset", "advanced", "file_outputs", "stream_outputs", "segment_outputs", "image_outputs", "webhooks")
ROOM_NAME_FIELD_NUMBER: _ClassVar[int]
IDENTITY_FIELD_NUMBER: _ClassVar[int]
SCREEN_SHARE_FIELD_NUMBER: _ClassVar[int]
PRESET_FIELD_NUMBER: _ClassVar[int]
ADVANCED_FIELD_NUMBER: _ClassVar[int]
FILE_OUTPUTS_FIELD_NUMBER: _ClassVar[int]
STREAM_OUTPUTS_FIELD_NUMBER: _ClassVar[int]
SEGMENT_OUTPUTS_FIELD_NUMBER: _ClassVar[int]
IMAGE_OUTPUTS_FIELD_NUMBER: _ClassVar[int]
WEBHOOKS_FIELD_NUMBER: _ClassVar[int]
room_name: str
identity: str
screen_share: bool
preset: EncodingOptionsPreset
advanced: EncodingOptions
file_outputs: _containers.RepeatedCompositeFieldContainer[EncodedFileOutput]
stream_outputs: _containers.RepeatedCompositeFieldContainer[StreamOutput]
segment_outputs: _containers.RepeatedCompositeFieldContainer[SegmentedFileOutput]
image_outputs: _containers.RepeatedCompositeFieldContainer[ImageOutput]
webhooks: _containers.RepeatedCompositeFieldContainer[_models.WebhookConfig]
def __init__(self, room_name: _Optional[str] = ..., identity: _Optional[str] = ..., screen_share: bool = ..., preset: _Optional[_Union[EncodingOptionsPreset, str]] = ..., advanced: _Optional[_Union[EncodingOptions, _Mapping]] = ..., file_outputs: _Optional[_Iterable[_Union[EncodedFileOutput, _Mapping]]] = ..., stream_outputs: _Optional[_Iterable[_Union[StreamOutput, _Mapping]]] = ..., segment_outputs: _Optional[_Iterable[_Union[SegmentedFileOutput, _Mapping]]] = ..., image_outputs: _Optional[_Iterable[_Union[ImageOutput, _Mapping]]] = ..., webhooks: _Optional[_Iterable[_Union[_models.WebhookConfig, _Mapping]]] = ...) -> None: ...
modern-city-48224
09/11/2025, 6:23 PMtall-airline-16756
09/11/2025, 6:24 PMParticipantEgressRequest
for audio-only egress with OGG output together. Here’s a simple step-by-step guide:
1. Use EncodedFileOutput
with `file_type=OGG`: This will make sure your output is audio-only since OGG format supports audio perfectly.
2. Specify a file path and destination: You’ll want to set a filepath
that ends with .ogg
and also configure where to upload it (like an S3 bucket).
3. Optionally customize audio encoding: If you want to tweak audio details like bitrate or codec, you can use EncodingOptions
to get it just right.
4. Start the egress: Finally, use the SDK’s method to kick off the egress with your setup.
Here’s an example in Python to help you visualize it:
from livekit import api
file_output = api.EncodedFileOutput(
file_type=api.EncodedFileType.OGG,
filepath="recordings/audio-only.ogg",
s3=api.S3Upload(
bucket="your-bucket",
region="your-region",
access_key="your-access-key",
secret="your-secret-key"
),
)
req = api.ParticipantEgressRequest(
room_name="your-room",
identity="participant-identity",
file_outputs=[file_output]
)
lkapi = api.LiveKitAPI()
res = await lkapi.egress.start_participant_egress(req)
await lkapi.aclose()
Just a quick note: unlike RoomCompositeEgressRequest
, ParticipantEgressRequest
doesn’t have an audio_only
field. But by setting file_type=OGG
, you’re all set to record audio only. If anything feels unclear or you want to dive deeper, I’m here to help—just let me know!