mirror of
https://cdm-project.com/Download-Tools/udemy-downloader.git
synced 2025-04-30 01:04:26 +02:00
Merge branch 'feat/refactor'
This commit is contained in:
commit
4b80e32433
54
README.md
54
README.md
@ -20,11 +20,24 @@
|
|||||||
Utility script to download Udemy courses, has support for DRM videos but requires the user to acquire the decryption key (for legal reasons).<br>
|
Utility script to download Udemy courses, has support for DRM videos but requires the user to acquire the decryption key (for legal reasons).<br>
|
||||||
Windows is the primary development OS, but I've made an effort to support Linux also (Mac untested).
|
Windows is the primary development OS, but I've made an effort to support Linux also (Mac untested).
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> The ability to download captions automatically is currently broken due to changes in Udemy's API!
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> This tool will not work on encrypted courses without decryption keys being provided!
|
||||||
|
>
|
||||||
|
> Downloading courses is against Udemy's Terms of Service, I am NOT held responsible for your account getting suspended as a result from the use of this program!
|
||||||
|
>
|
||||||
|
> This program is WIP, the code is provided as-is and I am not held resposible for any legal issues resulting from the use of this program.
|
||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
|
|
||||||
The following are a list of required third-party tools, you will need to ensure they are in your systems path and that typing their name in a terminal invokes them.
|
The following are a list of required third-party tools, you will need to ensure they are in your systems path and that typing their name in a terminal invokes them.
|
||||||
|
|
||||||
_**Note**:_ _These are seperate requirements that are not installed with the pip command! You will need to download and install these manually!_
|
> [!NOTE]
|
||||||
|
> These are seperate requirements that are not installed with the pip command!
|
||||||
|
>
|
||||||
|
> You will need to download and install these manually!
|
||||||
|
|
||||||
- [Python 3](https://python.org/)
|
- [Python 3](https://python.org/)
|
||||||
- [ffmpeg](https://www.ffmpeg.org/) - This tool is also available in Linux package repositories.
|
- [ffmpeg](https://www.ffmpeg.org/) - This tool is also available in Linux package repositories.
|
||||||
@ -35,8 +48,6 @@ _**Note**:_ _These are seperate requirements that are not installed with the pip
|
|||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
_quick and dirty how-to_
|
|
||||||
|
|
||||||
You will need to get a few things before you can use this program:
|
You will need to get a few things before you can use this program:
|
||||||
|
|
||||||
- Decryption Key ID
|
- Decryption Key ID
|
||||||
@ -58,7 +69,10 @@ You will need to get a few things before you can use this program:
|
|||||||
|
|
||||||
## Key ID and Key
|
## Key ID and Key
|
||||||
|
|
||||||
It is up to you to acquire the key and key ID. Please **DO NOT** ask me for help acquiring these, decrypting DRM protected content can be considered piracy. The tool required for this has already been discused in a GitHub issue.
|
> [!IMPORTANT]
|
||||||
|
> For courses that are encrypted, It is up to you to acquire the decryption keys.
|
||||||
|
>
|
||||||
|
> Please **DO NOT** ask me for help acquiring these!
|
||||||
|
|
||||||
- Enter the key and key id in the `keyfile.json`
|
- Enter the key and key id in the `keyfile.json`
|
||||||
- 
|
- 
|
||||||
@ -66,18 +80,21 @@ It is up to you to acquire the key and key ID. Please **DO NOT** ask me for help
|
|||||||
|
|
||||||
## Cookies
|
## Cookies
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> Cookies are not required for individually purchased courses.
|
||||||
|
|
||||||
To download a course included in a subscription plan that you did not purchase individually, you will need to use cookies. You can also use cookies as an alternative to Bearer Tokens.
|
To download a course included in a subscription plan that you did not purchase individually, you will need to use cookies. You can also use cookies as an alternative to Bearer Tokens.
|
||||||
|
|
||||||
The program can automatically extract them from your browser. You can specify what browser to extract cookies from with the `--browser` argument. Supported browsers are:
|
The program can automatically extract them from your browser. You can specify what browser to extract cookies from with the `--browser` argument. Supported browsers are:
|
||||||
|
|
||||||
- chrome
|
- `chrome`
|
||||||
- firefox
|
- `firefox`
|
||||||
- opera
|
- `opera`
|
||||||
- edge
|
- `edge`
|
||||||
- brave
|
- `brave`
|
||||||
- chromium
|
- `chromium`
|
||||||
- vivaldi
|
- `vivaldi`
|
||||||
- safari
|
- `safari`
|
||||||
|
|
||||||
## Ready to go
|
## Ready to go
|
||||||
|
|
||||||
@ -86,7 +103,7 @@ You can now run the program, see the examples below. The course will download to
|
|||||||
# Advanced Usage
|
# Advanced Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
usage: main.py [-h] -c COURSE_URL [-b BEARER_TOKEN] [-q QUALITY] [-l LANG] [-cd CONCURRENT_DOWNLOADS] [--disable-ipv6] [--skip-lectures] [--download-assets]
|
usage: main.py [-h] -c COURSE_URL [-b BEARER_TOKEN] [-q QUALITY] [-l LANG] [-cd CONCURRENT_DOWNLOADS] [--skip-lectures] [--download-assets]
|
||||||
[--download-captions] [--download-quizzes] [--keep-vtt] [--skip-hls] [--info] [--id-as-course-name] [-sc] [--save-to-file] [--load-from-file]
|
[--download-captions] [--download-quizzes] [--keep-vtt] [--skip-hls] [--info] [--id-as-course-name] [-sc] [--save-to-file] [--load-from-file]
|
||||||
[--log-level LOG_LEVEL] [--browser {chrome,firefox,opera,edge,brave,chromium,vivaldi,safari}] [--use-h265] [--h265-crf H265_CRF] [--h265-preset H265_PRESET]
|
[--log-level LOG_LEVEL] [--browser {chrome,firefox,opera,edge,brave,chromium,vivaldi,safari}] [--use-h265] [--h265-crf H265_CRF] [--h265-preset H265_PRESET]
|
||||||
[--use-nvenc] [--out OUT] [--continue-lecture-numbers]
|
[--use-nvenc] [--out OUT] [--continue-lecture-numbers]
|
||||||
@ -105,7 +122,6 @@ options:
|
|||||||
-l LANG, --lang LANG The language to download for captions, specify 'all' to download all captions (Default is 'en')
|
-l LANG, --lang LANG The language to download for captions, specify 'all' to download all captions (Default is 'en')
|
||||||
-cd CONCURRENT_DOWNLOADS, --concurrent-downloads CONCURRENT_DOWNLOADS
|
-cd CONCURRENT_DOWNLOADS, --concurrent-downloads CONCURRENT_DOWNLOADS
|
||||||
The number of maximum concurrent downloads for segments (HLS and DASH, must be a number 1-30)
|
The number of maximum concurrent downloads for segments (HLS and DASH, must be a number 1-30)
|
||||||
--disable-ipv6 If specified, ipv6 will be disabled in aria2
|
|
||||||
--skip-lectures If specified, lectures won't be downloaded
|
--skip-lectures If specified, lectures won't be downloaded
|
||||||
--download-assets If specified, lecture assets will be downloaded
|
--download-assets If specified, lecture assets will be downloaded
|
||||||
--download-captions If specified, captions will be downloaded
|
--download-captions If specified, captions will be downloaded
|
||||||
@ -187,16 +203,6 @@ options:
|
|||||||
- `python main.py -c <Course URL> --continue-lecture-numbers`
|
- `python main.py -c <Course URL> --continue-lecture-numbers`
|
||||||
- `python main.py -c <Course URL> -n`
|
- `python main.py -c <Course URL> -n`
|
||||||
|
|
||||||
If you encounter errors while downloading such as
|
|
||||||
|
|
||||||
`errorCode=1 Network problem has occurred. cause:Unknown socket error 10051 (0x2743)`
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
`errorCode=1 Network problem has occurred. cause:A socket operation was attempted to an unreachable network.`
|
|
||||||
|
|
||||||
Then try disabling ipv6 in aria2 using the `--disable-ipv6` option
|
|
||||||
|
|
||||||
# Support
|
# Support
|
||||||
|
|
||||||
if you want help using the program, join my [Discord](https://discord.gg/tMzrSxQ) server or use [GitHub Issues](https://github.com/Puyodead1/udemy-downloader/issues)
|
if you want help using the program, join my [Discord](https://discord.gg/tMzrSxQ) server or use [GitHub Issues](https://github.com/Puyodead1/udemy-downloader/issues)
|
||||||
|
12
constants.py
12
constants.py
@ -11,7 +11,8 @@ HEADERS = {
|
|||||||
}
|
}
|
||||||
LOGIN_URL = "https://www.udemy.com/join/login-popup/?ref=&display_type=popup&loc"
|
LOGIN_URL = "https://www.udemy.com/join/login-popup/?ref=&display_type=popup&loc"
|
||||||
LOGOUT_URL = "https://www.udemy.com/user/logout"
|
LOGOUT_URL = "https://www.udemy.com/user/logout"
|
||||||
COURSE_URL = "https://{portal_name}.udemy.com/api-2.0/courses/{course_id}/cached-subscriber-curriculum-items?fields[asset]=results,title,external_url,time_estimation,download_urls,slide_urls,filename,asset_type,captions,media_license_token,course_is_drmed,media_sources,stream_urls,body&fields[chapter]=object_index,title,sort_order&fields[lecture]=id,title,object_index,asset,supplementary_assets,view_html&page_size=10000"
|
# COURSE_URL = "https://{portal_name}.udemy.com/api-2.0/courses/{course_id}/cached-subscriber-curriculum-items?fields[asset]=results,title,external_url,time_estimation,download_urls,slide_urls,filename,asset_type,captions,media_license_token,course_is_drmed,media_sources,stream_urls,body&fields[chapter]=object_index,title,sort_order&fields[lecture]=id,title,object_index,asset,supplementary_assets,view_html&page_size=10000"
|
||||||
|
COURSE_URL = "https://{portal_name}.udemy.com/api-2.0/courses/{course_id}/subscriber-curriculum-items/?page_size=100&fields[asset]=asset_type,length,media_license_token,course_is_drmed,media_sources,thumbnail_sprite,slides,slide_urls,filename,download_urls,external_url,stream_urls&fields[chapter]=object_index,title&fields[lecture]=id,title,object_index,asset,supplementary_assets,view_html&caching_intent=True"
|
||||||
COURSE_INFO_URL = "https://{portal_name}.udemy.com/api-2.0/courses/{course_id}/"
|
COURSE_INFO_URL = "https://{portal_name}.udemy.com/api-2.0/courses/{course_id}/"
|
||||||
COURSE_SEARCH = "https://{portal_name}.udemy.com/api-2.0/users/me/subscribed-courses?fields[course]=id,url,title,published_title&page=1&page_size=500&search={course_name}"
|
COURSE_SEARCH = "https://{portal_name}.udemy.com/api-2.0/users/me/subscribed-courses?fields[course]=id,url,title,published_title&page=1&page_size=500&search={course_name}"
|
||||||
SUBSCRIBED_COURSES = "https://{portal_name}.udemy.com/api-2.0/users/me/subscribed-courses/?ordering=-last_accessed&fields[course]=id,title,url&page=1&page_size=12"
|
SUBSCRIBED_COURSES = "https://{portal_name}.udemy.com/api-2.0/users/me/subscribed-courses/?ordering=-last_accessed&fields[course]=id,title,url&page=1&page_size=12"
|
||||||
@ -25,7 +26,10 @@ KEY_FILE_PATH = os.path.join(os.getcwd(), "keyfile.json")
|
|||||||
COOKIE_FILE_PATH = os.path.join(os.getcwd(), "cookies.txt")
|
COOKIE_FILE_PATH = os.path.join(os.getcwd(), "cookies.txt")
|
||||||
LOG_DIR_PATH = os.path.join(os.getcwd(), "logs")
|
LOG_DIR_PATH = os.path.join(os.getcwd(), "logs")
|
||||||
LOG_FILE_PATH = os.path.join(
|
LOG_FILE_PATH = os.path.join(
|
||||||
os.getcwd(), "logs", f"{time.strftime('%Y-%m-%d-%I-%M-%S')}.log")
|
os.getcwd(), "logs", f"{time.strftime('%Y-%m-%d-%I-%M-%S')}.log"
|
||||||
LOG_FORMAT = '[%(asctime)s] [%(name)s] [%(funcName)s:%(lineno)d] %(levelname)s: %(message)s'
|
)
|
||||||
LOG_DATE_FORMAT = '%I:%M:%S'
|
LOG_FORMAT = (
|
||||||
|
"[%(asctime)s] [%(name)s] [%(funcName)s:%(lineno)d] %(levelname)s: %(message)s"
|
||||||
|
)
|
||||||
|
LOG_DATE_FORMAT = "%I:%M:%S"
|
||||||
LOG_LEVEL = logging.INFO
|
LOG_LEVEL = logging.INFO
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"KeyID": "key"
|
"the key id goes here": "the key goes here"
|
||||||
}
|
}
|
||||||
|
@ -15,4 +15,5 @@ lxml
|
|||||||
six
|
six
|
||||||
pathvalidate
|
pathvalidate
|
||||||
coloredlogs
|
coloredlogs
|
||||||
browser_cookie3
|
browser_cookie3
|
||||||
|
demoji
|
Loading…
x
Reference in New Issue
Block a user