fix: update config

This commit is contained in:
John Howe
2025-04-10 20:30:50 +08:00
parent 1f319f773f
commit e1df9d18a8
17 changed files with 51 additions and 51 deletions

View File

@@ -169,7 +169,7 @@ pip install -r requirements.txt
> - 有关自动切片的配置在 `bilive.toml` 文件的 `[slice]` 部分。
> - `auto_slice` 默认为 false, 即不进行自动切片。
MLLM 模型主要用于自动切片后的切片标题生成,此功能默认关闭,如果需要打开请将 `auto_slice` 参数设置为 `true`其他配置分别有:
MLLM 模型主要用于自动切片后的切片标题生成,此功能默认关闭,如果需要打开请将 `auto_slice` 参数设置为 `true`,并且写下你自己的 prompt其他配置分别有:
- `slice_duration` 以秒为单位设置切片时长(不建议超过 180 秒)。
- `slice_num` 设置切片数量。
- `slice_overlap` 设置切片重叠时长。切片采用滑动窗口法处理,细节内容请见 [auto-slice-video](https://github.com/timerring/auto-slice-video)
@@ -178,11 +178,11 @@ MLLM 模型主要用于自动切片后的切片标题生成,此功能默认关
接下来配置模型有关的 `mllm_model` 参数即对应的 api-key请自行根据链接注册账号并且申请对应 api key填写在对应的参数中请注意以下模型只有你在 `mllm_model` 参数中设置的那个模型会生效。
| Company | Google | 智谱 | 阿里云 |
|----------------|-------------------|------------------|-----------------------|
| Name | Gemini-2.0-flash | GLM-4V-PLUS | Qwen-2.5-72B-Instruct |
| `mllm_model` | `gemini`| `zhipu` | `qwen` |
| `API key` | [gemini_api_key](https://aistudio.google.com/app/apikey) | [zhipu_api_key](https://www.bigmodel.cn/invite?icode=shBtZUfNE6FfdMH1R6NybGczbXFgPRGIalpycrEwJ28%3D) | [qwen_api_key](https://bailian.console.aliyun.com/?apiKey=1) |
| Company | Alicloud | zhipu | Google |
|----------------|-----------------------|------------------|-------------------|
| Name | Qwen-2.5-72B-Instruct | GLM-4V-PLUS | Gemini-2.0-flash |
| `mllm_model` | `qwen` | `zhipu` | `gemini` |
| `API key` | [qwen_api_key](https://bailian.console.aliyun.com/?apiKey=1) | [zhipu_api_key](https://www.bigmodel.cn/invite?icode=shBtZUfNE6FfdMH1R6NybGczbXFgPRGIalpycrEwJ28%3D) | [gemini_api_key](https://aistudio.google.com/app/apikey) |
#### 2.3 Image Generation Model自动生成视频封面
@@ -191,8 +191,7 @@ MLLM 模型主要用于自动切片后的切片标题生成,此功能默认关
> - 有关自动生成视频封面的配置在 `bilive.toml` 文件的 `[cover]` 部分。
> - `generate_cover` 默认为 false, 即不进行自动生成视频封面。
采用图生图多模态模型,自动获取视频截图并上传风格变换后的视频封面,如需使用本功能,请将 `generate_cover` 参数设置为 `true`接下来需要配置的参数有 image_gen_model 和对应的 api key请自行根据链接注册账号并且申请对应 api key填写在对应的参数中请注意以下模型只有你在 `image_gen_model` 参数中设置的那个模型会生效。
采用图生图多模态模型,自动获取视频截图并上传风格变换后的视频封面,如需使用本功能,请将 `generate_cover` 参数设置为 `true`,并且写下你自己的 prompt注意部分模型只支持英文接下来需要配置的参数有 image_gen_model 和对应的 api key请自行根据链接注册账号并且申请对应 api key填写在对应的参数中请注意以下模型只有你在 `image_gen_model` 参数中设置的那个模型会生效。
| Company | Model Name | `image_gen_model` | `API Key` |
|--------------|--------------------------------|-------------------|---------------------------------------------------------------------------------|
@@ -208,10 +207,10 @@ MLLM 模型主要用于自动切片后的切片标题生成,此功能默认关
#### 3. 配置上传参数
上传默认参数如下,[]中内容全部自动替换。可以`bilive.toml` 中自定义相关配置,映射关键词为 `{artist}``{date}``{title}``{source_link}`自行组合删减定制模板:
`bilive.toml` 中自定义相关配置,映射关键词为 `{artist}``{date}``{title}``{source_link}`自行组合删减定制模板:
- `title` 标题模板`{artist}直播回放-{date}-{title}`,效果为"【弹幕+字幕】[XXX]直播回放-[日期]-[直播间标题]",可自行修改
- `description` 简介模板`{artist}直播,直播间地址:{source_link} 内容仅供娱乐,直播中主播的言论、观点和行为均由主播本人负责,不代表录播员的观点或立场。`,效果为"【弹幕+字幕】[XXX]直播,直播间地址:[https://live.bilibili.com/XXX] 内容仅供娱乐,直播中主播的言论、观点和行为均由主播本人负责,不代表录播员的观点或立场。",可自行修改
- `title` 标题模板。
- `description` 简介模板。
- `gift_price_filter = 1` 表示过滤价格低于 1 元的礼物。
- `reserve_for_fixing = false` 表示如果视频出现错误,重试失败后不保留视频用于修复,推荐硬盘空间有限的用户设置 false。
- `upload_line = "auto"` 表示自动探测上传线路并上传,如果需要指定固定的线路,可以设置为 `bldsa``ws``tx``qn``bda2`

View File

@@ -15,10 +15,8 @@ inference_model = "small" # If you choose "deploy", you should download the infe
[video]
# You can change the title as you like, eg.
# f"{artist}直播回放-{date}-{title}" - Streamer直播回放-20250328-Live title
# f"{date}-{artist}直播回放" - 20250328-Streamer直播回放
title = "{artist}直播回放-{date}-{title}" # Key words: {artist}, {date}, {title}, {source_link}
description = "{artist}直播回放,直播间地址:{source_link} 内容仅供娱乐,直播中主播的言论、观点和行为均由主播本人负责,不代表录播员的观点或立场。" # Key words: {artist}, {date}, {title}, {source_link}
title = "{date}直播" # Key words: {artist}, {date}, {title}, {source_link}
description = "录制请征求主播同意,若未经同意就录制,所引起的任何法律问题均由该违规录制的 b 站账号承担。" # Key words: {artist}, {date}, {title}, {source_link}
gift_price_filter = 1 # The gift whose price is less than this value will be filtered, unit: RMB
reserve_for_fixing = false # If encounter MOOV crash error, delete the video or reserve for fixing
upload_line = "auto" # The upload line to be used, default None is auto detect(recommended), if you want to specify, it can be "bldsa", "ws", "tx", "qn", "bda2".
@@ -30,13 +28,15 @@ slice_num = 2 # the number of slices
slice_overlap = 30 # the overlap of slices(seconds) see my package https://github.com/timerring/auto-slice-video for more details
slice_step = 1 # the step of slices(seconds)
min_video_size = 200 # The minimum video size to be sliced (MB)
mllm_model = "gemini" # the multi-model LLMs, can be "gemini" or "zhipu" or "qwen"
mllm_model = "qwen" # the multi-model LLMs, can be "qwen" or "gemini" or "zhipu"
slice_prompt = "" # Write your own slice prompt here
qwen_api_key = "" # Apply for your own Qwen API key at https://bailian.console.aliyun.com/?apiKey=1
zhipu_api_key = "" # Apply for your own GLM-4v-Plus API key at https://www.bigmodel.cn/invite?icode=shBtZUfNE6FfdMH1R6NybGczbXFgPRGIalpycrEwJ28%3D
gemini_api_key = "" # Apply for your own Gemini API key at https://aistudio.google.com/app/apikey
qwen_api_key = "" # Apply for your own Qwen API key at https://bailian.console.aliyun.com/?apiKey=1
[cover]
generate_cover = false # whether to generate cover
cover_prompt = "" # Write your own cover prompt here
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"
minimax_api_key = "" # Apply for your own Minimax API key at https://platform.minimaxi.com/user-center/basic-information/interface-key
siliconflow_api_key = "" # Apply for your own SiliconFlow API key at https://cloud.siliconflow.cn/i/3Szr5BVg

View File

@@ -1,7 +1,7 @@
from google import genai
from google.genai import types
from src.log.logger import scan_log
from src.config import GEMINI_API_KEY
from src.config import GEMINI_API_KEY, SLICE_PROMPT
def gemini_generate_title(video_path, artist):
@@ -14,7 +14,7 @@ def gemini_generate_title(video_path, artist):
model='models/gemini-2.0-flash',
contents=types.Content(
parts=[
types.Part(text=f'视频是{artist}的直播的切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,只需要返回一个标题即可,无需返回其他内容,标题中不要有表情符号。'),
types.Part(text=SLICE_PROMPT),
types.Part(
inline_data=types.Blob(data=video_bytes, mime_type='video/mp4')
)
@@ -22,6 +22,6 @@ def gemini_generate_title(video_path, artist):
)
)
scan_log.info("使用 Gemini-2.0-flash 生成切片标题")
scan_log.info(f"Prompt: 视频是{artist}的直播的切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,只需要返回一个标题即可,无需返回其他内容,标题中不要有表情符号。")
scan_log.info(f"Prompt: {SLICE_PROMPT}")
scan_log.info(f"生成的切片标题为: {response.text}")
return response.text

View File

@@ -1,5 +1,5 @@
import google.generativeai as genai
from src.config import GEMINI_API_KEY
from src.config import GEMINI_API_KEY, SLICE_PROMPT
from src.log.logger import scan_log
import time
@@ -22,7 +22,7 @@ def gemini_generate_title(video_path, artist):
raise ValueError(video_file.state.name)
# Create the prompt.
prompt = f"视频是{artist}的直播的切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,只返回该标题即可,无需返回其他内容,标题中不要有表情符号。"
prompt = SLICE_PROMPT
# Set the model to Gemini Flash.
model = genai.GenerativeModel(model_name="models/gemini-2.0-flash")
@@ -32,6 +32,6 @@ def gemini_generate_title(video_path, artist):
# delete the video file
genai.delete_file(video_file.name)
scan_log.info("使用 Gemini-2.0-flash 生成切片标题")
scan_log.info(f"Prompt: 视频是{artist}的直播的切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,只需要返回一个标题即可,无需返回其他内容,标题中不要有表情符号。")
scan_log.info(f"Prompt: {SLICE_PROMPT}")
scan_log.info(f"生成的切片标题为: {response.text}")
return response.text

View File

@@ -1,4 +1,4 @@
from src.config import QWEN_API_KEY
from src.config import QWEN_API_KEY, SLICE_PROMPT
from src.log.logger import scan_log
from openai import OpenAI
import os
@@ -28,12 +28,12 @@ def qwen_generate_title(video_path, artist):
"type": "video_url",
"video_url": {"url": f"data:video/mp4;base64,{base64_video}"},
},
{"type": "text", "text": f"视频是{artist}的直播切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,标题中不要表情符号,可以适当使用网络热词或流行语"},
{"type": "text", "text": SLICE_PROMPT},
],
}
],
)
scan_log.info("使用 Qwen-2.5-72B-Instruct 生成切片标题")
scan_log.info(f"Prompt: 视频是{artist}的直播切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,标题中不要表情符号,可以适当使用网络热词或流行语")
scan_log.info(f"Prompt: {SLICE_PROMPT}")
scan_log.info(f"生成的切片标题为: {completion.choices[0].message.content}")
return completion.choices[0].message.content.strip('"')

