mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
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:
parent
8fc0663198
commit
409de2fe2f
2 changed files with 32 additions and 1 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
Loading…
Add table
Reference in a new issue