File size: 5,969 Bytes
433cf79
 
 
bf6f372
433cf79
 
bf6f372
433cf79
 
 
e3f544b
433cf79
 
 
 
3af1854
433cf79
 
 
 
 
 
 
 
 
 
 
 
 
b8c56e5
433cf79
 
 
 
 
 
 
 
 
 
 
 
bf6f372
9b7d0e7
bf6f372
433cf79
 
 
 
 
 
 
 
 
 
 
2b0d0d6
433cf79
2b0d0d6
433cf79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2b0d0d6
433cf79
 
 
 
 
 
 
 
 
 
2b0d0d6
433cf79
 
b8c56e5
 
433cf79
 
 
 
 
3ff023a
433cf79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b8c56e5
 
bf6f372
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
import streamlit as st
import asyncio
import httpx
from pathlib import Path
import os
import base64

# Inicjalizacja katalogu wyj艣ciowego
OUTPUT_DIR = "generated_videos"
Path(OUTPUT_DIR).mkdir(parents=True, exist_ok=True)

# Aktualne URL dla API Hailuo
CREATE_URL = "https://api.minimaxi.chat/v1/video_generation"
STATUS_URL = "https://api.minimaxi.chat/v1/query/video_generation"
RETRIEVE_URL = "https://api.minimaxi.chat/v1/files/retrieve"

def encode_image(image_path):
    """Konwertuje obraz na base64."""
    with open(image_path, "rb") as image_file:
        encoded = base64.b64encode(image_file.read()).decode('utf-8')
        st.write(f"D艂ugo艣膰 base64 obrazu: {len(encoded)} znak贸w")  # Debugowanie
        return encoded

async def generate_video(api_key: str, prompt: str, optimize_prompt: bool = True, image: str = None) -> str:
    """Funkcja generuje film na podstawie promptu i opcjonalnego obrazu."""
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }

    data = {
        "model": "video-01",
        "prompt": prompt,
        "prompt_optimizer": optimize_prompt  # Dodana kontrola optymalizacji promptu
    }

    if image:
        if os.path.exists(image):  # Je艣li to plik, przekonwertuj na base64
            image = encode_image(image)
        data["first_frame_image"] = f"data:image/png;base64,{image}"  # Poprawione przekazywanie base64

    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(CREATE_URL, headers=headers, json=data, timeout=60.0)
            response.raise_for_status()
            response_data = response.json()

            st.write("**Pe艂na odpowied藕 API:**")
            st.json(response_data)  # Wy艣wietlanie pe艂nej odpowiedzi API

            task_id = response_data.get('task_id')
            if not task_id:
                st.error("Brak task_id w odpowiedzi API")
                return None

            max_retries = 60  # maksymalnie 10 minut przy 10s odst臋pie
            retry_count = 0

            while retry_count < max_retries:
                status_response = await client.get(f"{STATUS_URL}?task_id={task_id}", headers=headers)
                status_response.raise_for_status()
                status_data = status_response.json()
                status = status_data.get('status')

                if status == "Success":
                    file_id = status_data.get('file_id')
                    if not file_id:
                        st.error("Brak file_id w odpowiedzi API")
                        return None

                    retrieve_response = await client.get(f"{RETRIEVE_URL}?file_id={file_id}", headers=headers)
                    retrieve_response.raise_for_status()
                    retrieve_data = retrieve_response.json()
                    download_url = retrieve_data.get('file', {}).get('download_url')

                    if not download_url:
                        st.error("Nie mo偶na pobra膰 URL dla pliku")
                        return None

                    file_response = await client.get(download_url)
                    file_response.raise_for_status()
                    output_path = os.path.join(OUTPUT_DIR, "generated_video.mp4")
                    with open(output_path, 'wb') as f:
                        f.write(file_response.content)

                    return output_path
                elif status == "Fail":
                    st.error(f"Generowanie filmu nie powiod艂o si臋: {status_data.get('status_msg')}")
                    return None

                await asyncio.sleep(10)
                retry_count += 1

            st.error("Przekroczono limit czasu podczas generowania filmu")
            return None

        except httpx.HTTPStatusError as http_err:
            st.error(f"HTTP error: {http_err.response.status_code} - {http_err.response.text}")
            return None
        except httpx.RequestError as req_err:
            st.error(f"Request error: {req_err}")
            return None
        except Exception as e:
            st.error(f"Wyst膮pi艂 b艂膮d: {e}")
            return None

def main():
    """Interfejs u偶ytkownika aplikacji."""
    st.title("Generator Filmik贸w Hailuo")
    st.write("Wprowad藕 sw贸j klucz API, opis filmu i opcjonalnie obraz jako pierwsz膮 klatk臋.")

    api_key = st.text_input("Wprowad藕 sw贸j klucz API", type="password")
    prompt = st.text_area("Wprowad藕 opis filmu", "prompt")
    
    # Dodana kontrola optymalizacji promptu
    optimize_prompt = st.checkbox("Optymalizuj prompt", value=True, 
                                help="Gdy w艂膮czone, model automatycznie optymalizuje prompt dla lepszych rezultat贸w")
    
    image_option = st.radio("Wybierz spos贸b dodawania obrazu", ("Brak obrazu", "Wklej adres URL obrazu", "Prze艣lij obraz"))

    image = None
    if image_option == "Wklej adres URL obrazu":
        image = st.text_input("Wprowad藕 adres URL obrazu")
    elif image_option == "Prze艣lij obraz":
        uploaded_file = st.file_uploader("Prze艣lij obraz", type=["jpg", "jpeg", "png"])
        if uploaded_file is not None:
            image_path = os.path.join(OUTPUT_DIR, uploaded_file.name)
            with open(image_path, "wb") as f:
                f.write(uploaded_file.getbuffer())
            image = image_path

    if st.button("Generuj Film"):
        if not api_key:
            st.error("Prosz臋 wprowad藕 sw贸j klucz API.")
            return
        if not prompt:
            st.error("Prosz臋 wprowad藕 opis filmu.")
            return

        st.info("Rozpocz臋to generowanie filmu...")
        output_path = asyncio.run(generate_video(api_key, prompt, optimize_prompt, image))

        if output_path:
            st.success("Film zosta艂 wygenerowany!")
            st.video(output_path)
        else:
            st.error("Wyst膮pi艂 b艂膮d podczas generowania filmu.")

if __name__ == "__main__":
    main()