diff --git a/main.py b/main.py index ed6857e..0f60e68 100644 --- a/main.py +++ b/main.py @@ -171,7 +171,7 @@ def yt_single_coordinator(record_quality, proxy_address): - 轮询 URL_config.ini,找“第一条在播”的源; - 找到就启动 ffmpeg 推到同一条 YouTube live; - 源断/下播 -> 立刻切到下一路在播; - - 没有任何在播源 -> 不在面板里显示录制项(保持空)。 + - 没有任何在播源 -> 不在面板里显示直播项(保持空)。 """ key = (_yt_get("youtube", "key", fallback="", cast=str) or "").strip() if not key: @@ -437,7 +437,7 @@ def display_info() -> None: stat_parts = [] stat_parts.append(f"监测中: {monitoring}") stat_parts.append(f"并发线程: {max_request}") - stat_parts.append(f"代理录制: {'是' if use_proxy else '否'}") + stat_parts.append(f"代理直播: {'是' if use_proxy else '否'}") stat_parts.append(f"分段: {f'{split_time}s' if split_video_by_time else '否'}") if create_time_file: stat_parts.append("时间字幕: 是") @@ -454,14 +454,14 @@ def display_info() -> None: if monitoring == 0: print("暂无监测任务。") else: - print(f"暂无正在录制的直播。下次检测间隔:{delay_default} 秒") + print(f"暂无正在直播的直播。下次检测间隔:{delay_default} 秒") else: no_repeat = list(set(recording)) - print(f"正在录制:{len(no_repeat)} 个") + print(f"正在直播:{len(no_repeat)} 个") print(_hr("·")) # 标题行 - print(f"{'序号/主播名':<28} {'清晰度':<6} {'开始时间':<19} {'已录制':<10}") + print(f"{'序号/主播名':<28} {'清晰度':<6} {'开始时间':<19} {'已直播':<10}") print(_hr("·")) for name in sorted(no_repeat): @@ -743,7 +743,7 @@ def clear_record_info(record_name: str, record_url: str) -> None: if record_url in url_comments and record_url in running_list: running_list.remove(record_url) monitoring -= 1 - color_obj.print_colored(f"[{record_name}]已经从录制列表中移除\n", color_obj.YELLOW) + color_obj.print_colored(f"[{record_name}]已经从直播列表中移除\n", color_obj.YELLOW) def direct_download_stream(source_url: str, save_path: str, record_name: str, live_url: str, platform: str) -> bool: @@ -768,7 +768,7 @@ def direct_download_stream(source_url: str, save_path: str, record_name: str, li for chunk in response.iter_bytes(chunk_size): if live_url in url_comments or exit_recording: - color_obj.print_colored(f"[{record_name}]录制时已被注释或请求停止,下载中断", color_obj.YELLOW) + color_obj.print_colored(f"[{record_name}]直播时已被注释或请求停止,下载中断", color_obj.YELLOW) clear_record_info(record_name, live_url) return False @@ -800,7 +800,7 @@ def check_subprocess(record_name: str, record_url: str, ffmpeg_command: list, sa while process.poll() is None: if record_url in url_comments or exit_recording: - color_obj.print_colored(f"[{record_name}]录制时已被注释,本条线程将会退出", color_obj.YELLOW) + color_obj.print_colored(f"[{record_name}]直播时已被注释,本条线程将会退出", color_obj.YELLOW) clear_record_info(record_name, record_url) # process.terminate() if os.name == 'nt': @@ -825,7 +825,7 @@ def check_subprocess(record_name: str, record_url: str, ffmpeg_command: list, sa threading.Thread(target=converts_mp4, args=(path, delete_origin_file)).start() else: threading.Thread(target=converts_mp4, args=(save_file_path, delete_origin_file)).start() - print(f"\n{record_name} {stop_time} 直播录制完成\n") + print(f"\n{record_name} {stop_time} 直播直播完成\n") if script_command: logger.debug("开始执行脚本命令!") @@ -850,7 +850,7 @@ def check_subprocess(record_name: str, record_url: str, ffmpeg_command: list, sa logger.debug("脚本命令执行结束!") else: - color_obj.print_colored(f"\n{record_name} {stop_time} 直播录制出错,返回码: {return_code}\n", color_obj.RED) + color_obj.print_colored(f"\n{record_name} {stop_time} 直播直播出错,返回码: {return_code}\n", color_obj.RED) recording.discard(record_name) return False @@ -972,7 +972,7 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None: elif record_url.find(".m3u8") > -1 or record_url.find(".flv") > -1: - platform = '自定义录制直播' + platform = '自定义直播直播' port_info = { "anchor_name": platform + '_' + str(uuid.uuid4())[:8], "is_live": True, @@ -1094,7 +1094,7 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None: except Exception as e: logger.error(f"错误信息: {e} 发生错误的行数: {e.__traceback__.tb_lineno}") - if platform != '自定义录制直播': + if platform != '自定义直播直播': if enable_https_recording and real_url.startswith("http://"): real_url = real_url.replace("http://", "https://") @@ -1154,7 +1154,7 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None: recording.add(record_name) start_record_time = datetime.datetime.now() recording_time_list[record_name] = [start_record_time, record_quality_zh] - rec_info = f"\r{anchor_name} 准备开始录制视频: {full_path}" + rec_info = f"\r{anchor_name} 准备开始直播视频: {full_path}" if show_url: re_plat = ('WinkTV', 'PandaTV', 'ShowRoom', 'CHZZK', 'Youtube') if platform in re_plat: @@ -1167,7 +1167,7 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None: only_flv_record = False only_flv_platform_list = ['shopee', '花椒直播'] if platform in only_flv_platform_list: - logger.debug(f"提示: {platform} 将强制使用FLV格式录制") + logger.debug(f"提示: {platform} 将强制使用FLV格式直播") only_flv_record = True only_audio_record = False @@ -1192,7 +1192,7 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None: f"{name_format}.{extension}") if split_video_by_time: - print(f'\r{anchor_name} 准备开始录制音频: {save_file_path}') + print(f'\r{anchor_name} 准备开始直播音频: {save_file_path}') if "MP3" in record_save_type: command = [ @@ -1281,22 +1281,22 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None: if download_success: record_finished = True - print(f"\n{anchor_name} {time.strftime('%Y-%m-%d %H:%M:%S')} 直播录制完成\n") + print(f"\n{anchor_name} {time.strftime('%Y-%m-%d %H:%M:%S')} 直播直播完成\n") recording.discard(record_name) else: - logger.debug("未找到FLV直播流,跳过录制") + logger.debug("未找到FLV直播流,跳过直播") except Exception as e: clear_record_info(record_name, record_url) color_obj.print_colored( - f"\n{anchor_name} {time.strftime('%Y-%m-%d %H:%M:%S')} 直播录制出错,请检查网络\n", + f"\n{anchor_name} {time.strftime('%Y-%m-%d %H:%M:%S')} 直播直播出错,请检查网络\n", color_obj.RED) logger.error(f"错误信息: {e} 发生错误的行数: {e.__traceback__.tb_lineno}") with max_request_lock: error_count += 1 error_window.append(1) - elif record_save_type == "MP4录制": + elif record_save_type == "MP4直播": print('---mp4------------') filename = anchor_name + f'_{title_in_name}' + now + ".mp4" print(f'{rec_info}/{filename}') @@ -1664,7 +1664,7 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None: x = x + 60 color_obj.print_colored("\r瞬时错误太多,延迟加60秒", color_obj.YELLOW) - # 这里是.如果录制结束后,循环时间会暂时变成30s后检测一遍. 这样一定程度上防止主播卡顿造成少录 + # 这里是.如果直播结束后,循环时间会暂时变成30s后检测一遍. 这样一定程度上防止主播卡顿造成少录 # 当30秒过后检测一遍后. 会回归正常设置的循环秒数 if record_finished: count_time_end = time.time() - count_time @@ -1766,7 +1766,7 @@ print("GitHub: https://github.com/ihmily/DouyinLiveRecorder") print(f'支持平台: {platforms}') print('.....................................................') if not check_ffmpeg_existence(): - logger.error("缺少ffmpeg无法进行录制,程序退出") + logger.error("缺少ffmpeg无法进行直播,程序退出") sys.exit(1) os.makedirs(os.path.dirname(config_file), exist_ok=True) t3 = threading.Thread(target=backup_file_start, args=(), daemon=True) @@ -1779,8 +1779,8 @@ def read_config_value(config_parser: configparser.RawConfigParser, section: str, try: config_parser.read(config_file, encoding=text_encoding) - if '录制设置' not in config_parser.sections(): - config_parser.add_section('录制设置') + if '直播设置' not in config_parser.sections(): + config_parser.add_section('直播设置') if '推送配置' not in config_parser.sections(): config_parser.add_section('推送配置') if 'Cookie' not in config_parser.sections(): @@ -1799,8 +1799,8 @@ def read_config_value(config_parser: configparser.RawConfigParser, section: str, options = {"是": True, "否": False} config = configparser.RawConfigParser() -language = read_config_value(config, '录制设置', 'language(zh_cn/en)', "zh_cn") -skip_proxy_check = options.get(read_config_value(config, '录制设置', '是否跳过代理检测(是/否)', "否"), False) +language = read_config_value(config, '直播设置', 'language(zh_cn/en)', "zh_cn") +skip_proxy_check = options.get(read_config_value(config, '直播设置', '是否跳过代理检测(是/否)', "否"), False) if language and 'en' not in language.lower(): from i18n import translated_print @@ -1821,7 +1821,7 @@ try: except HTTPError as err: print(f"HTTP error occurred: {err.code} - {err.reason}") except URLError: - color_obj.print_colored("INFO:未检测到全局/规则网络代理,请检查代理配置(若无需录制海外直播请忽略此条提示)", + color_obj.print_colored("INFO:未检测到全局/规则网络代理,请检查代理配置(若无需直播海外直播请忽略此条提示)", color_obj.YELLOW) except Exception as err: print("An unexpected error occurred:", err) @@ -1839,45 +1839,45 @@ while True: ini_URL_content = file.read().strip() if not ini_URL_content.strip(): - input_url = input('请输入要录制的主播直播间网址(尽量使用PC网页端的直播间地址):\n') + input_url = input('请输入要直播的主播直播间网址(尽量使用PC网页端的直播间地址):\n') with open(url_config_file, 'w', encoding=text_encoding) as file: file.write(input_url) except OSError as err: logger.error(f"发生 I/O 错误: {err}") - video_save_path = read_config_value(config, '录制设置', '直播保存路径(不填则默认)', "") - folder_by_author = options.get(read_config_value(config, '录制设置', '保存文件夹是否以作者区分', "是"), False) - folder_by_time = options.get(read_config_value(config, '录制设置', '保存文件夹是否以时间区分', "否"), False) - folder_by_title = options.get(read_config_value(config, '录制设置', '保存文件夹是否以标题区分', "否"), False) - filename_by_title = options.get(read_config_value(config, '录制设置', '保存文件名是否包含标题', "否"), False) - clean_emoji = options.get(read_config_value(config, '录制设置', '是否去除名称中的表情符号', "是"), True) - video_save_type = read_config_value(config, '录制设置', '视频保存格式ts|mkv|flv|mp4|mp3音频|m4a音频', "mp4") - video_record_quality = read_config_value(config, '录制设置', '原画|超清|高清|标清|流畅', "原画") - use_proxy = options.get(read_config_value(config, '录制设置', '是否使用代理ip(是/否)', "是"), False) - proxy_addr_bak = read_config_value(config, '录制设置', '代理地址', "") + video_save_path = read_config_value(config, '直播设置', '直播保存路径(不填则默认)', "") + folder_by_author = options.get(read_config_value(config, '直播设置', '保存文件夹是否以作者区分', "是"), False) + folder_by_time = options.get(read_config_value(config, '直播设置', '保存文件夹是否以时间区分', "否"), False) + folder_by_title = options.get(read_config_value(config, '直播设置', '保存文件夹是否以标题区分', "否"), False) + filename_by_title = options.get(read_config_value(config, '直播设置', '保存文件名是否包含标题', "否"), False) + clean_emoji = options.get(read_config_value(config, '直播设置', '是否去除名称中的表情符号', "是"), True) + video_save_type = read_config_value(config, '直播设置', '视频保存格式ts|mkv|flv|mp4|mp3音频|m4a音频', "mp4") + video_record_quality = read_config_value(config, '直播设置', '原画|超清|高清|标清|流畅', "原画") + use_proxy = options.get(read_config_value(config, '直播设置', '是否使用代理ip(是/否)', "是"), False) + proxy_addr_bak = read_config_value(config, '直播设置', '代理地址', "") proxy_addr = None if not use_proxy else proxy_addr_bak - max_request = int(read_config_value(config, '录制设置', '同一时间访问网络的线程数', 3)) + max_request = int(read_config_value(config, '直播设置', '同一时间访问网络的线程数', 3)) semaphore = threading.Semaphore(max_request) - delay_default = int(read_config_value(config, '录制设置', '循环时间(秒)', 120)) - local_delay_default = int(read_config_value(config, '录制设置', '排队读取网址时间(秒)', 0)) - loop_time = options.get(read_config_value(config, '录制设置', '是否显示循环秒数', "否"), False) - show_url = options.get(read_config_value(config, '录制设置', '是否显示直播源地址', "否"), False) - split_video_by_time = options.get(read_config_value(config, '录制设置', '分段录制是否开启', "否"), False) - enable_https_recording = options.get(read_config_value(config, '录制设置', '是否强制启用https录制', "否"), False) - disk_space_limit = float(read_config_value(config, '录制设置', '录制空间剩余阈值(gb)', 1.0)) - split_time = str(read_config_value(config, '录制设置', '视频分段时间(秒)', 1800)) - converts_to_mp4 = options.get(read_config_value(config, '录制设置', '录制完成后自动转为mp4格式', "否"), False) - converts_to_h264 = options.get(read_config_value(config, '录制设置', 'mp4格式重新编码为h264', "否"), False) - delete_origin_file = options.get(read_config_value(config, '录制设置', '追加格式后删除原文件', "否"), False) - create_time_file = options.get(read_config_value(config, '录制设置', '生成时间字幕文件', "否"), False) - is_run_script = options.get(read_config_value(config, '录制设置', '是否录制完成后执行自定义脚本', "否"), False) - custom_script = read_config_value(config, '录制设置', '自定义脚本执行命令', "") if is_run_script else None + delay_default = int(read_config_value(config, '直播设置', '循环时间(秒)', 120)) + local_delay_default = int(read_config_value(config, '直播设置', '排队读取网址时间(秒)', 0)) + loop_time = options.get(read_config_value(config, '直播设置', '是否显示循环秒数', "否"), False) + show_url = options.get(read_config_value(config, '直播设置', '是否显示直播源地址', "否"), False) + split_video_by_time = options.get(read_config_value(config, '直播设置', '分段直播是否开启', "否"), False) + enable_https_recording = options.get(read_config_value(config, '直播设置', '是否强制启用https直播', "否"), False) + disk_space_limit = float(read_config_value(config, '直播设置', '直播空间剩余阈值(gb)', 1.0)) + split_time = str(read_config_value(config, '直播设置', '视频分段时间(秒)', 1800)) + converts_to_mp4 = options.get(read_config_value(config, '直播设置', '直播完成后自动转为mp4格式', "否"), False) + converts_to_h264 = options.get(read_config_value(config, '直播设置', 'mp4格式重新编码为h264', "否"), False) + delete_origin_file = options.get(read_config_value(config, '直播设置', '追加格式后删除原文件', "否"), False) + create_time_file = options.get(read_config_value(config, '直播设置', '生成时间字幕文件', "否"), False) + is_run_script = options.get(read_config_value(config, '直播设置', '是否直播完成后执行自定义脚本', "否"), False) + custom_script = read_config_value(config, '直播设置', '自定义脚本执行命令', "") if is_run_script else None enable_proxy_platform = read_config_value( - config, '录制设置', '使用代理录制的平台(逗号分隔)', + config, '直播设置', '使用代理直播的平台(逗号分隔)', 'tiktok, soop, pandalive, winktv, flextv, popkontv, twitch, liveme, showroom, chzzk, shopee, shp, youtu, faceit' ) enable_proxy_platform_list = enable_proxy_platform.replace(',', ',').split(',') if enable_proxy_platform else None - extra_enable_proxy = read_config_value(config, '录制设置', '额外使用代理录制的平台(逗号分隔)', '') + extra_enable_proxy = read_config_value(config, '直播设置', '额外使用代理直播的平台(逗号分隔)', '') extra_enable_proxy_platform_list = extra_enable_proxy.replace(',', ',').split(',') if extra_enable_proxy else None live_status_push = read_config_value(config, '推送配置', '直播状态推送渠道', "") dingtalk_api_url = read_config_value(config, '推送配置', '钉钉推送接口链接', "") @@ -1904,7 +1904,7 @@ while True: push_message_title = read_config_value(config, '推送配置', '自定义推送标题', "直播间状态更新通知") begin_push_message_text = read_config_value(config, '推送配置', '自定义开播推送内容', "") over_push_message_text = read_config_value(config, '推送配置', '自定义关播推送内容', "") - disable_record = options.get(read_config_value(config, '推送配置', '只推送通知不录制(是/否)', "否"), False) + disable_record = options.get(read_config_value(config, '推送配置', '只推送通知不直播(是/否)', "否"), False) push_check_seconds = int(read_config_value(config, '推送配置', '直播推送检测频率(秒)', 1800)) begin_show_push = options.get(read_config_value(config, '推送配置', '开播推送开启(是/否)', "是"), True) over_show_push = options.get(read_config_value(config, '推送配置', '关播推送开启(是/否)', "否"), False) @@ -2171,7 +2171,7 @@ while True: # 保序去重(文件顺序 = 备源优先级) text_no_repeat_url = list(dict.fromkeys(url_tuples_list)) - # 监测数量显示为“URL 条数”(哪怕不启动录制线程) + # 监测数量显示为“URL 条数”(哪怕不启动直播线程) monitoring = len(text_no_repeat_url) if yt_single_mode and video_save_type.upper() == "MP4": @@ -2186,7 +2186,7 @@ while True: t_yt.start() yt_thread_started = True else: - # ===== 传统模式:按原先逻辑为每个 URL 启动录制(本地落地 / 其他保存格式)===== + # ===== 传统模式:按原先逻辑为每个 URL 启动直播(本地落地 / 其他保存格式)===== if len(text_no_repeat_url) > 0: for url_tuple in text_no_repeat_url: if url_tuple[1] in not_record_list: