DDownloader 0.1.0__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.
- DDownloader/__init__.py +3 -0
- DDownloader/dash_downloader.py +44 -0
- DDownloader/decrypt_downloader.py +39 -0
- DDownloader/hls_downloader.py +40 -0
- DDownloader-0.1.0.dist-info/METADATA +12 -0
- DDownloader-0.1.0.dist-info/RECORD +9 -0
- DDownloader-0.1.0.dist-info/WHEEL +5 -0
- DDownloader-0.1.0.dist-info/entry_points.txt +2 -0
- DDownloader-0.1.0.dist-info/top_level.txt +1 -0
DDownloader/__init__.py
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
import requests
|
2
|
+
import os
|
3
|
+
import xml.etree.ElementTree as ET
|
4
|
+
import subprocess
|
5
|
+
|
6
|
+
class DASHDownloader:
|
7
|
+
def __init__(self, manifest_url):
|
8
|
+
self.manifest_url = manifest_url
|
9
|
+
self.binary_path = os.path.join(os.path.dirname(__file__), 'bin', 'N_m3u8DL-RE')
|
10
|
+
|
11
|
+
def download_with_n_m3u8dl(self):
|
12
|
+
command = [self.binary_path, self.manifest_url]
|
13
|
+
try:
|
14
|
+
exit_code = subprocess.run(command, check=True)
|
15
|
+
print("Downloaded using N_m3u8DL-RE")
|
16
|
+
except subprocess.CalledProcessError as e:
|
17
|
+
print(f"Error during download: {e}")
|
18
|
+
|
19
|
+
def download_manifest(self):
|
20
|
+
response = requests.get(self.manifest_url)
|
21
|
+
response.raise_for_status()
|
22
|
+
return response.content
|
23
|
+
|
24
|
+
def download_segments(self, manifest_content, output_dir='downloads'):
|
25
|
+
os.makedirs(output_dir, exist_ok=True)
|
26
|
+
root = ET.fromstring(manifest_content)
|
27
|
+
|
28
|
+
for adaptation_set in root.findall('.//AdaptationSet'):
|
29
|
+
for representation in adaptation_set.findall('Representation'):
|
30
|
+
base_url = representation.attrib.get('baseURL', '')
|
31
|
+
for segment in representation.findall('.//SegmentURL'):
|
32
|
+
segment_url = base_url + segment.attrib['media']
|
33
|
+
self.download_segment(segment_url, output_dir)
|
34
|
+
|
35
|
+
def download_segment(self, segment_url, output_dir):
|
36
|
+
response = requests.get(segment_url, stream=True)
|
37
|
+
response.raise_for_status()
|
38
|
+
|
39
|
+
filename = os.path.join(output_dir, segment_url.split("/")[-1])
|
40
|
+
with open(filename, 'wb') as f:
|
41
|
+
for chunk in response.iter_content(chunk_size=8192):
|
42
|
+
f.write(chunk)
|
43
|
+
|
44
|
+
print(f"Downloaded: {filename}")
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import os
|
2
|
+
import subprocess
|
3
|
+
|
4
|
+
class DecryptDownloader:
|
5
|
+
def __init__(self):
|
6
|
+
self.kid = None
|
7
|
+
self.key = None
|
8
|
+
self.manifest_url = None
|
9
|
+
self.binary_path = os.path.join(os.path.dirname(__file__), 'bin', 'mp4decrypt') # Adjust if necessary
|
10
|
+
|
11
|
+
def set_manifest_url(self, manifest_url):
|
12
|
+
self.manifest_url = manifest_url
|
13
|
+
|
14
|
+
def set_decryption_key(self, key):
|
15
|
+
self.key = key
|
16
|
+
|
17
|
+
def set_kid(self, kid):
|
18
|
+
self.kid = kid
|
19
|
+
|
20
|
+
def download_and_decrypt(self, input_file, output_file):
|
21
|
+
if not self.key:
|
22
|
+
print("Decryption key is not set.")
|
23
|
+
return
|
24
|
+
|
25
|
+
self.download_media_file() # Placeholder for your download logic
|
26
|
+
|
27
|
+
command = [self.binary_path, '--key', f'{self.kid}:{self.key}', input_file, output_file]
|
28
|
+
try:
|
29
|
+
exit_code = subprocess.run(command, check=True)
|
30
|
+
print(f"Decrypted file saved as: {output_file}")
|
31
|
+
except subprocess.CalledProcessError as e:
|
32
|
+
print(f"Error during decryption: {e}")
|
33
|
+
|
34
|
+
def download_media_file(self):
|
35
|
+
if not self.manifest_url:
|
36
|
+
print("Manifest URL is not set.")
|
37
|
+
return
|
38
|
+
|
39
|
+
print(f"Downloading media from: {self.manifest_url}")
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import requests
|
2
|
+
import os
|
3
|
+
import subprocess
|
4
|
+
|
5
|
+
class HLSDownloader:
|
6
|
+
def __init__(self, manifest_url):
|
7
|
+
self.manifest_url = manifest_url
|
8
|
+
self.binary_path = os.path.join(os.path.dirname(__file__), 'bin', 'N_m3u8DL-RE')
|
9
|
+
|
10
|
+
def download_with_n_m3u8dl(self):
|
11
|
+
command = [self.binary_path, self.manifest_url]
|
12
|
+
try:
|
13
|
+
exit_code = subprocess.run(command, check=True)
|
14
|
+
print("Downloaded using N_m3u8DL-RE")
|
15
|
+
except subprocess.CalledProcessError as e:
|
16
|
+
print(f"Error during download: {e}")
|
17
|
+
|
18
|
+
def download_manifest(self):
|
19
|
+
response = requests.get(self.manifest_url)
|
20
|
+
response.raise_for_status()
|
21
|
+
return response.text
|
22
|
+
|
23
|
+
def download_segments(self, manifest_content, output_dir='downloads'):
|
24
|
+
os.makedirs(output_dir, exist_ok=True)
|
25
|
+
lines = manifest_content.splitlines()
|
26
|
+
for line in lines:
|
27
|
+
if line.endswith('.ts'):
|
28
|
+
segment_url = line
|
29
|
+
self.download_segment(segment_url, output_dir)
|
30
|
+
|
31
|
+
def download_segment(self, segment_url, output_dir):
|
32
|
+
response = requests.get(segment_url, stream=True)
|
33
|
+
response.raise_for_status()
|
34
|
+
|
35
|
+
filename = os.path.join(output_dir, segment_url.split("/")[-1])
|
36
|
+
with open(filename, 'wb') as f:
|
37
|
+
for chunk in response.iter_content(chunk_size=8192):
|
38
|
+
f.write(chunk)
|
39
|
+
|
40
|
+
print(f"Downloaded: {filename}")
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: DDownloader
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: A library to download HLS and DASH manifests and decrypt media files.
|
5
|
+
Author: Pari Malam
|
6
|
+
Author-email: shafiqsamsuri@serasi.tech
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
9
|
+
Classifier: Operating System :: OS Independent
|
10
|
+
Requires-Python: >=3.9
|
11
|
+
Requires-Dist: requests
|
12
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
DDownloader/__init__.py,sha256=o3loo1Z5ZdvQYZIjgdgZarMVMIz5pHRRZ_x0IXYA6nU,135
|
2
|
+
DDownloader/dash_downloader.py,sha256=MTaM_8lmLJ9nFQKY-Q_akr9qsT88nlCy1bODCBV1Io8,1730
|
3
|
+
DDownloader/decrypt_downloader.py,sha256=LdjZkVgyPile6TRueFMNcRdZkkNVwoTL5qNp5i0De_c,1233
|
4
|
+
DDownloader/hls_downloader.py,sha256=OiTw2xdva5eM1QaxKgcRCpvkMaBpdjQrwtYtwvLZm4g,1435
|
5
|
+
DDownloader-0.1.0.dist-info/METADATA,sha256=Ev4md5x6p_faGian9SU7Z2zEj9HYBg_iQmHE9PyrG7M,387
|
6
|
+
DDownloader-0.1.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
7
|
+
DDownloader-0.1.0.dist-info/entry_points.txt,sha256=No1ydBHwuyjy4I_ySPjMQAmZ-KMuuemGlEQvkv4rGyw,58
|
8
|
+
DDownloader-0.1.0.dist-info/top_level.txt,sha256=INZYgY1vEHV1MIWTPXKJL8j8-ZXjWb8u4XLuU3S8umY,12
|
9
|
+
DDownloader-0.1.0.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
DDownloader
|