KSL_Translator / main.py
Hermit11's picture
Update main.py
525cc78 verified
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import cv2
import numpy as np
import requests
import tempfile
import os
from typing import List
import logging
import urllib3
import vimeo
# Suppress only the single InsecureRequestWarning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
app = FastAPI()
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class VideoURLs(BaseModel):
urls: List[str]
MAX_VIDEOS = 1010
# Vimeo API credentials
VIMEO_ACCESS_TOKEN = "35b24d71f540bfa24e61d488cf34e457" # Replace with your Vimeo token
VIMEO_UPLOAD_URL = "https://api.vimeo.com/me/videos"
def download_video(url):
try:
response = requests.get(url, verify=False, timeout=30)
response.raise_for_status()
with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as tmp_file:
tmp_file.write(response.content)
return tmp_file.name
except requests.RequestException as e:
logger.error(f"Failed to download video from {url}: {str(e)}")
raise Exception(f"Failed to download video from {url}: {str(e)}")
def combine_videos(urls):
if not urls:
return None
if len(urls) > MAX_VIDEOS:
raise HTTPException(status_code=400, detail=f"Maximum of {MAX_VIDEOS} videos allowed")
temp_files = []
for url in urls:
if url.strip():
# Check if it's a newline character
try:
temp_files.append(download_video(url.strip()))
except Exception as e:
logger.error(f"Error downloading video: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))
if not temp_files:
raise HTTPException(status_code=400, detail="No valid videos to combine")
try:
# Trim video to 400 milliseconds for newline characters
captures = [cv2.VideoCapture(file) for file in temp_files]
fps = captures[0].get(cv2.CAP_PROP_FPS)
frame_size = (int(captures[0].get(cv2.CAP_PROP_FRAME_WIDTH)),
int(captures[0].get(cv2.CAP_PROP_FRAME_HEIGHT)))
output_path = 'combined_video.mp4'
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, frame_size)
for cap in captures:
while True:
ret, frame = cap.read()
if not ret:
break
out.write(frame)
for cap in captures:
cap.release()
out.release()
for file in temp_files:
os.remove(file)
return output_path
except Exception as e:
logger.error(f"Error combining videos: {str(e)}")
raise HTTPException(status_code=500, detail=f"Error combining videos: {str(e)}")
def upload_to_vimeo(video_path):
try:
# Step 1: Request an upload link (initialize the upload)
headers = {
'Authorization': f'Bearer {VIMEO_ACCESS_TOKEN}',
'Content-Type': 'application/json',
'Accept': 'application/vnd.vimeo.*+json;version=3.4'
}
# Video metadata and upload initialization
upload_data = {
'upload': {
'approach': 'tus', # Use the 'tus' approach for large file uploads
'size': os.path.getsize(video_path)
},
'name': 'Uploaded Video',
'description': 'This video was uploaded using the Vimeo Upload API.'
}
# Send request to create an upload ticket
response = requests.post(VIMEO_UPLOAD_URL, json=upload_data, headers=headers)
response.raise_for_status()
vimeo_data = response.json()
# Extract the upload link
upload_link = vimeo_data['upload']['upload_link']
video_uri = vimeo_data['uri'] # Used to get the video link after upload
# Step 2: Upload the video file using the provided upload link
tus_headers = {
'Tus-Resumable': '1.0.0',
'Upload-Offset': '0',
'Content-Type': 'application/offset+octet-stream',
'Authorization': f'Bearer {VIMEO_ACCESS_TOKEN}'
}
with open(video_path, 'rb') as video_file:
tus_response = requests.patch(upload_link, headers=tus_headers, data=video_file)
tus_response.raise_for_status()
# Step 3: Confirm the upload and retrieve the Vimeo video link
video_response = requests.get(f"https://api.vimeo.com{video_uri}?fields=link", headers=headers)
video_response.raise_for_status()
video_link = video_response.json()['link']
print(f"Video uploaded successfully: {video_link}")
return video_link
except requests.RequestException as e:
print(f"Error uploading video to Vimeo: {str(e)}")
raise
@app.post("/combine_videos")
async def process_urls(video_urls: VideoURLs):
try:
combined_video_path = combine_videos(video_urls.urls)
if combined_video_path:
vimeo_url = upload_to_vimeo(combined_video_path)
os.remove(combined_video_path) # Clean up the local file
return {"vimeo_url": vimeo_url}
else:
raise HTTPException(status_code=400, detail="Failed to combine videos")
except HTTPException as he:
logger.error(f"HTTP Exception: {str(he)}")
raise he
except Exception as e:
logger.error(f"Unexpected error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8080)