View File

@@ -1,7 +1,7 @@
# Copyright (c) 2024 bilive.
import base64
from src.config import ZHIPU_API_KEY
from src.config import ZHIPU_API_KEY, SLICE_PROMPT
from zhipuai import ZhipuAI
from src.log.logger import scan_log
@@ -24,13 +24,13 @@ def zhipu_glm_4v_plus_generate_title(video_path, artist):
},
{
"type": "text",
"text": f"视频是{artist}的直播的切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,注意标题中如果有“主播”请替换成{artist}"
"text": SLICE_PROMPT
}
]
}
]
)
scan_log.info("使用 Zhipu-glm-4v-plus 生成切片标题")
scan_log.info(f"Prompt: 视频是{artist}的直播的切片,请根据该视频中的内容及弹幕信息,为这段视频起一个调皮并且吸引眼球的标题,注意标题中如果有“主播”请替换成{artist}")
scan_log.info(f"Prompt: {SLICE_PROMPT}")
scan_log.info(f"生成的切片标题为: {response.choices[0].message.content}")
return response.choices[0].message.content.replace("", "").replace("", "")

View File

@@ -85,3 +85,6 @@ IDEOGRAM_API_KEY = config.get('cover', {}).get('ideogram_api_key')
RECRAFT_API_KEY = config.get('cover', {}).get('recraft_api_key')
AWS_ACCESS_KEY_ID = config.get('cover', {}).get('aws_access_key_id')
AWS_SECRET_ACCESS_KEY = config.get('cover', {}).get('aws_secret_access_key')
SLICE_PROMPT = config.get('slice', {}).get('slice_prompt')
COVER_PROMPT = config.get('cover', {}).get('cover_prompt')

