Skip to content

Commit 6ccecd4

Browse files
authored
feat: add kling (#331)
* feat: add kling
1 parent dddbcc8 commit 6ccecd4

File tree

4 files changed

+86
-2
lines changed

4 files changed

+86
-2
lines changed

bilive.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ sensenova_api_key = "" # Apply for your own SenseNova API key at https://console
4040
generate_cover = false # whether to generate cover
4141
cover_prompt = "" # Write your own cover prompt here
4242
image_gen_model = "minimax" # the image generation model, can be "minimax" or "siliconflow" or "tencent" or "baidu" or "stability" or "luma" or "ideogram" or "recraft" or "amazon" or "hidream"
43+
dmx_api_token = "" # Apply for your own dmxapi token at https://www.dmxapi.cn/token
4344
minimax_api_key = "" # Apply for your own Minimax API key at https://platform.minimaxi.com/user-center/basic-information/interface-key
4445
siliconflow_api_key = "" # Apply for your own SiliconFlow API key at https://cloud.siliconflow.cn/i/3Szr5BVg
4546
tencent_secret_id = "" # Apply for your own Tencent Cloud API key at https://console.cloud.tencent.com/cam/capi

src/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,6 @@ def get_interface_config():
9292
AWS_ACCESS_KEY_ID = config.get("cover", {}).get("aws_access_key_id")
9393
AWS_SECRET_ACCESS_KEY = config.get("cover", {}).get("aws_secret_access_key")
9494
HIDREAM_API_KEY = config.get("cover", {}).get("hidream_api_key")
95-
95+
DMX_API_TOKEN = config.get("cover", {}).get("dmx_api_token")
9696
SLICE_PROMPT = config.get("slice", {}).get("slice_prompt")
9797
COVER_PROMPT = config.get("cover", {}).get("cover_prompt")
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import http.client
2+
import json
3+
import base64
4+
import requests
5+
import time
6+
import os
7+
from src.config import DMX_API_TOKEN, COVER_PROMPT
8+
9+
10+
conn = http.client.HTTPSConnection("www.dmxapi.cn")
11+
12+
def get_image_base64(image_path):
13+
with open(image_path, "rb") as image_file:
14+
return base64.b64encode(image_file.read()).decode("utf-8")
15+
16+
def generate_cover(your_file_path):
17+
image_base = get_image_base64(your_file_path)
18+
payload = json.dumps({
19+
"model_name": "kling-v1-5",
20+
"prompt": COVER_PROMPT,
21+
"image": image_base,
22+
"image_reference": "subject"
23+
})
24+
headers = {
25+
'Authorization': f'Bearer {DMX_API_TOKEN}',
26+
'Content-Type': 'application/json'
27+
}
28+
conn.request("POST", "/kling/v1/images/generations?=null", payload, headers)
29+
res = conn.getresponse()
30+
json_data = json.loads(res.read().decode("utf-8"))
31+
print(json_data)
32+
return json_data['data']['task_id']
33+
34+
def get_kling_cover(task_id):
35+
action = "images"
36+
action2 = "generations"
37+
38+
query_path = f"/kling/v1/{action}/{action2}/{task_id}"
39+
40+
headers = {
41+
'Authorization': f'Bearer {DMX_API_TOKEN}'
42+
}
43+
44+
conn.request("GET", query_path, None, headers)
45+
res = conn.getresponse()
46+
json_data = json.loads(res.read().decode("utf-8"))
47+
if json_data['data']['task_status'] == "succeed":
48+
return json_data['data']['task_result']['images'][0]['url']
49+
else:
50+
return None
51+
52+
def kling_generate_cover(your_file_path):
53+
task_id = generate_cover(your_file_path)
54+
start_time = time.time()
55+
timeout = 60
56+
57+
while True:
58+
image_url = get_kling_cover(task_id)
59+
if image_url is not None:
60+
img_data = requests.get(image_url).content
61+
cover_name = time.strftime("%Y%m%d%H%M%S") + ".png"
62+
temp_cover_path = os.path.join(os.path.dirname(your_file_path), cover_name)
63+
with open(temp_cover_path, "wb") as handler:
64+
handler.write(img_data)
65+
os.remove(your_file_path)
66+
return temp_cover_path
67+
68+
if time.time() - start_time > timeout:
69+
print(f"Generate cover {timeout} seconds timeout")
70+
return None
71+
72+
time.sleep(1)
73+
print(f"Waiting for cover generation, {int(time.time() - start_time)} seconds", flush=True)
74+
75+
if __name__ == "__main__":
76+
your_file_path = ""
77+
print(kling_generate_cover(your_file_path))

tests/test_cover.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from src.cover.image_model_sdk.recraft_sdk import recraft_generate_cover
1010
from src.cover.image_model_sdk.stability_sdk import stable_diffusion_generate_cover
1111
from src.cover.image_model_sdk.tencent_sdk import hunyuan_generate_cover
12-
12+
from src.cover.image_model_sdk.kling_sdk import kling_generate_cover
1313

1414
class BaseTest(unittest.TestCase):
1515
file_path = "your_image_path"
@@ -76,5 +76,11 @@ def test_hunyuan_generate_cover(self):
7676
self.assertIsNotNone(cover_path)
7777
print(cover_path, flush=True)
7878

79+
class TestKlingMain(BaseTest):
80+
def test_kling_generate_cover(self):
81+
cover_path = kling_generate_cover(self.file_path)
82+
self.assertIsNotNone(cover_path)
83+
print(cover_path, flush=True)
84+
7985
if __name__ == "__main__":
8086
unittest.main()

0 commit comments

Comments
 (0)