File size: 5,248 Bytes
e62cec6
 
 
 
 
 
 
 
 
 
 
 
 
58e96a5
e62cec6
58e96a5
4fdaf10
 
 
e62cec6
 
 
 
0c65dab
 
e62cec6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0c65dab
e62cec6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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("<h1 style='text-align: center;'>📖 KnowFlow 🌊</h1>", unsafe_allow_html=True)
st.markdown("<h4 style='text-align: center;'>Convert documents into videos with AI-powered storytelling</h4>", 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.")