fix: label .webm as audio/webm in audio transcription

process_audio_file only ever handles audio for transcription, but it derived
the MIME type from the file extension via get_file_mime_type_from_extension,
which returns the video-biased "video/webm". Vertex Gemini transcription then
sends inlineData.mimeType: video/webm and returns an empty transcript for
audio-only webm uploads (browser MediaRecorder output).

Override the webm extension to audio/webm in this audio-only helper. Other
audio containers (ogg, m4a) already resolve to audio/*.

Fixes #38963
This commit is contained in:
SWAPI03 2026-09-04 09:41:05 +05:30
parent 8fc0663198
commit 409de2fe2f
2 changed files with 32 additions and 1 deletions

View file

@ -4,7 +4,9 @@ Utils used for litellm.transcription() and litellm.atranscription()
import hashlib
import os
from collections.abc import Mapping
from dataclasses import dataclass
from types import MappingProxyType
from typing import Final
from litellm.types.files import (
@ -16,6 +18,13 @@ from litellm.types.files import (
)
from litellm.types.utils import FileTypes
# webm is an audio/video container; get_file_mime_type_from_extension returns
# "video/webm", but this helper only ever handles audio for transcription, so a
# .webm upload is audio. Labeling it video/webm makes Vertex Gemini
# transcription return an empty transcript.
# https://github.com/BerriAI/litellm/issues/38963
_AUDIO_CONTAINER_MIME_OVERRIDES: Final[Mapping[str, str]] = MappingProxyType({"webm": "audio/webm"})
@dataclass
class ProcessedAudioFile:
@ -121,7 +130,9 @@ def process_audio_file(audio_file: FileTypes) -> ProcessedAudioFile:
try:
# Extract extension from filename
extension: Final = filename.split(".")[-1].lower() if "." in filename else "wav"
content_type = get_file_mime_type_from_extension(extension)
content_type = _AUDIO_CONTAINER_MIME_OVERRIDES.get(extension) or get_file_mime_type_from_extension(
extension
)
except ValueError:
# If extension is not recognized, fallback to audio/wav
content_type = "audio/wav"

View file

@ -0,0 +1,20 @@
from litellm.litellm_core_utils.audio_utils.utils import process_audio_file
def test_process_audio_file_labels_webm_as_audio():
# Regression for https://github.com/BerriAI/litellm/issues/38963: webm is an
# audio/video container and process_audio_file is audio-only, so a .webm
# upload must be audio/webm. video/webm makes Vertex Gemini transcription
# return an empty transcript
processed = process_audio_file(("speech.webm", b"\x1aE\xdf\xa3"))
assert processed.content_type == "audio/webm"
def test_process_audio_file_keeps_known_audio_extension():
processed = process_audio_file(("speech.wav", b"RIFF"))
assert processed.content_type == "audio/wav"
def test_process_audio_file_unknown_extension_falls_back_to_wav():
processed = process_audio_file(("recording.unknownext", b"x"))
assert processed.content_type == "audio/wav"