12 Commits

Author SHA1 Message Date
652d0588fc update dependencies and version 2026-01-11 21:26:52 +01:00
a2a7132d0b format 2026-01-11 21:25:53 +01:00
0696165932 fix vidoza 2026-01-11 21:20:18 +01:00
8cb9a83b2c fix doodstream 2026-01-11 21:17:42 +01:00
f200312ad5 fix background listeners not working 2026-01-11 21:17:30 +01:00
1cf4940453 minor refactor 2026-01-11 21:17:10 +01:00
67dbb9c685 fix vidmoly 2026-01-08 00:50:00 +01:00
f9a0197f7f update readme 2025-11-08 23:24:25 +01:00
d8bb70890a update build instructions 2025-11-08 22:26:18 +01:00
45900b2e86 do not upload sources to releases 2025-11-08 22:21:10 +01:00
3058847f31 upload artifacts when publishing 2025-11-08 22:20:35 +01:00
082f30722c do not lint on tag push 2025-11-08 21:52:46 +01:00
11 changed files with 819 additions and 673 deletions

View File

@@ -1,8 +1,12 @@
name: lint name: lint
on: on:
push: push:
pull_request: branches:
- '**'
tags-ignore:
- '*'
pull_request:
jobs: jobs:
lint: lint:

View File

