hs-m3u8 0.1.2__py3-none-any.whl → 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
hs_m3u8/__init__.py
CHANGED
hs_m3u8/main.py
CHANGED
|
@@ -8,10 +8,8 @@ import posixpath
|
|
|
8
8
|
import shutil
|
|
9
9
|
import subprocess
|
|
10
10
|
from collections.abc import Callable
|
|
11
|
-
from enum import Enum, auto
|
|
12
11
|
from hashlib import md5
|
|
13
12
|
from pathlib import Path
|
|
14
|
-
from typing import Any
|
|
15
13
|
from urllib.parse import urljoin, urlparse
|
|
16
14
|
from zipfile import ZipFile
|
|
17
15
|
|
|
@@ -46,16 +44,6 @@ def get_ffmpeg():
|
|
|
46
44
|
return ffmpeg_bin
|
|
47
45
|
|
|
48
46
|
|
|
49
|
-
class ContentType(Enum):
|
|
50
|
-
"""
|
|
51
|
-
获取URL数据的,类型枚举
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
Text = auto()
|
|
55
|
-
Json = auto()
|
|
56
|
-
Bytes = auto()
|
|
57
|
-
|
|
58
|
-
|
|
59
47
|
class M3u8Key:
|
|
60
48
|
"""
|
|
61
49
|
M3u8key
|
|
@@ -80,6 +68,7 @@ class M3u8Downloader:
|
|
|
80
68
|
ts_url_list: list = []
|
|
81
69
|
ts_path_list: list = []
|
|
82
70
|
ts_key: M3u8Key = None
|
|
71
|
+
mp4_head_hrl: str = None
|
|
83
72
|
m3u8_md5 = ""
|
|
84
73
|
|
|
85
74
|
def __init__(
|
|
@@ -165,7 +154,7 @@ class M3u8Downloader:
|
|
|
165
154
|
if not merge:
|
|
166
155
|
return True
|
|
167
156
|
|
|
168
|
-
if self.merge():
|
|
157
|
+
if await self.merge():
|
|
169
158
|
self.logger.info("合并成功")
|
|
170
159
|
else:
|
|
171
160
|
self.logger.error(
|
|
@@ -185,30 +174,6 @@ class M3u8Downloader:
|
|
|
185
174
|
self.ts_path_list = [None] * len(self.ts_url_list)
|
|
186
175
|
await asyncio.gather(*[self._download_ts(url) for url in self.ts_url_list])
|
|
187
176
|
|
|
188
|
-
async def get_url_content(self, url: str, content_type: ContentType) -> bytes | str | Any:
|
|
189
|
-
"""
|
|
190
|
-
按照类型获取url内容
|
|
191
|
-
:param url: 请求地址
|
|
192
|
-
:param content_type: 内容类型
|
|
193
|
-
:return:
|
|
194
|
-
"""
|
|
195
|
-
data = None
|
|
196
|
-
try:
|
|
197
|
-
resp = await self.net.get(url, headers=self.headers)
|
|
198
|
-
if content_type == ContentType.Bytes:
|
|
199
|
-
data = resp.content
|
|
200
|
-
if content_type == ContentType.Text:
|
|
201
|
-
data = resp.text
|
|
202
|
-
if content_type == ContentType.Json:
|
|
203
|
-
data = resp.json
|
|
204
|
-
if resp.status_code != 200:
|
|
205
|
-
self.logger.error(f"请求{url}内容时返回码不正确,类型为:{content_type}, 返回码为:{resp.status_code}")
|
|
206
|
-
return None
|
|
207
|
-
except BaseException as exception:
|
|
208
|
-
self.logger.error(f"请求{url}内容时发生异常,类型为:{content_type}, 异常信息为:{exception}")
|
|
209
|
-
|
|
210
|
-
return data
|
|
211
|
-
|
|
212
177
|
async def get_ts_list(self, url) -> list[dict]:
|
|
213
178
|
"""
|
|
214
179
|
解析m3u8并保存至列表
|
|
@@ -235,6 +200,14 @@ class M3u8Downloader:
|
|
|
235
200
|
self.logger.info(f"选择的播放地址:{play_url},比特率:{bandwidth}")
|
|
236
201
|
return await self.get_ts_list(urlparse(play_url))
|
|
237
202
|
|
|
203
|
+
# 处理具有 #EXT-X-MAP:URI="*.mp4" 的情况
|
|
204
|
+
segment_map_count = len(m3u8_obj.segment_map)
|
|
205
|
+
if segment_map_count > 0:
|
|
206
|
+
if segment_map_count > 1:
|
|
207
|
+
raise ValueError("暂不支持segment_map有多个的情况,请提交issues,并告知m3u8的地址,方便做适配")
|
|
208
|
+
self.mp4_head_hrl = prefix + m3u8_obj.segment_map[0].uri
|
|
209
|
+
m3u8_obj.segment_map[0].uri = "head.mp4"
|
|
210
|
+
|
|
238
211
|
# 遍历ts文件
|
|
239
212
|
for index, segments in enumerate(m3u8_obj.segments):
|
|
240
213
|
ts_uri = segments.uri if "http" in m3u8_obj.segments[index].uri else segments.absolute_uri
|
|
@@ -283,7 +256,7 @@ class M3u8Downloader:
|
|
|
283
256
|
self.logger.info(f"{ts_uri}下载成功")
|
|
284
257
|
self.ts_path_list[index] = str(ts_path)
|
|
285
258
|
|
|
286
|
-
def merge(self):
|
|
259
|
+
async def merge(self):
|
|
287
260
|
"""
|
|
288
261
|
合并ts文件为mp4文件
|
|
289
262
|
:return:
|
|
@@ -301,8 +274,17 @@ class M3u8Downloader:
|
|
|
301
274
|
# mp4路径
|
|
302
275
|
mp4_path = self.save_dir.parent / f"{self.save_name}.mp4"
|
|
303
276
|
|
|
277
|
+
# 如果保护mp4的头,则把ts放到后面
|
|
278
|
+
mp4_head_data = b""
|
|
279
|
+
if self.mp4_head_hrl:
|
|
280
|
+
resp = await self.net.get(self.mp4_head_hrl)
|
|
281
|
+
mp4_head_data = resp.content
|
|
282
|
+
mp4_head_file = self.save_dir / "head.mp4"
|
|
283
|
+
mp4_head_file.write_bytes(mp4_head_data)
|
|
284
|
+
|
|
304
285
|
# 把ts文件整合到一起
|
|
305
286
|
big_ts_file = big_ts_path.open("ab+")
|
|
287
|
+
big_ts_file.write(mp4_head_data)
|
|
306
288
|
for path in self.ts_path_list:
|
|
307
289
|
with open(path, "rb") as ts_file:
|
|
308
290
|
data = ts_file.read()
|
|
@@ -316,7 +298,7 @@ class M3u8Downloader:
|
|
|
316
298
|
ffmpeg_bin = get_ffmpeg()
|
|
317
299
|
command = (
|
|
318
300
|
f'{ffmpeg_bin} -i "{big_ts_path}" '
|
|
319
|
-
f'-c copy -map 0:v -map 0:a -bsf:a aac_adtstoasc -threads 32 "{mp4_path}" -y'
|
|
301
|
+
f'-c copy -map 0:v -map 0:a? -bsf:a aac_adtstoasc -threads 32 "{mp4_path}" -y'
|
|
320
302
|
)
|
|
321
303
|
self.logger.info(f"ts整合成功,开始转为mp4。 command:{command}")
|
|
322
304
|
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: hs-m3u8
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: m3u8 下载器
|
|
5
5
|
Project-URL: homepage, https://github.com/x-haose/hs-m3u8
|
|
6
6
|
Project-URL: repository, https://github.com/x-haose/hs-m3u8
|
|
7
7
|
Project-URL: documentation, https://github.com/x-haose/hs-m3u8
|
|
8
8
|
Author-email: 昊色居士 <xhrtxh@gmail.com>
|
|
9
|
-
License: MIT
|
|
9
|
+
License-Expression: MIT
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -36,6 +36,13 @@ m3u8 视频下载工具。支持大部分的m3u8视频下载。后续增加UI界
|
|
|
36
36
|
- 可选择保留ts文件
|
|
37
37
|
- 内置Windows平台ffmpeg可执行文件(由于Linux及Mac下权限问题,需自行安装ffmpeg文件)
|
|
38
38
|
|
|
39
|
+
## 计划
|
|
40
|
+
|
|
41
|
+
- 增加cli功能,通过终端执行命令去下载
|
|
42
|
+
- 增加支持curl参数功能。直接在curl里面读取请求头及cookie
|
|
43
|
+
- 编写详细文档
|
|
44
|
+
- 选择一个合适的技术栈,增加UI界面
|
|
45
|
+
|
|
39
46
|
## 安装
|
|
40
47
|
|
|
41
48
|
### pip包安装
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
hs_m3u8/__init__.py,sha256=t0R3Q2zVnUtOiJ8e2sL29N4QkkBHXKgC54n6OqMbwJs,63
|
|
2
|
+
hs_m3u8/main.py,sha256=kJ4HV1eISz80ttxsr2E9K-tfTKK79URiEJviPcc5tfg,11259
|
|
3
|
+
hs_m3u8-0.1.3.dist-info/METADATA,sha256=nskQSk_KjDfVtGPhdr6cYXdJbfrbHJXnf7JnvtxIcjg,2204
|
|
4
|
+
hs_m3u8-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
5
|
+
hs_m3u8-0.1.3.dist-info/RECORD,,
|
hs_m3u8-0.1.2.dist-info/RECORD
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
hs_m3u8/__init__.py,sha256=VWzgd1ZOktIFqMuyNnZFhKltLMFS7g9IOS5FUZXZpoE,63
|
|
2
|
-
hs_m3u8/main.py,sha256=tq-JtMzfEy1YTTpZFL9Oas5ZzrON3eigWxlKAduc-oU,11592
|
|
3
|
-
hs_m3u8-0.1.2.dist-info/METADATA,sha256=e6BAuDJEiq0k_mhn5uuYUpLcW6f6eEw1yocday1-NW0,1979
|
|
4
|
-
hs_m3u8-0.1.2.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
5
|
-
hs_m3u8-0.1.2.dist-info/RECORD,,
|