import os import zipfile import random import base64 from others import * import streamlit as st from io import BytesIO from moviepy.editor import vfx from streamlit_option_menu import option_menu from youtube import youtube, download_youtube from moviepy.video.io.VideoFileClip import VideoFileClip def session(info_list): st.video(info_list[1]) st.text(f"Video Information: {info_list[0]}") if len(info_list) == 5: st.text(f"Duration: {info_list[3]} - {info_list[4]} seconds") def random_cuts(video_file, title, num_cuts=1, duration=60, speed_factor=1.0, mute_audio=False, use_aspect_ratio=None): clip = VideoFileClip(video_file) total_duration = clip.duration cuts = [] for _ in range(num_cuts): start_time = random.uniform(0, max(total_duration - duration, 0)) end_time = min(start_time + duration, total_duration) cuts.append((start_time, end_time)) output_files = [] prev_end_time = 0 for i, (start_time, end_time) in enumerate(cuts): if start_time == prev_end_time: continue output_file = f"{title}_cut_{i+1}.mp4" clipped_clip = clip.subclip(start_time, end_time) if mute_audio: clipped_clip = clipped_clip.set_audio(None) clipped_clip = clipped_clip.fx(vfx.speedx, speed_factor) if use_aspect_ratio: original_width, original_height = clip.size if use_aspect_ratio == '16:9': target_ratio = 16 / 9 elif use_aspect_ratio == '9:16': target_ratio = 9 / 16 elif use_aspect_ratio == '21:9': target_ratio = 21 / 9 else: target_ratio = 16 / 9 if use_aspect_ratio: original_width, original_height = clip.size if use_aspect_ratio == '21:9': target_ratio = 21 / 9 else: target_ratio = 16 / 9 if use_aspect_ratio == '16:9' else 9 / 16 target_width = int(original_height * target_ratio) target_height = original_height if use_aspect_ratio == '21:9': target_height = int(original_width / target_ratio) margin = (original_height - target_height) // 2 clipped_clip = clipped_clip.crop(y1=margin, y2=original_height - margin) else: margin = (original_width - target_width) // 2 clipped_clip = clipped_clip.crop(x1=margin, x2=original_width - margin) with st.spinner(f'Procesando video {i+1} de {num_cuts}...'): clipped_clip.write_videofile(output_file, codec="libx264", audio_codec="aac", verbose=False) output_files.append(output_file) prev_end_time = end_time return output_files, cuts def download_all_button(cut_files): zip_buffer = BytesIO() with zipfile.ZipFile(zip_buffer, 'w') as zip_file: for cut_file in cut_files: zip_file.write(cut_file, os.path.basename(cut_file)) zip_filename = 'cortes_videos.zip' zip_data = zip_buffer.getvalue() b64 = base64.b64encode(zip_data).decode() href = f'Descargar Todos' st.markdown(href, unsafe_allow_html=True) opciones = ['YouTube'] with st.sidebar: seleccionado = option_menu("Descargador", opciones, icons=['play'], menu_icon="cast", default_index=0) funciones = [youtube] if seleccionado: indice = opciones.index(seleccionado) funcion = funciones[indice] st.title(f"{seleccionado} Descargador de Videos") st.write(f"Descarga y corta una parte aleatoria de {seleccionado}.") video_link = st.text_input("Enlace del Video", value='https://www.youtube.com/watch?v=urhsbKIF9pE') aspect_ratio_options = ['16:9', '9:16', '21:9'] aspect_ratio_choice = st.selectbox('Seleccionar Proporción:', aspect_ratio_options, index=2) resolution_options = [144, 240, 360, 720] resolution_choice = st.selectbox('Seleccionar Resolución:', resolution_options, index=2) choice = st.radio('Seleccionar Proceso:', ['Cortar Video', 'Descargar Completo'], 1) if choice == 'Cortar Video': num_cuts = st.slider('Seleccionar número de cortes', 1, 10, 1) duration_minutes_slider = st.slider('Seleccionar duración de los cortes (minutos)', 1, 180, 1) duration_seconds = duration_minutes_slider * 60 speed_factor = st.slider('Seleccionar velocidad del video', -2.0, 3.0, 1.0) mute_audio = st.checkbox('Eliminar sonido de los videos cortados') if st.button(f"Descargar y Cortar {seleccionado}"): video_file, titulo_video, video_info, thumbnail_file = funcion(video_link, resolusi_input=resolution_choice) cut_files, cuts = random_cuts(video_file, titulo_video, num_cuts=num_cuts, duration=duration_seconds, speed_factor=speed_factor, mute_audio=mute_audio, use_aspect_ratio=aspect_ratio_choice) for i, cut_file in enumerate(cut_files): file_size = os.path.getsize(cut_file) info_list = [f"{titulo_video}_cut_{i+1}", cut_file, thumbnail_file, cuts[i][0], cuts[i][1]] session(info_list) download_all_button(cut_files)