Spaces:
Paused
Paused
File size: 6,173 Bytes
c16a803 d6ab5d0 07853df 6312c58 998c128 956b26b e111c44 2569d41 eab3b6a 75926ea a56389b 065d626 6312c58 eab3b6a 2569d41 eab3b6a 2569d41 eab3b6a c16a803 40446f2 0343e3e 7028765 956b26b e111c44 6c154f8 c16a803 6c154f8 79683ca 07853df 79683ca c047e75 e4ed31e cbd85fc 6312c58 6c154f8 3c753ee 07853df 1cec1d6 6c154f8 79683ca 68e8422 6ae4e58 30f78b0 68e8422 089efa9 1cec1d6 089efa9 6312c58 30f78b0 e9309ff 089efa9 e9309ff 089efa9 08bc846 d7f009b 1828f72 07853df f34662a 6ae4e58 f34662a 0212a08 0343e3e 2d3ac4b 0343e3e 1794bc0 bd750f5 2d3ac4b 5a36eaa 0343e3e 1794bc0 78bfc84 1794bc0 b14e2a2 1794bc0 30f78b0 1794bc0 1229389 2d3ac4b 1229389 68e8422 1794bc0 30f78b0 f56e978 e111c44 1cec1d6 d7f009b 1cec1d6 b14e2a2 1cec1d6 d7f009b e111c44 78bfc84 998c128 8913cb5 08bc846 998c128 6c154f8 6ae4e58 68299e3 08bc846 998c128 4d4e03c 0c7d1ac 6ae4e58 1229389 99535b7 5a3efb4 998c128 |
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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
import logging
import requests
from urllib.parse import urlparse, quote_plus
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 = [4320, 2160, 1440, 1080, 720, 480, 360, 240]
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 / f"{Path(input_path).stem}_{res}p.m3u8"
return output_path
def create_master_playlist(output_paths, input_filename):
master_playlist_path = output_dir / f"{input_filename}_master_playlist.m3u8"
with open(master_playlist_path, "w") as f:
f.write("#EXTM3U\n")
for path in output_paths:
res = Path(path).stem.split("_")[1]
f.write(f'#EXT-X-STREAM-INF:BANDWIDTH=8000000,RESOLUTION={res}\n')
# read the .m3u8 file and replace relative links with absolute links
with open(path, 'r') as playlist_file:
content = playlist_file.readlines()
content = [line.replace('.ts', f'.ts\n') if line.endswith('.ts\n') else line for line in content]
content = [f"{quote_plus(line.rstrip())}\n" if line.endswith('.ts\n') else line for line in content]
f.writelines(content)
return master_playlist_path
def upload_file_to_s3(file_path, s3_path):
print(f"Uploading {file_path} to AWS at {s3_path}")
with open(file_path, 'rb') as file:
file_content = file.read()
with fs.open(s3_path, 'wb') as file:
file.write(file_content)
def convert_video(video_file, quality, aspect_ratio, video_url):
# Ensure either a file or a URL is provided
if not video_file and not video_url:
raise ValueError("Please provide either a video file or a 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]
# Get the original height to avoid upscaling
original_height = video.size[1]
output_paths = []
for res in reversed(standard_resolutions):
if res > original_height:
continue
scale = "-1:" + str(res)
output_path = get_output_path(input_path, str(res) + 'p')
# use a lower CRF value for better quality
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, Path(input_path).stem)
output_paths.append(master_playlist_path)
output_links = []
for path in output_paths:
s3_path = f"s3://{AWS_S3_BUCKET}/{Path(input_path).stem}/{Path(path).name}"
upload_file_to_s3(path, s3_path)
output_links.append(f'<a href="https://{AWS_S3_BUCKET}.s3.amazonaws.com/{Path(input_path).stem}/{quote_plus(Path(path).name)}" target="_blank">Download {Path(path).stem}</a>')
# upload ts files to s3
for path in output_dir.glob(f"{Path(input_path).stem}_*p_*.ts"):
s3_path = f"s3://{AWS_S3_BUCKET}/{Path(input_path).stem}/{Path(path).name}"
upload_file_to_s3(path, s3_path)
output_html = "<br>".join(output_links)
return output_html
video_file = gr.inputs.File(label="Your video file")
quality = gr.inputs.Slider(minimum=0, maximum=51, default=23, label="Quality (0: Highest Quality - 50: Fastest)")
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 in nearhub.club.",
allow_flagging='never'
)
start_http_server()
interface.launch(server_name=get_ip_address(), server_port=7860) |