Download app.py from apoastron/ffmpeg: direct link, hf CLI and curl.
- Browser
- Download file 2.13 kB
-
https://huggingface.co/spaces/apoastron/ffmpeg/resolve/main/app.py
- Command line
-
hf download hf://spaces/apoastron/ffmpeg/app.py
-
curl -L -o app.py https://huggingface.co/spaces/apoastron/ffmpeg/resolve/main/app.py
2.13 kB
| from fastapi import FastAPI, UploadFile, File, Form, HTTPException | |
| from fastapi.responses import StreamingResponse | |
| import subprocess | |
| import io | |
| import os | |
| from typing import Optional | |
| from urllib.parse import urlparse | |
| app = FastAPI() | |
| async def process_image( | |
| file: Optional[UploadFile] = File(None), | |
| url: Optional[str] = Form(None), | |
| options: Optional[str] = Form("-q:v 2"), | |
| filename: Optional[str] = Form(None) # 新增:支持自定义文件名 | |
| ): | |
| input_source = "" | |
| input_data = None | |
| # 1. 确定输入源 | |
| if file: | |
| input_data = await file.read() | |
| input_source = "pipe:0" | |
| # 如果没传 filename,则使用上传文件的原始名,但后缀改为 .jpg | |
| if not filename: | |
| filename = os.path.splitext(file.filename)[0] + ".jpg" | |
| elif url: | |
| input_source = url | |
| # 如果没传 filename,从 URL 中解析文件名,后缀改为 .jpg | |
| if not filename: | |
| path = urlparse(url).path | |
| base_name = os.path.basename(path) or "downloaded_image" | |
| filename = os.path.splitext(base_name)[0] + ".jpg" | |
| else: | |
| raise HTTPException(status_code=400, detail="Missing source") | |
| # 2. 执行 FFmpeg 转换 (PNG -> JPG) | |
| command = ['ffmpeg', '-i', input_source] | |
| if options: | |
| command.extend(options.split()) | |
| command.extend(['-f', 'image2', 'pipe:1']) | |
| try: | |
| process = subprocess.Popen( | |
| command, | |
| stdin=subprocess.PIPE if input_data else None, | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.PIPE | |
| ) | |
| out, err = process.communicate(input=input_data) | |
| # 3. 构建响应,添加 Content-Disposition Header | |
| # 这会让 n8n 和浏览器识别出文件名 | |
| headers = { | |
| 'Content-Disposition': f'attachment; filename="{filename}"' | |
| } | |
| return StreamingResponse( | |
| io.BytesIO(out), | |
| media_type="image/jpeg", | |
| headers=headers | |
| ) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) |