• Stefy Lanza (nextime / spora )'s avatar
    keep the sound, the shape and the uploaded file when editing media (v0.4.86) · 965e8cdb
    Stefy Lanza (nextime / spora ) authored
    Four ways an edit could answer 200 while quietly doing the wrong thing.
    
    The enhancement paths decode a clip to frames and encode a new video, so the
    audio was left behind: a clip that arrived with speech came back silent. Only
    the ffmpeg minterpolate fallback -- the path nobody takes by default -- ever
    kept it. _mux_original_audio() puts the track back on all three in-process
    paths, stream-copied where MP4 accepts the codec and re-encoded to AAC where it
    does not. Both paths already preserve the source duration, so nothing is
    stretched. A silent source, or a remux PyAV cannot do, returns the frames
    unchanged rather than losing a finished GPU job.
    
    The image and video editing endpoints took base64 (and, for video, an http
    URL), so a caller that had already uploaded a file had to re-send it on every
    edit -- megabytes a call for a file on the same disk. They now resolve through
    the compose resolver, so a /v1/files path or a sha256: upload id works
    everywhere, and our own files are read off disk instead of fetched back over a
    loopback that would need a token. Responses carry the relative path beside the
    url, as compose does, so a caller need not depend on the public hostname.
    
    Routing through that resolver would have tightened what callers may send: it
    validates base64 strictly, which rejects the 76-column wrapping that MIME, the
    base64 tool and encodebytes all produce. Whitespace carries no meaning in
    base64, so it is now stripped rather than refused.
    
    /v1/images/edits defaulted size to the string "1024x1024", so omitting it
    squashed every photo that was not square. Omitted now keeps the source's shape
    at the ~1 MP a diffusion model wants, on the 64-grid it needs.
    
    /v1/images/upscale fell through to PIL LANCZOS for an unrecognised model and
    still answered 200, charging for an AI upscale that never ran and returning
    something merely soft. That is a 400 naming the models that would work.
    Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01S8LAP3ueNzQJtwzhgVbq66
    965e8cdb
test_media_editing_refs_and_audio.py 19.5 KB