baldator's picture
Update app.py
2569d41
raw
history blame
5.09 kB
import logging
import requests
from urllib.parse import urlparse
import subprocess
from pathlib import Path
from moviepy.editor import VideoFileClip
import gradio as gr
import http.server
import socketserver
import threading
import socket
import boto3
import s3fs
import os
# Define output directory
output_dir = Path.cwd() / "output"
output_dir.mkdir(exist_ok=True)
# Set S3 credentials
AWS_S3_BUCKET = os.getenv("AWS_S3_BUCKET")
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
session = boto3.Session(
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name='us-east-1'
)
s3 = session.client('s3')
fs = s3fs.S3FileSystem(anon=False, client_kwargs={'region_name': 'us-east-1'})
logging.basicConfig(level=logging.INFO)
standard_resolutions = [240, 360, 480, 720, 1080, 1440, 2160, 4320]
def start_http_server(port=8000):
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), handler)
logging.info(f"Serving at port {port}")
thread = threading.Thread(target=httpd.serve_forever)
thread.start()
def get_ip_address():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return IP
def download_file(url, destination):
response = requests.get(url)
response.raise_for_status()
with open(destination, 'wb') as f:
f.write(response.content)
def get_input_path(video_file, video_url):
if video_file is not None:
return Path(video_file.name)
elif video_url:
url_path = urlparse(video_url).path
file_name = Path(url_path).name
destination = output_dir / file_name
download_file(video_url, destination)
return destination
else:
raise ValueError("No input was provided.")
def get_output_path(input_path, res):
output_path = output_dir / (Path(input_path).stem + f"_{res}p.m3u8")
return output_path
def create_master_playlist(output_paths):
master_playlist_path = output_dir / "master_playlist.m3u8"
with open(master_playlist_path, "w") as f:
f.write("#EXTM3U\n")
for path in output_paths:
f.write(f'#EXT-X-STREAM-INF:BANDWIDTH=8000000,RESOLUTION={Path(path).stem.split("_")[1]}\n')
f.write(f'{Path(path).name}\n')
return master_playlist_path
def convert_video(video_file, quality, aspect_ratio, video_url):
input_path = get_input_path(video_file, video_url)
video = VideoFileClip(str(input_path))
# Get the original height to avoid upscaling
original_height = video.size[1]
output_paths = []
for res in standard_resolutions:
if res > original_height:
continue
scale = "-1:" + str(res)
output_path = get_output_path(input_path, str(res) + 'p')
ffmpeg_command = [
"ffmpeg", "-i", str(input_path), "-c:v", "libx264", "-crf", str(quality),
"-vf", f"scale={scale}:force_original_aspect_ratio=decrease,pad=ceil(iw/2)*2:ceil(ih/2)*2",
"-hls_time", "10", "-hls_playlist_type", "vod", "-hls_segment_filename",
str(output_dir / f"{output_path.stem}_%03d.ts"), str(output_path)
]
logging.info("Running ffmpeg command: " + ' '.join(ffmpeg_command))
subprocess.run(ffmpeg_command, check=True)
output_paths.append(output_path)
master_playlist_path = create_master_playlist(output_paths)
output_paths.append(master_playlist_path)
server_ip = get_ip_address()
output_links = []
for path in output_paths:
output_links.append(f'<a href="http://{server_ip}:8000{path}" target="_blank">Download {Path(path).stem}</a>')
print("Read local file")
with open(path, 'rb') as file:
file_content = file.read()
print("Upload " + Path(path).stem + " to AWS")
# fs.mv(str(output_dir / f"{output_path.stem}_%03d.ts"), f"s3://{AWS_S3_BUCKET}/{Path(path).stem}",)
with fs.open(f"s3://{AWS_S3_BUCKET}/{Path(path).stem}", 'wb') as file:
file.write(your_file_content)
output_html = "<br>".join(output_links)
return output_html
video_file = gr.inputs.File(label="Your video file")
quality = gr.inputs.Slider(minimum=1, maximum=50, label="Quality (1:Speed - 50:Quality)")
aspect_ratio = gr.inputs.Dropdown(["16:9", "4:3", "1:1", "3:4", "9:16", "1:1", "2:1", "1:2"], label="Aspect Ratio", default="16:9")
video_url = gr.inputs.Textbox(lines=1, placeholder="or paste video url here", label="Video URL")
interface = gr.Interface(
fn=convert_video,
inputs=[video_file, quality, aspect_ratio, video_url],
outputs=gr.outputs.HTML(label="Download Links"),
title="NEAR Hub Video Transcoder to m3u8",
description="convert video files to m3u8 for VOD streaming",
allow_flagging='never'
)
start_http_server()
interface.launch(server_name=get_ip_address(), server_port=7860)