├── src ├── js │ ├── popup.js │ ├── background.js │ └── in-content.js ├── views │ └── popup.html ├── images │ ├── logo.png │ └── heart.svg ├── css │ ├── style.css │ └── popup.css └── popup.html ├── .eslintrc.json ├── .prettierrc ├── .gitignore ├── .github └── workflows │ └── node.js.yml ├── webpack.config.js ├── manifest.json ├── package.json └── README.md /src/js/popup.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/popup.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahgurung/coursera-HD-video-downloader/HEAD/src/images/logo.png -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb-base", 3 | "env": { 4 | "browser": true, 5 | "webextensions": true 6 | }, 7 | "parser": "babel-eslint" 8 | } -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 4, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "none", 8 | "bracketSpacing": true, 9 | "jsxBracketSameLine": false, 10 | "arrowParens": "avoid" 11 | } 12 | -------------------------------------------------------------------------------- /src/js/background.js: -------------------------------------------------------------------------------- 1 | chrome.webNavigation.onCompleted.addListener( 2 | (navigationEvent) => { 3 | const { tabId } = navigationEvent; 4 | chrome.tabs.executeScript(tabId, { file: 'in-content.js' }); 5 | }, { 6 | url: [{ 7 | hostSuffix: 'coursera.org', 8 | }, 9 | { 10 | hostSuffix: 'coursera.com', 11 | }], 12 | }, 13 | ); 14 | 15 | chrome.runtime.setUninstallURL('https://forms.gle/i5kpP8FALCLBUQqH9'); 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## IDEs ### 2 | *.sublime-workspace 3 | .tag* 4 | .tern-project 5 | 6 | ### OSX ### 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear on external disk 16 | .Spotlight-V100 17 | .Trashes 18 | 19 | ### Windows ### 20 | # Windows image file caches 21 | Thumbs.db 22 | ehthumbs.db 23 | 24 | # Folder config file 25 | Desktop.ini 26 | 27 | # Recycle Bin used on file shares 28 | $RECYCLE.BIN/ 29 | 30 | dist/ 31 | node_modules/ 32 | .tmp 33 | GumGumScreenshots_*.crx 34 | updates.xml 35 | -------------------------------------------------------------------------------- /src/css/style.css: -------------------------------------------------------------------------------- 1 | .container-courseraDownloader { 2 | display: grid; 3 | align-items: center; 4 | } 5 | 6 | .courseraDownloaderButton { 7 | padding: 5px 12px 5px 12px !important; 8 | min-height: 31.99px !important; 9 | font-size: 14px !important; 10 | margin-left: 6px !important; 11 | font-weight: 400 !important; 12 | color:#5e5e5e !important; 13 | border: 1px solid #ddd !important; 14 | border-radius: 2px !important; 15 | cursor: pointer !important; 16 | text-decoration: none !important; 17 | } 18 | 19 | .courseraDownloaderButton:hover{ 20 | background-color: #2d62d7 !important; 21 | color: white !important; 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Coursera HD Video Downloader 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [12.x, 14.x] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v1 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | 28 | - run: npm i 29 | - run: npm run build 30 | - run: npm run lint 31 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: { 6 | popup: './src/js/popup.js', 7 | background: './src/js/background.js', 8 | 'in-content': './src/js/in-content.js', 9 | }, 10 | output: { 11 | path: path.resolve(__dirname, 'dist'), 12 | filename: '[name].js', 13 | }, 14 | cache: true, 15 | devtool: 'eval-cheap-module-source-map', 16 | module: { 17 | loaders: [ 18 | { 19 | test: /\.js?$/, 20 | include: [path.resolve(__dirname, 'src')], 21 | loader: 'babel-loader', 22 | }, 23 | ], 24 | }, 25 | plugins: [ 26 | new CopyWebpackPlugin([ 27 | { from: './manifest.json' }, 28 | { from: './src/images' }, 29 | { from: './src/css' }, 30 | { from: './src/popup.html' }, 31 | ]), 32 | ], 33 | }; 34 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Coursera HD Video Downloader", 4 | "version": "2.1.3", 5 | "description": "Download coursera videos in HD", 6 | "icons": { 7 | "16": "logo.png", 8 | "48": "logo.png", 9 | "128": "logo.png" 10 | }, 11 | "browser_action": { 12 | "default_title": "Coursera Videos Downloader", 13 | "default_popup": "popup.html" 14 | }, 15 | "content_scripts": [ 16 | { 17 | "matches": ["https://www.coursera.org/*"], 18 | "js": ["in-content.js"], 19 | "css": ["style.css"], 20 | "run_at": "document_end" 21 | } 22 | ], 23 | "background": { 24 | "scripts": ["background.js"], 25 | "persistent": false 26 | }, 27 | "permissions": ["https://www.coursera.org/*", "webNavigation", "activeTab"], 28 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'" 29 | } 30 | -------------------------------------------------------------------------------- /src/css/popup.css: -------------------------------------------------------------------------------- 1 | .popup { 2 | border-radius: 10px; 3 | padding: 20px; 4 | width: 300px; 5 | height: auto; 6 | text-align: center; 7 | } 8 | 9 | .foot_icon { 10 | height: 20px; 11 | object-fit: contain; 12 | } 13 | 14 | .footer { 15 | padding: 0 20px; 16 | justify-content: center; 17 | grid-gap: 5px; 18 | display: flex; 19 | text-align: center; 20 | align-items: center; 21 | cursor: pointer; 22 | } 23 | 24 | a { 25 | text-decoration: none; 26 | color: #000; 27 | } 28 | 29 | .title-chvd { 30 | font-size: 20px; 31 | padding-bottom: 25px; 32 | } 33 | 34 | .link { 35 | color: #005282; 36 | } 37 | 38 | .donation { 39 | padding: 5px; 40 | border: solid 2px #00800047; 41 | font-size: 15px; 42 | text-align: left; 43 | margin-top: 5px; 44 | background: #d8ffd8; 45 | } 46 | 47 | .supporters { 48 | padding: 5px; 49 | margin-top: 5px; 50 | font-size: 15px; 51 | background: #ffffb0; 52 | } 53 | 54 | .thanks { 55 | background: aliceblue; 56 | font-size: 15px; 57 | text-align: left; 58 | padding: 5px; 59 | border-radius: 5px; 60 | } -------------------------------------------------------------------------------- /src/images/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "coursera-hd-video-downloader", 3 | "version": "2.0.2", 4 | "description": "Download Coursera Videos in HD", 5 | "main": "src/index.js", 6 | "repository": "git@github.com:gurrrung/coursera-HD-video-downloader.git", 7 | "license": "MIT", 8 | "devDependencies": { 9 | "babel-cli": "^6.26.0", 10 | "babel-eslint": "^7.2.3", 11 | "babel-loader": "^7.1.1", 12 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 13 | "babel-plugin-transform-react-jsx": "^6.24.1", 14 | "babel-preset-env": "^1.6.1", 15 | "copy-webpack-plugin": "^4.0.1", 16 | "crx-webpack-plugin": "^0.1.5", 17 | "eslint": "^7.3.1", 18 | "eslint-config-airbnb-base": "^14.2.0", 19 | "eslint-plugin-import": "^2.22.0", 20 | "eslint-plugin-react": "^7.1.0", 21 | "rimraf": "^2.6.1", 22 | "web-ext": "^4.3.0", 23 | "webpack": "^3.2.0" 24 | }, 25 | "scripts": { 26 | "start": "web-ext run --target=chromium --source-dir ./dist/", 27 | "start:firefox": "web-ext run --source-dir ./dist/", 28 | "prebuild": "rimraf dist", 29 | "build": "webpack", 30 | "lint": "eslint . --ext .js --ignore-pattern dist/" 31 | }, 32 | "nodemonConfig": { 33 | "ignore": [ 34 | "dist/", 35 | "node_modules" 36 | ], 37 | "execMap": { 38 | "js": "node" 39 | }, 40 | "ext": "js html css", 41 | "verbose": true 42 | }, 43 | "dependencies": { 44 | "nodemon": "^1.14.12" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/js/in-content.js: -------------------------------------------------------------------------------- 1 | function injectButton() { 2 | // Grab section in each page where we will inject our button 3 | let videoToolBarSection = document.getElementsByClassName('rc-VideoToolbar horizontal-box wrap align-items-spacebetween'); 4 | 5 | // In case of new UI 6 | if (videoToolBarSection.length < 1) { 7 | videoToolBarSection = document.getElementsByClassName('rc-VideoToolbar'); 8 | } 9 | 10 | videoToolBarSection = videoToolBarSection[0].firstChild; 11 | 12 | // Extracting the video download link 13 | const targetedVideo = document.getElementsByClassName('vjs-tech'); 14 | const downloadLink = targetedVideo[0].src; 15 | 16 | // Create our download button element 17 | const downloadButton = document.createElement('span'); 18 | downloadButton.classList.add('container-courseraDownloader'); 19 | downloadButton.innerHTML = `Download in HD`; 20 | 21 | // Inject button 22 | videoToolBarSection.appendChild(downloadButton); 23 | } 24 | 25 | function checkIfButtonThere() { 26 | const noOfButtons = document.getElementsByClassName('courseraDownloaderButton'); 27 | if (noOfButtons.length > 1) { 28 | noOfButtons[1].remove(); 29 | } 30 | } 31 | 32 | // Detect until the required content is rendered dynamically 33 | const obs = new MutationObserver(((mutations) => { 34 | mutations.forEach((element) => { 35 | for (let i = 0; i < element.addedNodes.length; i += 1) { 36 | if (element.addedNodes[i].nodeType === 1) { 37 | if (element.addedNodes[0].className === 'rc-VideoHighlightingManager') { 38 | injectButton(); 39 | checkIfButtonThere(); 40 | } 41 | } 42 | } 43 | }); 44 | })); 45 | obs.observe(document.body, { 46 | childList: true, subtree: true, attributes: false, characterData: false, 47 | }); 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚫 Deprecated 2 | 3 | This Chrome extension is **no longer maintained** and has been archived as Coursera rolled out its own download feature. 4 | 5 | **🗓️ Archived:** April 8, 2025 6 | **🧭 Last Known Version:** v2.0.0 7 | 8 | 9 | 10 |

