import asyncio try: asyncio.get_running_loop() except RuntimeError: asyncio.run(asyncio.sleep(0)) # Ensures an event loop is created before Streamlit starts import streamlit as st from main import main import os import subprocess from huggingface_hub import InferenceClient import google.generativeai as genai from dotenv import load_dotenv load_dotenv() # Load API Keys từ biến môi trường HF_TOKEN = os.getenv("HF_TOKEN") # Hugging Face API Key GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") # Google API Key genai.configure(api_key=GOOGLE_API_KEY) client = InferenceClient(provider="hf-inference", api_key=HF_TOKEN) # Định nghĩa đường dẫn video đầu ra OUTPUT_VIDEO_PATH = "./final_output.mp4" OUTPUT_VIDEO_FIXED_PATH = "./final_output_fixed.mp4" # Tiêu đề ứng dụng st.set_page_config(page_title="KnowFlow", page_icon="📖") st.markdown("

📖 KnowFlow 🌊

", unsafe_allow_html=True) st.markdown("

Convert documents into videos with AI-powered storytelling

", unsafe_allow_html=True) # Thông tin tác giả st.markdown("---") st.markdown("👨‍💻 **Author:** Nguyễn Trung Hiếu") st.markdown("🔗 [GitHub Repository](https://github.com/hieunguyen-cyber/KnowFlow.git)") st.markdown("---") # Upload file PDF uploaded_file = st.file_uploader("📂 Upload your document (PDF)", type=["pdf","docx"]) # Nếu có file, lưu vào thư mục tạm và lấy đường dẫn file_path = None if uploaded_file: file_path = f"./{uploaded_file.name}" with open(file_path, "wb") as f: f.write(uploaded_file.getbuffer()) # Lưu file thực tế number_of_images = st.slider("🖼️ Nhập số ảnh",1,10,3) # Cấu hình đầu vào gender = st.radio("🗣️ Select Voice Gender", options=["female", "male"]) # Nếu chọn giọng nam, vô hiệu hóa tốc độ (chỉ cho phép "normal") if gender == "male": speed = st.radio("⚡ Speech Speed (Male voice supports only normal)", options=["normal"], disabled=True) else: speed = st.radio("⚡ Speech Speed", options=["fast", "normal", "slow"]) analysis_level = st.radio("Analysis Level", options=["basic", "detailed"]) writting_style = st.radio("Writting Style", options = ["academic","popular","creative","humorous"]) # Tạo thanh trượt với giá trị từ 50 đến 250, bước nhảy 50 word_lower_limit, word_upper_limit = st.slider( "Chọn khoảng độ dài văn bản:", min_value=50, max_value=250, value=(50, 250), # Giá trị mặc định step=50 ) st.write(f"Giới hạn độ dài văn bản từ **{word_lower_limit}** đến **{word_upper_limit}** ký tự.") detail_level = st.radio("📖 Detail Level of Image Description", options=["short", "detailed"]) perspective = st.radio("🔎 Perspective", options=["subjective", "neutral"]) emotion = st.text_input("🎭 Emotion", placeholder="Example: mysterious, romantic,...") time_setting = st.text_input("⏳ Time Setting", placeholder="Example: modern, medieval,...") art_style = st.text_input("🖌️ Image Description Style", placeholder="Example: realistic, abstract,...") style = st.text_input("🎨 Image Style", placeholder="Example: realistic, anime,...") color_palette = st.text_input("🌈 Color Palette", placeholder="Example: vibrant, monochrome,...") def convert_audio_format(video_input, video_output): """Chuyển đổi định dạng âm thanh của video sang AAC.""" if not os.path.exists(video_input): raise FileNotFoundError(f"File '{video_input}' không tồn tại!") command = [ "ffmpeg", "-i", video_input, "-c:v", "copy", "-c:a", "aac", "-b:a", "192k", "-y", # Ghi đè nếu file output đã tồn tại video_output ] try: subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print(f"✅ Chuyển đổi thành công: {video_output}") except subprocess.CalledProcessError as e: print(f"❌ Lỗi khi chuyển đổi video: {e.stderr.decode()}") # Nút chạy pipeline if st.button("🚀 Generate Video"): if file_path and os.path.exists(file_path): st.success("⏳ Processing started...") main(file_path, analysis_level, writting_style, word_lower_limit, word_upper_limit, gender, speed, number_of_images, detail_level, perspective, emotion, time_setting, art_style, style, color_palette) # Kiểm tra xem video đã được tạo chưa if os.path.exists(OUTPUT_VIDEO_PATH): st.success("🎉 Video generated successfully!") # Chuyển đổi định dạng âm thanh convert_audio_format(OUTPUT_VIDEO_PATH, OUTPUT_VIDEO_FIXED_PATH) st.video(OUTPUT_VIDEO_FIXED_PATH) # Trình chiếu video # Tạo link tải về with open(OUTPUT_VIDEO_FIXED_PATH, "rb") as video_file: st.download_button(label="📥 Download Video", data=video_file, file_name="final_output_fixed.mp4", mime="video/mp4") else: st.error("⚠️ Video generation failed. Please check the logs.") else: st.error("⚠️ Please upload a valid PDF file.")