Spaces:
Running
Running
import streamlit as st | |
from huggingface_hub import HfApi | |
import os | |
import json | |
from datetime import datetime | |
import cv2 | |
import random | |
from PIL import Image | |
import string | |
import subprocess | |
import glob | |
import shutil | |
# Initialize the Hugging Face API with the token | |
api = HfApi(token=os.getenv("HF_API_TOKEN")) | |
def generate_random_string(length=4): | |
return ''.join(random.choices(string.ascii_lowercase, k=length)) | |
def add_random_to_filename(filename): | |
name, ext = os.path.splitext(filename) | |
random_string = generate_random_string() | |
return f"{name}-{random_string}{ext}" | |
def extract_thumbnail(video_path, thumbnail_path): | |
video = cv2.VideoCapture(video_path) | |
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) | |
random_frame = random.randint(0, total_frames - 1) | |
video.set(cv2.CAP_PROP_POS_FRAMES, random_frame) | |
success, frame = video.read() | |
if success: | |
cv2.imwrite(thumbnail_path, frame) | |
video.release() | |
return success | |
def save_custom_thumbnail(thumbnail_file, thumbnail_path): | |
img = Image.open(thumbnail_file) | |
img.save(thumbnail_path) | |
return True | |
def get_video_length(video_path): | |
video = cv2.VideoCapture(video_path) | |
fps = video.get(cv2.CAP_PROP_FPS) # Frames per second | |
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) # Total frames in the video | |
duration = int(total_frames / fps) if fps > 0 else 0 # Duration in seconds, as an integer | |
video.release() | |
return duration | |
def generate_metadata(video_name, title, description, uploader, file_location, thumbnail_location, duration): | |
return { | |
"fileName": video_name, | |
"title": title, | |
"description": description, | |
"uploader": uploader, | |
"uploadTimestamp": datetime.now().isoformat(), | |
"fileLocation": file_location, | |
"thumbnailLocation": thumbnail_location, | |
"duration": duration, # Add duration here | |
"views": 0, | |
"likes": 0 | |
} | |
def update_index_file(new_metadata_path): | |
# Create a temporary directory for cloning | |
temp_dir = "temp_repo" | |
if os.path.exists(temp_dir): | |
shutil.rmtree(temp_dir) | |
try: | |
# Clone the repository | |
subprocess.run(['git', 'clone', 'https://huggingface.co/spaces/vericudebuget/ok4231', temp_dir], check=True) | |
# Find all JSON files in the metadata directory | |
metadata_dir = os.path.join(temp_dir, 'metadata') | |
json_files = glob.glob(os.path.join(metadata_dir, '*-index.json')) | |
# Create the paths string | |
base_url = "huggingface.co/spaces/vericudebuget/ok4231/raw/main/metadata/" | |
paths = [f"{base_url}{os.path.basename(f)}" for f in json_files] | |
# Add the new metadata path if it's not already there | |
new_metadata_filename = os.path.basename(new_metadata_path) | |
new_full_path = f"{base_url}{new_metadata_filename}" | |
if new_full_path not in paths: | |
paths.append(new_full_path) | |
# Create the index content | |
index_content = "{ " + "; ".join(paths) + "; }" | |
# Write to a temporary file | |
index_path = os.path.join(temp_dir, 'metadata', 'video-index.json') | |
os.makedirs(os.path.dirname(index_path), exist_ok=True) | |
with open(index_path, 'w') as f: | |
f.write(index_content) | |
# Upload the index file | |
api.upload_file( | |
path_or_fileobj=index_path, | |
path_in_repo="metadata/video-index.json", | |
repo_id="vericudebuget/ok4231", | |
repo_type="space", | |
) | |
finally: | |
# Clean up | |
if os.path.exists(temp_dir): | |
shutil.rmtree(temp_dir) | |
def upload_video_to_hf(video_file, original_video_name, title, description, uploader, custom_thumbnail=None): | |
# Create temp paths | |
temp_dir = "temp" | |
if not os.path.exists(temp_dir): | |
os.makedirs(temp_dir) | |
try: | |
# Generate randomized filenames | |
video_name = add_random_to_filename(original_video_name) | |
video_path = os.path.join(temp_dir, video_name) | |
base_name = os.path.splitext(video_name)[0] | |
thumbnail_name = f"{base_name}_thumb.jpg" | |
thumbnail_path = os.path.join(temp_dir, thumbnail_name) | |
json_name = f"{base_name}-index.json" | |
json_path = os.path.join(temp_dir, json_name) | |
# Write the video content to a file | |
with open(video_path, "wb") as f: | |
f.write(video_file.read()) | |
# Handle thumbnail | |
if custom_thumbnail: | |
thumbnail_extracted = save_custom_thumbnail(custom_thumbnail, thumbnail_path) | |
else: | |
thumbnail_extracted = extract_thumbnail(video_path, thumbnail_path) | |
if not thumbnail_extracted: | |
st.error("Failed to process thumbnail") | |
return None | |
# Get video length | |
video_length = get_video_length(video_path) | |
# Upload the video | |
video_location = f"videos/{video_name}" | |
api.upload_file( | |
path_or_fileobj=video_path, | |
path_in_repo=video_location, | |
repo_id="vericudebuget/ok4231", | |
repo_type="space", | |
) | |
# Upload the thumbnail | |
thumbnail_location = f"thumbnails/{thumbnail_name}" | |
api.upload_file( | |
path_or_fileobj=thumbnail_path, | |
path_in_repo=thumbnail_location, | |
repo_id="vericudebuget/ok4231", | |
repo_type="space", | |
) | |
# Generate and upload metadata JSON | |
metadata = generate_metadata(video_name, title, description, uploader, video_location, thumbnail_location, video_length) | |
with open(json_path, "w") as f: | |
json.dump(metadata, f, indent=2) | |
metadata_location = f"metadata/{json_name}" | |
api.upload_file( | |
path_or_fileobj=json_path, | |
path_in_repo=metadata_location, | |
repo_id="vericudebuget/ok4231", | |
repo_type="space", | |
) | |
# Update the index file | |
update_index_file(metadata_location) | |
return metadata | |
finally: | |
# Cleanup temp files | |
if os.path.exists(temp_dir): | |
shutil.rmtree(temp_dir) | |
# Streamlit app interface | |
st.title("Upload your video") | |
st.markdown("---") | |
# File uploader for video input | |
uploaded_video = st.file_uploader("Choose video file", type=["mp4", "avi", "mov"]) | |
if uploaded_video: | |
# Show the video details form | |
with st.form("video_details"): | |
st.write("Video Details") | |
title = st.text_input("Title", placeholder="Enter video title") | |
description = st.text_area("Description", placeholder="Enter video description") | |
uploader = st.text_input("Uploader Name", placeholder="Enter your name") | |
# Optional custom thumbnail uploader | |
custom_thumbnail = st.file_uploader("Upload custom thumbnail (optional)", type=["jpg", "jpeg", "png"]) | |
# Upload button within the form | |
submit_button = st.form_submit_button("Upload Video") | |
if submit_button: | |
if not title or not uploader: | |
st.error("Please fill in the title and uploader name.") | |
else: | |
with st.spinner("Uploading video, generating thumbnail and metadata..."): | |
metadata = upload_video_to_hf( | |
uploaded_video, | |
uploaded_video.name, | |
title, | |
description, | |
uploader, | |
custom_thumbnail | |
) | |
if metadata: | |
st.success("Upload completed successfully!") | |
st.json(metadata) | |
else: | |
st.info("Please upload a video file to begin.") | |