11 | 12 |

Coursera HD Video Downloader

13 |

14 | 15 |

16 |

17 | 18 | 19 |

20 | 21 | ## Introduction 22 | 23 | Right now, an issue with video downloads of Coursera is that it doesn't allows to download videos in HD. This extension resolves that issue by providing the video download in best quality available. 24 | 25 | ## Usage 26 | 1) Install the extension 27 | 2) Click on new `Download in HD` button to open the HD video in browser's local player 28 | 3) Ctrl + S 29 | 4) It's all yours 30 | 31 | ## Installation 32 | 33 | [Chrome Web Store](https://chrome.google.com/webstore/detail/coursera-hd-video-downloa/kpnmpopgchfdpjephjkcgikfjnbpoahf) 34 | 35 | [Firefox Addon](https://addons.mozilla.org/en-US/firefox/addon/coursera-hd-video-downloader/) 36 | 37 | ## Development 38 | 39 | To run a development server that will watch for file changes and rebuild the scripts, run: 40 | 41 | ``` 42 | yarn start 43 | ``` 44 | 45 | To just build the files without the development server: 46 | 47 | ``` 48 | yarn build 49 | ``` 50 | 51 | Both commands will create a `dist/` directory, it will contain the built files that should be loaded into the browser or packed. 52 | --------------------------------------------------------------------------------