File size: 4,499 Bytes
0978387 a909c5f 0978387 a909c5f 0978387 a909c5f 0978387 f74ada5 a909c5f 0978387 a909c5f 0978387 285564b 0978387 285564b 0978387 285564b 0978387 a909c5f 0978387 a909c5f 0978387 a909c5f 0978387 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
from fastapi import APIRouter, HTTPException, BackgroundTasks
import tempfile
import os
import logging
import asyncio
from .Schema import YouTubeUploadTask
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/youtube", tags=["youtube"])
async def download_file(url: str) -> str:
"""Download file from URL using aria2c."""
try:
# Create temp directory for download
temp_dir = tempfile.mkdtemp()
temp_path = os.path.join(
temp_dir, "video"
) # aria2c will add extension automatically
# Build aria2c command
command = [
"aria2c",
"--allow-overwrite=true",
"--auto-file-renaming=false",
"--max-connection-per-server=16",
"--split=16",
"--dir",
temp_dir,
"--out",
"video",
url,
]
logger.info(f"Starting download with aria2c: {url}")
process = await asyncio.create_subprocess_exec(
*command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await process.communicate()
if process.returncode != 0:
raise Exception(f"Download failed: {stderr.decode()}")
# Find the downloaded file (aria2c adds extension automatically)
downloaded_files = os.listdir(temp_dir)
if not downloaded_files:
raise Exception("No file downloaded")
downloaded_file = os.path.join(temp_dir, downloaded_files[0])
logger.info(f"Download completed: {downloaded_file}")
return downloaded_file
except Exception as e:
logger.error(f"Error downloading file: {str(e)}")
raise HTTPException(status_code=500, detail=f"File download failed: {str(e)}")
async def upload_video_background(task: YouTubeUploadTask):
"""Background task to handle video upload."""
temp_dir = None
try:
# Convert HttpUrl to string
url = str(task.filename)
logger.info(f"Starting download for video: {url}")
downloaded_file = await download_file(url)
temp_dir = os.path.dirname(downloaded_file)
logger.info(f"Download complete. Saved to: {downloaded_file}")
# Build the command
command = [
"/srv/youtube/youtubeuploader",
"-filename",
downloaded_file,
"-title",
task.title,
"-description",
task.description,
"-categoryId",
task.category_id,
"-privacy",
task.privacy,
"-tags",
task.tags,
]
if task.thumbnail:
command.extend(["-thumbnail", task.thumbnail])
logger.info("Executing upload command")
process = await asyncio.create_subprocess_exec(
*command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await process.communicate()
if process.returncode != 0:
logger.error(f"Upload failed: {stderr.decode()}")
raise Exception(f"Upload failed: {stderr.decode()}")
logger.info("Upload completed successfully")
logger.debug(f"Upload output: {stdout.decode()}")
except Exception as e:
logger.error(f"Error in upload process: {str(e)}")
raise
finally:
# Clean up temp directory and its contents
if temp_dir and os.path.exists(temp_dir):
try:
for file in os.listdir(temp_dir):
os.remove(os.path.join(temp_dir, file))
os.rmdir(temp_dir)
logger.info(f"Cleaned up temporary directory: {temp_dir}")
except Exception as e:
logger.error(f"Failed to clean up temp directory: {str(e)}")
@router.post("/upload")
async def upload_video_to_youtube(
task: YouTubeUploadTask, background_tasks: BackgroundTasks
):
"""
Endpoint to handle YouTube video upload requests.
The actual upload is performed as a background task.
"""
try:
background_tasks.add_task(upload_video_background, task)
return {"message": "Upload task started", "status": "processing"}
except Exception as e:
logger.error(f"Error initiating upload task: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
|