Initial
This commit is contained in:
148
.gitignore
vendored
Normal file
148
.gitignore
vendored
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
68
yt_dlp_plugins/extractor/filemoon.py
Normal file
68
yt_dlp_plugins/extractor/filemoon.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from Crypto.Cipher import AES
|
||||||
|
|
||||||
|
from yt_dlp.extractor.common import InfoExtractor
|
||||||
|
|
||||||
|
|
||||||
|
class FilemoonIE(InfoExtractor):
|
||||||
|
_valid_domains = r'|'.join([
|
||||||
|
r'filemoon\.sx', r'bysejikuar\.com', r'bysedikamoum\.com',
|
||||||
|
r'byse\.sx', r'byseraguci\.com', r'bysezejataos\.com',
|
||||||
|
r'filemoon\.to', r'filemoon\.eu', r'filemooon\.link',
|
||||||
|
r'morgan0928-6v7c14vs\.fun', r'bf0skv\.org',
|
||||||
|
r'ghajini-emtftw1o\.lol', r'f51rm\.com', r'filemooon\.link',
|
||||||
|
r'bysekoze\.com', r'bysesayeveum\.com'
|
||||||
|
])
|
||||||
|
_VALID_URL = r'https?://(?:' + _valid_domains + ')/(?:d|e)/(?P<id>[^?#]+)?$'
|
||||||
|
|
||||||
|
def fix_base64(self, text):
|
||||||
|
replaced = text.replace('-','+').replace('_','/')
|
||||||
|
padding_length = 0 if (len(replaced) % 4 == 0) else 4 - len(replaced) % 4
|
||||||
|
return base64.b64decode(replaced + '=' * padding_length)
|
||||||
|
|
||||||
|
def fix_key_parts(self, key_parts):
|
||||||
|
fixed = [self.fix_base64(key_part) for key_part in key_parts]
|
||||||
|
return b''.join(fixed)
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = urllib.parse.unquote_plus(self._match_id(url))
|
||||||
|
|
||||||
|
metadata = self._download_json(f'https://filemoon.to/api/videos/{video_id}/details', video_id)
|
||||||
|
playback = self._download_json(f'https://filemoon.to/api/videos/{video_id}/playback', video_id)
|
||||||
|
|
||||||
|
iv = self.fix_base64(playback['playback']['iv'])
|
||||||
|
ciphertext = self.fix_base64(playback['playback']['payload'])
|
||||||
|
key = self.fix_key_parts(playback['playback']['key_parts'])
|
||||||
|
|
||||||
|
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
|
||||||
|
plaintext = cipher.decrypt_and_verify(ciphertext[:-16], ciphertext[-16:])
|
||||||
|
|
||||||
|
content = json.loads(plaintext.decode('utf8'))
|
||||||
|
|
||||||
|
print(json.dumps(content, indent=4))
|
||||||
|
|
||||||
|
m3u8_url = content['sources'][0]['url']
|
||||||
|
formats = self._extract_m3u8_formats(
|
||||||
|
m3u8_url, video_id, 'mp4',
|
||||||
|
'm3u8_native', m3u8_id='hls')
|
||||||
|
|
||||||
|
created_at = datetime.fromisoformat(metadata['created_at']).strftime('%Y%m%d')
|
||||||
|
|
||||||
|
ret = {
|
||||||
|
'id': video_id,
|
||||||
|
'display_id': video_id,
|
||||||
|
'title': metadata['title'],
|
||||||
|
'thumbnail': f'https://img-place.com/{video_id}.jpg',
|
||||||
|
'upload_date': created_at,
|
||||||
|
'formats': formats,
|
||||||
|
}
|
||||||
|
|
||||||
|
print(json.dumps(ret, indent=4))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
Reference in New Issue
Block a user