mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-09 10:19:26 +00:00
✨(summary) extended support for all video/audio files
* Removed constraint on file extension * Infer audio/video streams from the media with ffmpeg * Infer the correct processed audio file extension based on actual codec to avoid ffmpeg errors We need to support more extensions and make audio extraction dynamic, as we shipped transcript in production and it led to user complaints requesting more formats.
This commit is contained in:
committed by
aleb_the_flash
parent
bf69cbc14e
commit
ec688e728d
@@ -4,27 +4,121 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from summary.core.file_service import get_media_duration
|
||||
from summary.core.file_service import (
|
||||
MediaInfo,
|
||||
extract_audio_from_video,
|
||||
get_media_info,
|
||||
)
|
||||
|
||||
BASE_PATH = Path(__file__).parent.parent / "assets"
|
||||
|
||||
MEDIA_INFO_SAMPLE_VISIO = MediaInfo(
|
||||
path=BASE_PATH / "video-sample-visio.mp4",
|
||||
has_audio=True,
|
||||
has_video=True,
|
||||
audio_duration_seconds=5.34059,
|
||||
audio_codec_name="aac",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"filename, duration",
|
||||
"media_info",
|
||||
[
|
||||
("audio-sample-android-chrome.webm", 2.2795),
|
||||
("audio-sample-android-firefox.ogg", 2.3025),
|
||||
("audio-sample-android.m4a", 1.38),
|
||||
("audio-sample-chromium.webm", 2.65),
|
||||
("audio-sample-firefox.ogg", 2.0865),
|
||||
("audio-sample-ios-browser.webm", 2.6229),
|
||||
("audio-sample-ios.m4a", 1.408),
|
||||
("audio-sample-mac-os-safari.webm", 2.3049),
|
||||
("video-sample-visio.mp4", 5.34059),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-android-chrome.webm",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=2.2795,
|
||||
audio_codec_name="opus",
|
||||
),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-android-firefox.ogg",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=2.3025,
|
||||
audio_codec_name="opus",
|
||||
),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-android.m4a",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=1.38,
|
||||
audio_codec_name="aac",
|
||||
),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-chromium.webm",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=2.65,
|
||||
audio_codec_name="opus",
|
||||
),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-firefox.ogg",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=2.0865,
|
||||
audio_codec_name="opus",
|
||||
),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-ios-browser.webm",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=2.6229,
|
||||
audio_codec_name="opus",
|
||||
),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-ios.m4a",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=1.408,
|
||||
audio_codec_name="aac",
|
||||
),
|
||||
MediaInfo(
|
||||
path=BASE_PATH / "audio-sample-mac-os-safari.webm",
|
||||
has_audio=True,
|
||||
has_video=False,
|
||||
audio_duration_seconds=2.3049,
|
||||
audio_codec_name="opus",
|
||||
),
|
||||
MEDIA_INFO_SAMPLE_VISIO,
|
||||
],
|
||||
)
|
||||
def test_validate_duration_supports_all_used_file_formats(
|
||||
filename: str, duration: float
|
||||
def test_validate_media_info_supports_all_used_file_formats(
|
||||
media_info: MediaInfo,
|
||||
) -> None:
|
||||
"""Validate duration for Safari iPhone WebM files without format duration."""
|
||||
audio_path = Path(__file__).parent.parent / "assets" / filename
|
||||
"""Validate media_info for different files that the service can handle."""
|
||||
res = get_media_info(media_info.path)
|
||||
assert res.has_audio == media_info.has_audio
|
||||
assert res.has_video == media_info.has_video
|
||||
assert res.audio_codec_name == media_info.audio_codec_name
|
||||
if res.has_audio:
|
||||
assert res.audio_duration_seconds == pytest.approx(
|
||||
media_info.audio_duration_seconds, 1e-3
|
||||
)
|
||||
else:
|
||||
assert res.audio_duration_seconds is None
|
||||
|
||||
assert get_media_duration(audio_path) == pytest.approx(duration, 1e-3)
|
||||
|
||||
def test_media_info_invalid_file() -> None:
|
||||
"""Test that media_info returns correct values for invalid files."""
|
||||
assert get_media_info(Path(__file__)) == MediaInfo(
|
||||
path=Path(__file__),
|
||||
has_audio=False,
|
||||
has_video=False,
|
||||
audio_duration_seconds=None,
|
||||
audio_codec_name=None,
|
||||
)
|
||||
|
||||
|
||||
def test_extract_audio_from_video():
|
||||
"""Test that extract_audio_from_video can extract audio from a video file."""
|
||||
path = None
|
||||
# A bit of cleanup logic since this is not a generator
|
||||
try:
|
||||
path = extract_audio_from_video(MEDIA_INFO_SAMPLE_VISIO)
|
||||
assert path.name.endswith(".m4a")
|
||||
except Exception as e:
|
||||
pytest.fail(f"Failed to extract audio from video: {e}")
|
||||
finally:
|
||||
if path and path.exists():
|
||||
path.unlink()
|
||||
|
||||
Reference in New Issue
Block a user