View File

@@ -12,7 +12,7 @@ from PIL import Image
from botocore.exceptions import ClientError
import os
import time
from src.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
from src.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, COVER_PROMPT
class ImageError(Exception):
"Custom exception for errors returned by Amazon Titan Image Generator V2"
@@ -67,7 +67,7 @@ def amazon_generate_cover(your_file_path):
body = json.dumps({
"taskType": "TEXT_IMAGE",
"textToImageParams": {
"text": "This is a video screenshot, please generate a cover in the style of a manga",
"text": COVER_PROMPT,
"negativeText": "",
"conditionImage": input_image,
"controlMode": "CANNY_EDGE"

View File

@@ -6,7 +6,7 @@ from PIL import Image
from io import BytesIO
import time
from src.upload.bilitool.bilitool.model.model import Model
from src.config import BAIDU_API_KEY
from src.config import BAIDU_API_KEY, COVER_PROMPT
def cover_up(img: str):
@@ -72,7 +72,7 @@ def baidu_generate_cover(your_file_path):
payload = json.dumps(
{
"model": "irag-1.0",
"prompt": "这是视频截图,请根据该图生成对应的动漫类型的封面",
"prompt": COVER_PROMPT,
"refer_image": cover_url,
}
)

View File

@@ -2,7 +2,7 @@ import requests
import json
import os
import time
from src.config import IDEOGRAM_API_KEY
from src.config import IDEOGRAM_API_KEY, COVER_PROMPT
def ideogram_generate_cover(your_file_path):
@@ -19,7 +19,7 @@ def ideogram_generate_cover(your_file_path):
payload = {
"image_request": json.dumps(
{
"prompt": "This is a video screenshot, please generate a cover in the style of a manga",
"prompt": COVER_PROMPT,
"aspect_ratio": "ASPECT_10_16",
"image_weight": 75,
"magic_prompt_option": "ON",

View File

@@ -2,7 +2,7 @@ import requests
import base64
import time
import os
from src.config import SILICONFLOW_API_KEY
from src.config import SILICONFLOW_API_KEY, COVER_PROMPT
def kolors_generate_cover(your_file_path):
@@ -17,7 +17,7 @@ def kolors_generate_cover(your_file_path):
payload = {
"model": "Kwai-Kolors/Kolors",
"prompt": "这是一个视频截图,请尝试生成对应的日本动漫类型的封面",
"prompt": COVER_PROMPT,
"image_size": "1024x1024",
"batch_size": 1,
"num_inference_steps": 20,

View File

@@ -7,7 +7,7 @@ from PIL import Image
from io import BytesIO
from lumaai import LumaAI
from src.upload.bilitool.bilitool.model.model import Model
from src.config import LUMA_API_KEY
from src.config import LUMA_API_KEY, COVER_PROMPT
def cover_up(img: str):
@@ -72,7 +72,7 @@ def luma_generate_cover(your_file_path):
auth_token=LUMA_API_KEY,
)
generation = client.generations.image.create(
prompt="This is a video screenshot, please generate a cover in the style of a manga",
prompt=COVER_PROMPT,
image_ref=[{"url": cover_url, "weight": 0.85}],
)
completed = False

View File

@@ -3,7 +3,7 @@ import json
import base64
import os
import time
from src.config import MINIMAX_API_KEY
from src.config import MINIMAX_API_KEY, COVER_PROMPT
def minimax_generate_cover(your_file_path):
@@ -20,7 +20,7 @@ def minimax_generate_cover(your_file_path):
payload = json.dumps(
{
"model": "image-01",
"prompt": "这是一个视频截图,请生成其对应的吉普力风格的图片",
"prompt": COVER_PROMPT,
"subject_reference": [
{"type": "character", "image_file": f"data:image/jpeg;base64,{data}"}
],

View File

@@ -1,5 +1,5 @@
from openai import OpenAI
from src.config import RECRAFT_API_KEY
from src.config import RECRAFT_API_KEY, COVER_PROMPT
import requests
import os
import time
@@ -20,7 +20,7 @@ def recraft_generate_cover(your_file_path):
'image': open(your_file_path, 'rb'),
},
body={
'prompt': 'This is a video screenshot, please generate a cover in the style of a manga',
'prompt': COVER_PROMPT,
'strength': 0.75,
},
)

View File

@@ -1,5 +1,5 @@
import requests
from src.config import STABILITY_API_KEY
from src.config import STABILITY_API_KEY, COVER_PROMPT
import time
import os
@@ -24,7 +24,7 @@ def stable_diffusion_generate_cover(your_file_path):
},
files={"image": ("image.jpg", img_file, "image/jpeg")},
data={
"prompt": "This is a video screenshot, please generate a cover in the style of a manga", # English only
"prompt": COVER_PROMPT, # English only
"strength": 0.75,
"output_format": "jpeg",
"mode": "image-to-image",

View File

@@ -8,7 +8,7 @@ import base64
from datetime import datetime
import os
import requests
from src.config import TENCENT_SECRET_ID, TENCENT_SECRET_KEY
from src.config import TENCENT_SECRET_ID, TENCENT_SECRET_KEY, COVER_PROMPT
if sys.version_info[0] <= 2:
from httplib import HTTPSConnection
@@ -125,7 +125,7 @@ def hunyuan_generate_cover(your_file_path):
submit_action = "SubmitHunyuanImageJob"
with open(your_file_path, "rb") as image_file:
data = base64.b64encode(image_file.read()).decode("utf-8")
payload = f'{{"Prompt":"这是一个视频截图,请尝试根据该图生成对应的动漫类型的封面","Style":"riman","ContentImage":{{"ImageBase64":"data:image/png;base64,{data}"}}}}'
payload = f'{{"Prompt":"{COVER_PROMPT}","Style":"riman","ContentImage":{{"ImageBase64":"data:image/png;base64,{data}"}}}}'
submit_return = post_request(submit_action, payload).decode("utf-8")
job_id = json.loads(submit_return)["Response"]["JobId"]
query_action = "QueryHunyuanImageJob"

View File

@@ -46,17 +46,15 @@ def generate_title(video_path):
upload_log.error(f"Error occurred in generate_title: {title}")
return None
source_link = generate_source(video_path)
prefix = "【弹幕+字幕】"
formatted_title = TITLE.format(artist=artist, date=date, title=title, source_link=source_link)
new_title = f"{prefix}{formatted_title}"
new_title = f"{formatted_title}"
return new_title
def generate_desc(video_path):
title, artist, date = get_video_info(video_path)
source_link = generate_source(video_path)
prefix = "【弹幕+字幕】"
formatted_desc = DESC.format(artist=artist, date=date, title=title, source_link=source_link)
new_desc = f"{prefix}{formatted_desc}"
new_desc = f"{formatted_desc}"
return new_desc
def generate_tag(video_path):