mirror of
https://github.com/ihmily/DouyinLiveRecorder.git
synced 2025-12-26 05:48:32 +08:00
refactor: add ffmpeg automatic installation
This commit is contained in:
parent
b963d8ac6f
commit
eeeed2fc5f
@ -23,13 +23,16 @@ execute_dir = os.path.split(os.path.realpath(sys.argv[0]))[0]
|
||||
current_env_path = os.environ.get('PATH')
|
||||
|
||||
|
||||
def unzip_file(zip_path: str | Path, extract_to: str | Path) -> None:
|
||||
def unzip_file(zip_path: str | Path, extract_to: str | Path, delete: bool = True) -> None:
|
||||
if not os.path.exists(extract_to):
|
||||
os.makedirs(extract_to)
|
||||
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(extract_to)
|
||||
|
||||
if delete and os.path.exists(zip_path):
|
||||
os.remove(zip_path)
|
||||
|
||||
|
||||
def install_nodejs_windows():
|
||||
try:
|
||||
@ -148,14 +151,22 @@ def install_nodejs_mac():
|
||||
logger.error(f"An unexpected error occurred: {e}")
|
||||
|
||||
|
||||
def get_package_manager():
|
||||
dist_id = distro.id()
|
||||
if dist_id in ["centos", "fedora", "rhel", "amzn", "oracle", "scientific", "opencloudos", "alinux"]:
|
||||
return "RHS"
|
||||
else:
|
||||
return "DBS"
|
||||
|
||||
|
||||
def install_nodejs() -> bool:
|
||||
if current_platform == "Windows":
|
||||
return install_nodejs_windows()
|
||||
elif current_platform == "Linux":
|
||||
dist = distro.id()
|
||||
if dist.lower() == "centos":
|
||||
os_type = get_package_manager()
|
||||
if os_type == "RHS":
|
||||
return install_nodejs_centos()
|
||||
elif dist.lower() == "ubuntu":
|
||||
else:
|
||||
return install_nodejs_ubuntu()
|
||||
elif current_platform == "Darwin":
|
||||
return install_nodejs_mac()
|
||||
@ -206,4 +217,4 @@ def check_nodejs_installed() -> bool:
|
||||
|
||||
def check_node() -> bool:
|
||||
if not check_nodejs_installed():
|
||||
return install_nodejs()
|
||||
return install_nodejs()
|
||||
|
||||
BIN
ffmpeg.exe
BIN
ffmpeg.exe
Binary file not shown.
221
ffmpeg_install.py
Normal file
221
ffmpeg_install.py
Normal file
@ -0,0 +1,221 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: Hmily
|
||||
GitHub: https://github.com/ihmily
|
||||
Copyright (c) 2024 by Hmily, All Rights Reserved.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import platform
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
import requests
|
||||
from tqdm import tqdm
|
||||
from douyinliverecorder.logger import logger
|
||||
|
||||
current_platform = platform.system()
|
||||
execute_dir = os.path.split(os.path.realpath(sys.argv[0]))[0]
|
||||
current_env_path = os.environ.get('PATH')
|
||||
|
||||
|
||||
def unzip_file(zip_path: str | Path, extract_to: str | Path, delete: bool = True) -> None:
|
||||
if not os.path.exists(extract_to):
|
||||
os.makedirs(extract_to)
|
||||
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(extract_to)
|
||||
|
||||
if delete and os.path.exists(zip_path):
|
||||
os.remove(zip_path)
|
||||
|
||||
|
||||
def get_lanzou_download_link(url: str, password: str | None = None) -> str | None:
|
||||
try:
|
||||
headers = {
|
||||
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
|
||||
'Origin': 'https://wweb.lanzouv.com',
|
||||
'Referer': 'https://wweb.lanzouv.com/iXncv0dly6mh',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
|
||||
'Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0',
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
sign = re.search("var skdklds = '(.*?)';", response.text).group(1)
|
||||
data = {
|
||||
'action': 'downprocess',
|
||||
'sign': sign,
|
||||
'p': password,
|
||||
'kd': '1',
|
||||
}
|
||||
response = requests.post('https://wweb.lanzouv.com/ajaxm.php', headers=headers, data=data)
|
||||
json_data = response.json()
|
||||
download_url = json_data['dom'] + "/file/" + json_data['url']
|
||||
response = requests.get(download_url, headers=headers)
|
||||
return response.url
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to obtain ffmpeg download address. {e}")
|
||||
|
||||
|
||||
def install_ffmpeg_windows():
|
||||
try:
|
||||
logger.warning("ffmpeg is not installed.")
|
||||
logger.debug("Installing the stable version of ffmpeg for Windows...")
|
||||
ffmpeg_url = get_lanzou_download_link('https://wweb.lanzouv.com/in54b2gmj24b', 'e3ut')
|
||||
if ffmpeg_url:
|
||||
full_file_name = 'ffmpeg-7.1.zip'
|
||||
version = '7.1'
|
||||
zip_file_path = Path(execute_dir) / full_file_name
|
||||
if Path(zip_file_path).exists():
|
||||
logger.debug("ffmpeg installation file already exists, start install...")
|
||||
else:
|
||||
response = requests.get(ffmpeg_url, stream=True)
|
||||
total_size = int(response.headers.get('Content-Length', 0))
|
||||
block_size = 1024
|
||||
|
||||
with tqdm(total=total_size, unit="B", unit_scale=True,
|
||||
ncols=100, desc=f'Downloading ffmpeg ({version})') as t:
|
||||
with open(zip_file_path, 'wb') as f:
|
||||
for data in response.iter_content(block_size):
|
||||
t.update(len(data))
|
||||
f.write(data)
|
||||
|
||||
unzip_file(zip_file_path, execute_dir)
|
||||
extract_dir_path = str(zip_file_path).rsplit('.', maxsplit=1)[0]
|
||||
os.environ['PATH'] = execute_dir + '/' + extract_dir_path + os.pathsep + current_env_path
|
||||
result = subprocess.run(["ffmpeg", "-version"], capture_output=True)
|
||||
if result.returncode == 0:
|
||||
logger.debug('ffmpeg installation was successful')
|
||||
else:
|
||||
logger.error('ffmpeg installation failed. Please manually install ffmpeg by yourself')
|
||||
return True
|
||||
else:
|
||||
logger.error("Please manually install ffmpeg by yourself")
|
||||
except Exception as e:
|
||||
logger.error(f"type: {type(e).__name__}, ffmpeg installation failed {e}")
|
||||
|
||||
|
||||
def install_ffmpeg_mac():
|
||||
logger.warning("ffmpeg is not installed.")
|
||||
logger.debug("Installing the stable version of ffmpeg for macOS...")
|
||||
try:
|
||||
result = subprocess.run(["brew", "install", "ffmpeg"], capture_output=True)
|
||||
if result.returncode == 0:
|
||||
logger.debug('ffmpeg installation was successful. Restart for changes to take effect.')
|
||||
return True
|
||||
else:
|
||||
logger.error("ffmpeg installation failed")
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f"Failed to install ffmpeg using Homebrew. {e}")
|
||||
logger.error("Please install ffmpeg manually or check your Homebrew installation.")
|
||||
except Exception as e:
|
||||
logger.error(f"An unexpected error occurred: {e}")
|
||||
|
||||
|
||||
def install_ffmpeg_linux():
|
||||
is_RHS = True
|
||||
|
||||
try:
|
||||
logger.warning("ffmpeg is not installed.")
|
||||
logger.debug("Trying to install the stable version of ffmpeg")
|
||||
result = subprocess.run(['yum', '-y', 'update'], capture_output=True)
|
||||
if result.returncode != 0:
|
||||
logger.error(f"Failed to update package lists using yum.")
|
||||
return False
|
||||
|
||||
result = subprocess.run(['yum', 'install', '-y', 'ffmpeg'], capture_output=True)
|
||||
if result.returncode == 0:
|
||||
logger.debug("ffmpeg installation was successful using yum. Restart for changes to take effect.")
|
||||
return True
|
||||
logger.error(result.stderr.decode('utf-8').strip())
|
||||
except FileNotFoundError:
|
||||
logger.debug("yum command not found, trying to install using apt...")
|
||||
is_RHS = False
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred while trying to install ffmpeg using yum: {e}")
|
||||
|
||||
if not is_RHS:
|
||||
try:
|
||||
logger.debug("Trying to install the stable version of ffmpeg for Linux using apt...")
|
||||
result = subprocess.run(['apt', 'update'], capture_output=True)
|
||||
if result.returncode != 0:
|
||||
logger.error("Failed to update package lists using apt")
|
||||
return False
|
||||
|
||||
result = subprocess.run(['apt', 'install', '-y', 'ffmpeg'], capture_output=True)
|
||||
if result.returncode == 0:
|
||||
logger.debug("ffmpeg installation was successful using apt. Restart for changes to take effect.")
|
||||
return True
|
||||
else:
|
||||
logger.error(result.stderr.decode('utf-8').strip())
|
||||
except FileNotFoundError:
|
||||
logger.error("apt command not found, unable to install ffmpeg. Please manually install ffmpeg by yourself")
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred while trying to install ffmpeg using apt: {e}")
|
||||
logger.error("Manual installation of ffmpeg is required. Please manually install ffmpeg by yourself.")
|
||||
return False
|
||||
|
||||
|
||||
def install_ffmpeg() -> bool:
|
||||
if current_platform == "Windows":
|
||||
return install_ffmpeg_windows()
|
||||
elif current_platform == "Linux":
|
||||
return install_ffmpeg_linux()
|
||||
elif current_platform == "Darwin":
|
||||
return install_ffmpeg_mac()
|
||||
else:
|
||||
logger.debug(f"ffmpeg auto installation is not supported on this platform: {current_platform}. "
|
||||
f"Please install ffmpeg manually.")
|
||||
return False
|
||||
|
||||
|
||||
def ensure_ffmpeg_installed(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
result = subprocess.run(['ffmpeg', '-version'], capture_output=True)
|
||||
version = result.stdout.strip()
|
||||
if result.returncode == 0 and version:
|
||||
return func(*args, **kwargs)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return False
|
||||
|
||||
def wrapped_func(*args, **kwargs):
|
||||
if sys.version_info >= (3, 7):
|
||||
res = wrapper(*args, **kwargs)
|
||||
else:
|
||||
res = wrapper(*args, **kwargs)
|
||||
if not res:
|
||||
install_ffmpeg()
|
||||
res = wrapper(*args, **kwargs)
|
||||
|
||||
if not res:
|
||||
raise RuntimeError("ffmpeg is not installed.")
|
||||
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapped_func
|
||||
|
||||
|
||||
def check_ffmpeg_installed() -> bool:
|
||||
try:
|
||||
result = subprocess.run(['ffmpeg', '-version'], capture_output=True)
|
||||
version = result.stdout.strip()
|
||||
if result.returncode == 0 and version:
|
||||
return True
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
except OSError as e:
|
||||
print(f"OSError occurred: {e}. ffmpeg may not be installed correctly or is not available in the system PATH.")
|
||||
print("Please delete the ffmpeg and try to download and install again.")
|
||||
except Exception as e:
|
||||
print(f"An unexpected error occurred: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def check_ffmpeg() -> bool:
|
||||
if not check_ffmpeg_installed():
|
||||
return install_ffmpeg()
|
||||
return True
|
||||
25
main.py
25
main.py
@ -4,7 +4,7 @@
|
||||
Author: Hmily
|
||||
GitHub: https://github.com/ihmily
|
||||
Date: 2023-07-17 23:52:05
|
||||
Update: 2024-11-16 04:28:00
|
||||
Update: 2024-11-29 19:53:00
|
||||
Copyright (c) 2023-2024 by Hmily, All Rights Reserved.
|
||||
Function: Record live stream video.
|
||||
"""
|
||||
@ -27,6 +27,7 @@ import urllib.request
|
||||
from urllib.error import URLError, HTTPError
|
||||
from typing import Any
|
||||
import configparser
|
||||
from ffmpeg_install import check_ffmpeg
|
||||
from douyinliverecorder import spider, stream
|
||||
from douyinliverecorder.proxy import ProxyDetector
|
||||
from douyinliverecorder.utils import logger
|
||||
@ -1063,7 +1064,8 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None:
|
||||
_filepath, _ = urllib.request.urlretrieve(flv_url, save_file_path)
|
||||
record_finished = True
|
||||
recording.discard(record_name)
|
||||
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")
|
||||
else:
|
||||
logger.debug("未找到FLV直播流,跳过录制")
|
||||
except Exception as e:
|
||||
@ -1435,33 +1437,29 @@ def backup_file_start() -> None:
|
||||
logger.error(f"备份配置文件失败, 错误信息: {e}")
|
||||
|
||||
|
||||
# --------------------------检查是否存在ffmpeg-------------------------------------
|
||||
def check_ffmpeg_existence() -> bool:
|
||||
dev_null = open(os.devnull, 'wb')
|
||||
try:
|
||||
subprocess.run(['ffmpeg', '--help'], stdout=dev_null, stderr=dev_null, check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(e)
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
ffmpeg_file_check = subprocess.getoutput(ffmpeg_path)
|
||||
if ffmpeg_file_check.find("run") > -1 and os.path.isfile(ffmpeg_path):
|
||||
os.environ['PATH'] += os.pathsep + os.path.dirname(os.path.abspath(ffmpeg_path))
|
||||
# print(f"已将ffmpeg路径添加到环境变量:{ffmpeg_path}")
|
||||
return True
|
||||
else:
|
||||
logger.error("未检测到ffmpeg,请确保ffmpeg位于系统路径中,或将其路径添加到环境变量。")
|
||||
sys.exit(0)
|
||||
finally:
|
||||
dev_null.close()
|
||||
return True
|
||||
if check_ffmpeg():
|
||||
time.sleep(1)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# --------------------------初始化程序-------------------------------------
|
||||
if not check_ffmpeg_existence():
|
||||
logger.error("缺少ffmpeg无法进行录制,程序退出")
|
||||
sys.exit(1)
|
||||
|
||||
# --------------------------初始化程序-------------------------------------
|
||||
print("-----------------------------------------------------")
|
||||
print("| DouyinLiveRecorder |")
|
||||
print("-----------------------------------------------------")
|
||||
@ -1524,7 +1522,8 @@ try:
|
||||
except HTTPError as err:
|
||||
print(f"HTTP error occurred: {err.code} - {err.reason}")
|
||||
except URLError as err:
|
||||
color_obj.print_colored(f"INFO:未检测到全局/规则网络代理,请检查代理配置(若无需录制海外直播请忽略此条提示)", color_obj.YELLOW)
|
||||
color_obj.print_colored(f"INFO:未检测到全局/规则网络代理,请检查代理配置(若无需录制海外直播请忽略此条提示)",
|
||||
color_obj.YELLOW)
|
||||
except Exception as err:
|
||||
print("An unexpected error occurred:", err)
|
||||
|
||||
@ -1873,5 +1872,3 @@ while True:
|
||||
first_run = False
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user