forked from ihmily/DouyinLiveRecorder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ffmpeg_install.py
221 lines (188 loc) · 8.43 KB
/
ffmpeg_install.py
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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 = 'v7.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