@@ -35,12 +35,36 @@ jobs:
npm run zip:firefox npm run zip:firefox
npm run zip npm run zip
- name: Resolve zip extension paths
id: paths
run: |
MV2_PATH=$(find .output -type f -name "*-mv2.zip")
MV2_NAME=$(basename $MV2_PATH)
MV3_PATH=$(find .output -type f -name "*-mv3.zip")
MV3_NAME=$(basename $MV3_PATH)
echo "mv2_path=$MV2_PATH" >> "$GITHUB_OUTPUT"
echo "mv2_name=$MV2_NAME" >> "$GITHUB_OUTPUT"
echo "mv3_path=$MV3_PATH" >> "$GITHUB_OUTPUT"
echo "mv3_name=$MV3_NAME" >> "$GITHUB_OUTPUT"
- name: Upload mv2 as artifact
uses: actions/upload-artifact@v5
with:
name: ${{ steps.paths.outputs.mv2_name }}
path: ${{ steps.paths.outputs.mv2_path }}
- name: Upload mv3 as artifact
uses: actions/upload-artifact@v5
with:
name: ${{ steps.paths.outputs.mv3_name }}
path: ${{ steps.paths.outputs.mv3_path }}
- name: Upload to latest release - name: Upload to latest release
if: github.event.inputs.dry_run != 'true' if: github.event.inputs.dry_run != 'true'
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: .output/*.zip file: .output/*mv*.zip
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true
file_glob: true file_glob: true

View File

@@ -4,7 +4,7 @@ A multi-browser addon / extension for multiple streaming providers which redirec
<p align="center"> <p align="center">
<a href="https://github.com/bytedream/stream-bypass/releases/latest"> <a href="https://github.com/bytedream/stream-bypass/releases/latest">
<img src="https://img.shields.io/github/v/release/ByteDream/stream-bypass?label=Version&style=flat-square" alt="Version"> <img src="https://img.shields.io/github/v/release/bytedream/stream-bypass?label=Version&style=flat-square" alt="Version">
</a> </a>
<a href="https://addons.mozilla.org/de/firefox/addon/stream-bypass/"> <a href="https://addons.mozilla.org/de/firefox/addon/stream-bypass/">
<img src="https://img.shields.io/amo/users/stream-bypass?label=Firefox%20Users&style=flat-square" alt="Firefox Addon Store"> <img src="https://img.shields.io/amo/users/stream-bypass?label=Firefox%20Users&style=flat-square" alt="Firefox Addon Store">
@@ -13,7 +13,7 @@ A multi-browser addon / extension for multiple streaming providers which redirec
<img src="https://img.shields.io/chrome-web-store/users/ddfpfjomnakfckhmilacnbokdaknamdb?style=flat-square&label=Chrome%20Users" alt="Chrome Store"> <img src="https://img.shields.io/chrome-web-store/users/ddfpfjomnakfckhmilacnbokdaknamdb?style=flat-square&label=Chrome%20Users" alt="Chrome Store">
</a> </a>
<a href="https://github.com/bytedream/stream-bypass/releases/latest"> <a href="https://github.com/bytedream/stream-bypass/releases/latest">
<img src="https://img.shields.io/github/downloads/ByteDream/stream-bypass/total?label=GitHub%20Downloads&style=flat-square" alt="GitHub Downloads"> <img src="https://img.shields.io/github/downloads/bytedream/stream-bypass/total?label=GitHub%20Downloads&style=flat-square" alt="GitHub Downloads">
</a> </a>
</p> </p>
@@ -54,13 +54,18 @@ The best way to install the extension are the official browser extension stores:
- [Chrome Web Store](https://chromewebstore.google.com/detail/ddfpfjomnakfckhmilacnbokdaknamdb) - [Chrome Web Store](https://chromewebstore.google.com/detail/ddfpfjomnakfckhmilacnbokdaknamdb)
<details> <details>
<summary><h3>Manual installation</h3></summary> <summary><h3 id="manual-installation1">Manual installation</h3></summary>
- Firefox (mv2) - Firefox (mv2)
- Download `stream-bypass-<version>-mv2.zip` from the [latest release](https://github.com/ByteDream/stream-bypass/releases/latest) and unzip it (with [7zip](https://www.7-zip.org/) or something like that) - Download `stream-bypass-<version>-mv2.zip` from the [latest release](https://github.com/bytedream/stream-bypass/releases/latest) and unzip it (e.g. with [7zip](https://www.7-zip.org/))
- Go into your browser and type `about:debugging#/runtime/this-firefox` in the address bar - Go into your browser and type `about:debugging#/runtime/this-firefox` in the address bar
- Click the `Load Temporary Add-on...` button and choose the `manifest.json` file in the unzipped directory - Click the `Load Temporary Add-on...` button and choose the `manifest.json` file in the unzipped directory
- Chromium / Google Chrome (mv3) > As nearly every browser other than Firefox is based on Chromium, this should be the same for most of them - Download `stream-bypass-<version>-mv3.zip` from the [latest release](https://github.com/ByteDream/stream-bypass/releases/latest) and unzip it (with [7zip](https://www.7-zip.org/) or something like that) - Go into your browser and type `chrome://extensions` in the address bar - Turn on the developer mode by checking the switch in the top right corner - Click `Load unpacked` and choose the unzipped directory - Chromium / Google Chrome (mv3)
> As nearly every browser other than Firefox is based on Chromium, this should be the same for most of them
- Download `stream-bypass-<version>-mv3.zip` from the [latest release](https://github.com/bytedream/stream-bypass/releases/latest) and unzip it (e.g. [7zip](https://www.7-zip.org/))
- Go into your browser and type `chrome://extensions` in the address bar
- Turn on the developer mode by checking the switch in the top right corner
- Click `Load unpacked` and choose the unzipped directory
</details> </details>
@@ -71,9 +76,9 @@ The best way to install the extension are the official browser extension stores:
| Feature | Firefox (mv2) | Chrome (mv3) | Firefox for Android (mv2) | | Feature | Firefox (mv2) | Chrome (mv3) | Firefox for Android (mv2) |
| --------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------------ | ------------------------- | | --------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------------ | ------------------------- |
| Replace site-speicifc video player with browser native video player | ✔ | ✔ | ✔ | | Replace site-speicifc video player with browser native video player | ✔ | ✔ | ✔ |
| Support websites that are accessed via a redirect | ✔ | ✖ | ✔ | | Support websites that are accessed via a redirect | ✔ | ✖ | ✔ |
| Open video in mpv (with [ff2mpv](https://github.com/ByteDream/stream-bypass/tree/master#ff2mpv-use-mpv-to-directly-play-streams)) | ✔ | ✔ | ✖ | | Open video in mpv (with [ff2mpv](https://github.com/bytedream/stream-bypass/tree/master#ff2mpv-use-mpv-to-directly-play-streams)) | ✔ | ✔ | ✖ |
## 📜 Supported websites ## 📜 Supported websites
@@ -81,8 +86,8 @@ The best way to install the extension are the official browser extension stores:
- ⚠: Works with limitations. - ⚠: Works with limitations.
- ✖: Not supported. - ✖: Not supported.
| Site | Firefox & Firefox for Android (mv2) | Chrome & Chromium based (mv2) | | Site | Firefox & Firefox for Android (mv2) | Chrome & Chromium based (mv2) |
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| [dropload.io](https://dropload.io) | ✔ | ✔ | | [dropload.io](https://dropload.io) | ✔ | ✔ |
| [doodstream.com](doodstream.com) / [dood.pm](https://dood.pm) | ✔ | ⚠ (redirect probably required) | | [doodstream.com](doodstream.com) / [dood.pm](https://dood.pm) | ✔ | ⚠ (redirect probably required) |
| [filemoon.to](https://filemoon.to) | ✔ | ✔ | | [filemoon.to](https://filemoon.to) | ✔ | ✔ |
@@ -90,7 +95,7 @@ The best way to install the extension are the official browser extension stores:
| [kwik.cx](https://kwik.cx) | ✔ | ✔ | | [kwik.cx](https://kwik.cx) | ✔ | ✔ |
| [loadx.ws](https://loadx.ws) | ✔ | ✖ (background request always required) | | [loadx.ws](https://loadx.ws) | ✔ | ✖ (background request always required) |
| [luluvdo.com](https://luluvdo.com) | ✔ | ✖ (background request always required) | | [luluvdo.com](https://luluvdo.com) | ✔ | ✖ (background request always required) |
| [mixdrop.co](https://mixdrop.co) | ✔ | ✔ | | [mixdrop.co](https://mixdrop.co) | ✔ | ✔ |
| [mp4upload.com](https://mp4upload.com) | ✔ | ✔ | | [mp4upload.com](https://mp4upload.com) | ✔ | ✔ |
| [newgrounds.com](https://newgrounds.com) | ✔ | ✔ | | [newgrounds.com](https://newgrounds.com) | ✔ | ✔ |
| [streama2z.com](https://streama2z.com) | ✔ | ✖ (redirect always required) | | [streama2z.com](https://streama2z.com) | ✔ | ✖ (redirect always required) |
@@ -120,18 +125,20 @@ If the requirements are satisfied, you can continue with the following commands:
```shell ```shell
# install all dependencies # install all dependencies
$ npm install $ npm i
# build the extension source to the dist/ directory # build the extension and start it in a new firefox instance
$ npm run build $ npm run dev:firefox
# same as build + more optimizations and browser specific settings at release/ # build the extension with optimizations to the .output/firefox-mv2 directory
$ npm run release:firefox # or "release:chrome" to create a release for chromium based browsers $ npm run build:firefox
``` ```
You can omit the `:firefox` suffix, then it's built for Chrome.
##### Install ##### Install
If you want to use the addon in Chromium or any browser which is based on it, follow the steps in [installation](#-installation). If you want to use the addon in Chromium or any browser which is based on it, follow the steps in the [manual installation](#-installation).
When using firefox, use the following: When using firefox, use the following:
1. Type `about:debugging` in the browser's address bar. 1. Type `about:debugging` in the browser's address bar.

1301
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "stream-bypass", "name": "stream-bypass",
"version": "4.0.0", "version": "4.0.1",
"displayName": "Stream Bypass", "displayName": "Stream Bypass",
"author": "bytedream", "author": "bytedream",
"description": "Multi-browser addon for multiple streaming providers which redirects directly to the source video", "description": "Multi-browser addon for multiple streaming providers which redirects directly to the source video",
@@ -26,29 +26,29 @@
"lint": "prettier --check . && eslint ." "lint": "prettier --check . && eslint ."
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^1.4.1", "@eslint/compat": "^2.0.1",
"@ianvs/prettier-plugin-sort-imports": "^4.7.0", "@ianvs/prettier-plugin-sort-imports": "^4.7.0",
"@steeze-ui/heroicons": "^2.4.2", "@steeze-ui/heroicons": "^2.4.2",
"@steeze-ui/svelte-icon": "^1.6.2", "@steeze-ui/svelte-icon": "^1.6.2",
"@sveltejs/vite-plugin-svelte": "^6.2.1", "@sveltejs/vite-plugin-svelte": "^6.2.4",
"@tailwindcss/vite": "^4.1.16", "@tailwindcss/vite": "^4.1.18",
"@tsconfig/svelte": "^5.0.5", "@tsconfig/svelte": "^5.0.6",
"@wxt-dev/module-svelte": "^2.0.4", "@wxt-dev/module-svelte": "^2.0.4",
"eslint": "^9.38.0", "eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-svelte": "^3.12.5", "eslint-plugin-svelte": "^3.14.0",
"hls.js": "^1.6.13", "hls.js": "^1.6.15",
"prettier": "^3.6.2", "prettier": "^3.7.4",
"prettier-plugin-svelte": "^3.4.0", "prettier-plugin-svelte": "^3.4.1",
"sass": "^1.93.2", "sass": "^1.97.2",
"svelte": "^5.43.2", "svelte": "^5.46.1",
"svelte-check": "^4.3.3", "svelte-check": "^4.3.5",
"tailwindcss": "^4.1.16", "tailwindcss": "^4.1.18",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.46.2", "typescript-eslint": "^8.52.0",
"vite": "^7.1.12", "vite": "^7.3.1",
"web-ext": "^9.1.0", "web-ext": "^9.2.0",
"wxt": "^0.20.11" "wxt": "^0.20.13"
} }
} }

View File

@@ -1,30 +1,41 @@
import { UrlReferer } from '@/lib/settings'; import { getHost } from '@/lib/host';
import { HostSettings, UrlReferer } from '@/lib/settings';
export default defineBackground(() => { export default defineBackground(() => {
browser.runtime.onMessage.addListener(async (message) => { browser.runtime.onMessage.addListener(async (message) => {
if (message.action == 'ff2mpv') { if (message.action == 'ff2mpv') {
await browser.runtime.sendNativeMessage('ff2mpv', { url: message.url }); await browser.runtime.sendNativeMessage('ff2mpv', { url: message.url });
} }
// the following listener is only available in mv2
if (import.meta.env.MANIFEST_VERSION === 3) return;
browser.webRequest.onBeforeSendHeaders.addListener(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
async (details) => {
const referer = await UrlReferer.get(new URL(details.url).hostname);
if (!referer) return;
details.requestHeaders!.push({
name: 'Referer',
value: `https://${referer}/`
});
return { requestHeaders: details.requestHeaders };
},
{ urls: ['<all_urls>'], types: ['xmlhttprequest'] },
['blocking', 'requestHeaders']
);
}); });
// the following listener is only available in mv2
if (import.meta.env.MANIFEST_VERSION === 3) return;
browser.webRequest.onBeforeSendHeaders.addListener(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
async (details) => {
const referer = await UrlReferer.get(new URL(details.url).hostname);
if (!referer) return;
details.requestHeaders!.push({
name: 'Referer',
value: `https://${referer}/`
});
return { requestHeaders: details.requestHeaders };
},
{ urls: ['<all_urls>'], types: ['xmlhttprequest'] },
['blocking', 'requestHeaders']
);
browser.webRequest.onBeforeRedirect.addListener(
async (details) => {
const host = await getHost(new URL(details.url).hostname);
if (!host) return;
await HostSettings.addTemporaryHostDomain(host, new URL(details.redirectUrl).hostname);
},
{ urls: ['<all_urls>'], types: ['main_frame', 'sub_frame'] }
);
}); });

View File

@@ -1,4 +1,4 @@
import { getHost, hosts, type Host, type HostMatch } from '@/lib/host'; import { getHost, HostMatchType, hosts, type HostMatch } from '@/lib/host';
import { FF2MPVSettings } from '@/lib/settings'; import { FF2MPVSettings } from '@/lib/settings';
export default defineContentScript({ export default defineContentScript({
@@ -13,10 +13,8 @@ export default defineContentScript({
}); });
async function main() { async function main() {
let host: Host | null; const host = await getHost(window.location.host);
if ((host = await getHost(window.location.host)) === null) { if (!host) return;
return;
}
let re = null; let re = null;
for (const regex of host.regex) { for (const regex of host.regex) {
@@ -24,7 +22,7 @@ async function main() {
break; break;
} }
} }
if (re === null) { if (!re) {
return; return;
} }
@@ -42,7 +40,7 @@ async function main() {
await browser.runtime.sendMessage({ action: 'ff2mpv', url: hostMatch.url }); await browser.runtime.sendMessage({ action: 'ff2mpv', url: hostMatch.url });
} }
if (host.replace && hostMatch.type != 'hls') { if (host.replace && hostMatch.type != HostMatchType.HLS) {
// this destroys all intervals that may spawn popups or events // this destroys all intervals that may spawn popups or events
let intervalId = window.setInterval(() => {}, 0); let intervalId = window.setInterval(() => {}, 0);
while (intervalId--) { while (intervalId--) {

View File

@@ -4,6 +4,7 @@ export default {
name: 'Doodstream', name: 'Doodstream',
id: 'doodstream', id: 'doodstream',
domains: [ domains: [
'do7go.com',
'doodstream.com', 'doodstream.com',
'dood.pm', 'dood.pm',
'dood.ws', 'dood.ws',
@@ -34,7 +35,7 @@ export default {
referrer: `https://${window.location.host}/e/${window.location.pathname.split('/').slice(-1)[0]}` referrer: `https://${window.location.host}/e/${window.location.pathname.split('/').slice(-1)[0]}`
}); });
return { return {
type: HostMatchType.HLS, type: HostMatchType.NATIVE,
url: `${await response.text()}1234567890${match[2]}${Date.now()}` url: `${await response.text()}1234567890${match[2]}${Date.now()}`
}; };
} }

View File

@@ -63,7 +63,7 @@ export const hosts = [
Vupload Vupload
]; ];
export async function getHost(domain: string) { export async function getHost(domain: string): Promise<Host | null> {
if (await HostSettings.getAllHostsDisabled()) return null; if (await HostSettings.getAllHostsDisabled()) return null;
const disabledIds = await HostSettings.getDisabledHosts(); const disabledIds = await HostSettings.getDisabledHosts();

View File

@@ -3,7 +3,11 @@ import { HostMatchType, type Host } from '@/lib/host';
export default { export default {
name: 'Vidmoly', name: 'Vidmoly',
id: 'vidmoly', id: 'vidmoly',
domains: ['vidmoly.me', 'vidmoly.net', 'vidmoly.to'], // vidmoly has multiple domains, but regardless of the domain, the actual videos are loaded via an iframe which
// always points to vidmoly.net. the "outer" vidmoly site also has a link to some video, which, would
// be preferred to use, as the whole site could be replaced by the native video player instead of just the iframe,
// but said link doesn't always point the same video as the iframe
domains: ['vidmoly.net'],
regex: [/(?<=file:").+\.m3u8.*(?=")/gm], regex: [/(?<=file:").+\.m3u8.*(?=")/gm],
match: async function (match: RegExpMatchArray) { match: async function (match: RegExpMatchArray) {

View File

@@ -9,7 +9,7 @@ export default {
match: async function (match: RegExpMatchArray) { match: async function (match: RegExpMatchArray) {
return { return {
type: HostMatchType.HLS, type: HostMatchType.NATIVE,
url: match[0] url: match[0]
}; };
} }