feat(notes): support vidéo + transcodage audio AAC universel
Audio : ffmpeg transcode toute entrée (webm/ogg/m4a) vers AAC/m4a au moment de l'upload → lecture Safari iOS garantie. Vidéo : nouveau save_video(), webm transcodé en H.264/mp4, mp4/quicktime stocké directement. Lecteur <video> inline dans NoteCard. Frontend : - Bouton vidéo (fa-video) dans les actions de chaque note - Icônes fa-image / fa-microphone / fa-video / fa-location-dot dans la méta - Filtres rapides : Photo / Audio / Vidéo / GPS (avec icônes fa) - Boutons actions migrés vers icônes Font Awesome - client_max_body_size nginx : 15m → 200m pour les vidéos v0.5.4 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ from app.core.database import get_session
|
||||
from app.core.redis import enqueue
|
||||
from app.models.notes import NoteItem, NoteAttachment
|
||||
from app.schemas.notes import NoteCreate, NoteUpdate, NoteResponse
|
||||
from app.services.media import save_image, save_audio, delete_media, ALLOWED_IMAGE_TYPES, ALLOWED_AUDIO_PREFIXES
|
||||
from app.services.media import save_image, save_audio, save_video, delete_media, ALLOWED_IMAGE_TYPES, ALLOWED_AUDIO_PREFIXES, ALLOWED_VIDEO_TYPES
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -21,6 +21,7 @@ async def list_notes(
|
||||
tag: str | None = Query(default=None),
|
||||
has_photo: bool | None = Query(default=None),
|
||||
has_audio: bool | None = Query(default=None),
|
||||
has_video: bool | None = Query(default=None),
|
||||
has_gps: bool | None = Query(default=None),
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
@@ -55,15 +56,11 @@ async def list_notes(
|
||||
notes = result.scalars().all()
|
||||
|
||||
if has_photo is not None:
|
||||
notes = [
|
||||
n for n in notes
|
||||
if has_photo == any(a.file_type == "image" for a in n.attachments)
|
||||
]
|
||||
notes = [n for n in notes if has_photo == any(a.file_type == "image" for a in n.attachments)]
|
||||
if has_audio is not None:
|
||||
notes = [
|
||||
n for n in notes
|
||||
if has_audio == any(a.file_type == "audio" for a in n.attachments)
|
||||
]
|
||||
notes = [n for n in notes if has_audio == any(a.file_type == "audio" for a in n.attachments)]
|
||||
if has_video is not None:
|
||||
notes = [n for n in notes if has_video == any(a.file_type == "video" for a in n.attachments)]
|
||||
|
||||
return notes
|
||||
|
||||
@@ -137,6 +134,9 @@ async def add_attachment(
|
||||
elif ct in ALLOWED_AUDIO_PREFIXES:
|
||||
media = await save_audio(file)
|
||||
file_type = "audio"
|
||||
elif ct in ALLOWED_VIDEO_TYPES:
|
||||
media = await save_video(file)
|
||||
file_type = "video"
|
||||
else:
|
||||
raise HTTPException(400, f"Type non supporté : {file.content_type}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user