{"id":13554937,"url":"https://github.com/snobu/destreamer","last_synced_at":"2025-05-15T02:06:36.553Z","repository":{"id":37176751,"uuid":"175191426","full_name":"snobu/destreamer","owner":"snobu","description":"Save Microsoft Stream videos for offline enjoyment.","archived":false,"fork":false,"pushed_at":"2024-06-11T11:36:39.000Z","size":1383,"stargazers_count":2382,"open_issues_count":105,"forks_count":432,"subscribers_count":47,"default_branch":"master","last_synced_at":"2025-04-11T14:17:03.936Z","etag":null,"topics":["download","microsoft-stream","offline"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snobu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-12T10:52:44.000Z","updated_at":"2025-04-09T04:37:59.000Z","dependencies_parsed_at":"2022-07-12T16:14:08.882Z","dependency_job_id":"b29c51f3-5463-462c-9551-cdf5a41cf7b3","html_url":"https://github.com/snobu/destreamer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snobu%2Fdestreamer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snobu%2Fdestreamer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snobu%2Fdestreamer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snobu%2Fdestreamer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snobu","download_url":"https://codeload.github.com/snobu/destreamer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254259370,"owners_count":22040819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["download","microsoft-stream","offline"],"created_at":"2024-08-01T12:02:57.977Z","updated_at":"2025-05-15T02:06:36.520Z","avatar_url":"https://github.com/snobu.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# This project is abandoned. It will probably not work anymore against your MS Stream tenant.\n\n# A heartfelt thank you to all the contributors over the years. You are the real MVPs. 💖\n\n## Check out kylon's Sharedown for a SharePoint-backend implementation - https://github.com/kylon/Sharedown\n\n\u003chr\u003e\n\n![destreamer](assets/logo.png)\n\n_(Alternative artwork proposals are welcome! Submit one through an Issue.)_\n\n# Saves Microsoft Stream videos for offline enjoyment\n\n### v2 Release, codename _Hammer of Dawn\u003csup\u003eTM\u003c/sup\u003e_\n\nThis release would not have been possible without the code and time contributed by two distinguished developers: [@lukaarma](https://github.com/lukaarma) and [@kylon](https://github.com/kylon). Thank you!\n\n### Specialized versions\n\n- [Politecnico di Milano][polimi]: fork over at https://github.com/SamanFekri/destreamer\n- [Università di Pisa][unipi]: fork over at https://github.com/Guray00/destreamer-unipi\n- [Università della Calabria][unical]: fork over at https://github.com/peppelongo96/UnicalDown\n- [Università degli Studi di Parma][unipr]: fork over at https://github.com/vRuslan/destreamer-unipr\n\n## What's new\n### v2.2\n\n- Added title template\n\n### v2.1\n\n- Major code refactoring (all credits to @lukaarma)\n- Destreamer is now able to refresh the session's access token. Use this with `-k` (keep cookies) and tick \"Remember Me\" on login.\n- We added support for closed captions (see `--closedCaptions` below)\n\n## Disclaimer\n\nHopefully this doesn't break the end user agreement for Microsoft Stream. Since we're simply saving the HLS stream to disk as if we were a browser, this does not abuse the streaming endpoints. However i take no responsibility if either Microsoft or your Office 365 admins request a chat with you in a small white room.\n\n## Prereqs\n\n- [**Node.js**][node]: You'll need Node.js version 8.0 or higher. A GitHub Action runs tests on all major Node versions on every commit. One caveat for Node 8, if you get a `Parse Error` with `code: HPE_HEADER_OVERFLOW` you're out of luck and you'll need to upgrade to Node 10+. PLEASE NOTE WE NO LONGER TEST BUILDS AGAINST NODE 8.x. YOU ARE ON YOUR OWN.\n- **npm**: usually comes with Node.js, type `npm` in your terminal to check for its presence\n- [**ffmpeg**][ffmpeg]: a recent version (year 2019 or above), in `$PATH` or in the same directory as this README file (project root).\n- [**git**][git]: one or more npm dependencies require git.\n\nDestreamer takes a [honeybadger](https://www.youtube.com/watch?v=4r7wHMg5Yjg) approach towards the OS it's running on. We've successfully tested it on Windows, macOS and Linux.\n\n## Limits and limitations\n\nMake sure you use the right script (`.sh`, `.ps1` or `.cmd`) and escape char (if using line breaks) for your shell.\nPowerShell uses a backtick [ **`** ] and cmd.exe uses a caret [ **^** ].\n\nNote that destreamer won't run in an elevated (Administrator/root) shell. Running inside **Cygwin/MinGW/MSYS** may also fail, please use **cmd.exe** or **PowerShell** if you're on Windows.\n\n**WSL** (Windows Subsystem for Linux) is not supported as it can't easily pop up a browser window. It *may* work by installing an X Window server (like [Xming][xming]) and exporting the default display to it (`export DISPLAY=:0`) before running destreamer. See [this issue for more on WSL v1 and v2][wsl].\n\n## Can i plug in my own browser?\n\nYes, yes you can. This may be useful if your main browser has some authentication plugins that are required for you to logon to your Microsoft Stream tenant.\nTo use your own browser for the authentication part, locate the following snippet in `src/destreamer.ts` and `src/TokenCache.ts`:\n\n```typescript\nconst browser: puppeteer.Browser = await puppeteer.launch({\n  executablePath: getPuppeteerChromiumPath(),\n  // …\n});\n```\n\nNavigate to `chrome://version` in the browser you want to plug in and copy executable path from there. Use double backslash for Windows.\n\nNow, change `executablePath` to reflect the path to your browser and profile (i.e. to use Microsoft Edge on Windows):\n```typescript\n        executablePath: 'C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe',\n```\n\nYou can add `userDataDir` right after `executablePath` with the path to your browser profile (also shown in `chrome://version`) if you want that loaded as well.\n\nRemember to rebuild (`npm run build`) every time you change this configuration.\n\n## How to build\n\nTo build destreamer clone this repository, install dependencies and run the build script -\n\n```sh\n$ git clone https://github.com/snobu/destreamer\n$ cd destreamer\n$ npm install\n$ npm run build\n```\n\n## Usage\n\n```\n$ ./destreamer.sh\n\nOptions:\n  --help                  Show help                                                                            [boolean]\n  --version               Show version number                                                                  [boolean]\n  --username, -u          The username used to log into Microsoft Stream (enabling this will fill in the email field for\n                          you).                                                                                 [string]\n  --videoUrls, -i         List of urls to videos or Microsoft Stream groups.                                     [array]\n  --inputFile, -f         Path to text file containing URLs and optionally outDirs. See the README for more on outDirs.\n                                                                                                                [string]\n  --outputDirectory, -o   The directory where destreamer will save your downloads.          [string] [default: \"videos\"]\n  --outputTemplate, -t    The template for the title. See the README for more info.\n                                                                [string] [default: \"{title} - {publishDate} {uniqueId}\"]\n  --keepLoginCookies, -k  Let Chromium cache identity provider cookies so you can use \"Remember me\" during login.\n                          Must be used every subsequent time you launch Destreamer if you want to log in automatically.\n                                                                                              [boolean] [default: false]\n  --noExperiments, -x     Do not attempt to render video thumbnails in the console.           [boolean] [default: false]\n  --simulate, -s          Disable video download and print metadata information to the console.\n                                                                                              [boolean] [default: false]\n  --verbose, -v           Print additional information to the console (use this before opening an issue on GitHub).\n                                                                                              [boolean] [default: false]\n  --closedCaptions, --cc  Check if closed captions are available and let the user choose which one to download (will not\n                          ask if only one available).                                         [boolean] [default: false]\n  --noCleanup, --nc       Do not delete the downloaded video file when an FFmpeg error occurs.[boolean] [default: false]\n  --vcodec                Re-encode video track. Specify FFmpeg codec (e.g. libx265) or set to \"none\" to disable video.\n                                                                                              [string] [default: \"copy\"]\n  --acodec                Re-encode audio track. Specify FFmpeg codec (e.g. libopus) or set to \"none\" to disable audio.\n                                                                                              [string] [default: \"copy\"]\n  --format                Output container format (mkv, mp4, mov, anything that FFmpeg supports).\n                                                                                               [string] [default: \"mkv\"]\n  --skip                  Skip download if file already exists.                               [boolean] [default: false]\n```\n\n- both --videoUrls and --inputFile also accept Microsoft Teams Groups url so if your Organization placed the videos you are interested in a group you can copy the link and Destreamer will download all the videos it can inside it! A group url looks like this https://web.microsoftstream.com/group/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n\n- Passing `--username` is optional. It's there to make logging in faster (the username field will be populated automatically on the login form).\n\n- You can use an absolute path for `-o` (output directory), for example `/mnt/videos`.\n\n- We default to `.mkv` for the output container. If you prefer something else (like `mp4`), pass `--format mp4`.\n\nDownload a video -\n```sh\n$ ./destreamer.sh -i \"https://web.microsoftstream.com/video/VIDEO-1\"\n```\n\nDownload a video and re-encode with HEVC (libx265) -\n```sh\n$ ./destreamer.sh -i \"https://web.microsoftstream.com/video/VIDEO-1\" --vcodec libx265\n```\n\nDownload a video and speed up the interactive login by automagically filling in the username -\n```sh\n$ ./destreamer.sh -u user@example.com -i \"https://web.microsoftstream.com/video/VIDEO-1\"\n```\n\nDownload a video to a custom path -\n```sh\n$ ./destreamer.sh -i \"https://web.microsoftstream.com/video/VIDEO-1\" -o /Users/hacker/Downloads\n```\n\nDownload two or more videos -\n```sh\n$ ./destreamer.sh -i \"https://web.microsoftstream.com/video/VIDEO-1\" \\\n                     \"https://web.microsoftstream.com/video/VIDEO-2\"\n```\n\nDownload many videos but read URLs from a file -\n```sh\n$ ./destreamer.sh -f list.txt\n```\n### Input file\nYou can create a `.txt` file containing your video URLs, one video per line. The text file can have any name, followed by the `.txt` extension.\nAdditionally you can have destreamer download each video in the input list to a separate directory.\nThese optional lines must start with white space(s).\n\nUsage -\n```\nhttps://web.microsoftstream.com/video/xxxxxxxx-aaaa-xxxx-xxxx-xxxxxxxxxxxx\n -dir=\"videos/lessons/week1\"\nhttps://web.microsoftstream.com/video/xxxxxxxx-aaaa-xxxx-xxxx-xxxxxxxxxxxx\n -dir=\"videos/lessons/week2\"\n```\n\n### Title template\nThe `-t` option allows user to specify a custom filename for the videos.\n\nYou can use one or more of the following magic sequence which will get substituted at runtime. The magic sequence must be surrounded by curly brackets like this: `{title} {publishDate}`\n\n- `title`: Video title\n- `duration`: Video duration in HH:MM:SS format\n- `publishDate`: The date when the video was published in YYYY-MM-DD format\n- `publishTime`: The time the video was published in HH:MM:SS format\n- `author`: Name of video publisher\n- `authorEmail`: E-mail of video publisher\n- `uniqueId`: An _unique-enough_ ID generated from the video metadata\n\nExamples -\n```\nInput:\n    -t 'This is an example'\n\nExpected filename:\n    This is an example.mkv\n\nInput:\n    -t 'This is an example by {author}'\n\nExpected filename:\n    This is an example by lukaarma.mkv\n\nInput:\n    -t '{title} - {duration} - {publishDate} - {publishTime} - {author} - {authorEmail} - {uniqueId}'\n\nExpected filename:\n    This is an example - 0:16:18 - 2020-07-30 - 10:30:13 - lukaarma - example@domain.org - #3c6ca929.mkv\n```\n\n## Expected output\n\nWindows Terminal -\n\n![screenshot](assets/screenshot-win.png)\n\niTerm2 on a Mac -\n\n![screenshot](assets/screenshot-mac.png)\n\nBy default, downloads are saved under project root `Destreamer/videos/` ( Not the system media Videos folder ), unless specified by `-o` (output directory).\n\n## KNOWN BUGS\n\nIf you get a\n```\n[FATAL ERROR] Unknown error: exit code 4\n````\nwhen running destreamer, then make sure you're running a recent (post year 2019), stable version of **ffmpeg**.\n\n## Contributing\n\nContributions are welcome. Open an issue first before sending in a pull request. All pull requests require at least one code review before they are merged to master.\n\n## Found a bug?\n\nPlease open an [issue](https://github.com/snobu/destreamer/issues) and we'll look into it.\n\n\n[ffmpeg]: https://www.ffmpeg.org/download.html\n[xming]: https://sourceforge.net/projects/xming/\n[node]: https://nodejs.org/en/download/\n[git]: https://git-scm.com/downloads\n[wsl]: https://github.com/snobu/destreamer/issues/90#issuecomment-619377950\n[polimi]: https://www.polimi.it\n[unipi]: https://www.unipi.it/\n[unical]: https://www.unical.it/portale/\n[unipr]: https://www.unipr.it/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnobu%2Fdestreamer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnobu%2Fdestreamer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnobu%2Fdestreamer/lists"}