mirror of
https://github.com/bytedream/stream-bypass.git
synced 2025-05-11 13:15:13 +02:00
add ff2mpv setting + new hosters (#14)
* add Kwik, use unpacker to improve reliabilty * use packer for filemoon * use packer for upstream * add ff2mpv setting + functionality * Update README.md * get rid of @types/webextension-polyfill * Revert "Update README.md" This reverts commit affb6000968beb798423a5403508215b7f6e4670. * Update README.md * Update info link for ff2mpv * add kwik to hosters in readme * removes console.logs * Delete package-lock.json * add package-lock.json to .gitignore * unpack without using eval * Merge main branch into here * Add Dropload Hoster * Add Supervideo Hoster * Add GoodStream Hoster * Add hosters to readme and delete console.logs * Delete package-lock.json * Fix ff2mpv info url * Update readme --------- Co-authored-by: bytedream <bytedream@protonmail.com>
This commit is contained in:
parent
00514e4e81
commit
7c45cacd36
39
README.md
39
README.md
@ -27,7 +27,9 @@ A multi-browser addon / extension for multiple streaming providers which redirec
|
|||||||
•
|
•
|
||||||
<a href="#-supported-sites">Supported Sites 📜</a>
|
<a href="#-supported-sites">Supported Sites 📜</a>
|
||||||
•
|
•
|
||||||
<a href="#%EF%B8%8F-building">Building ⚙️</a>
|
<a href="#%EF%B8%8F-building">Building 🛠️</a>
|
||||||
|
•
|
||||||
|
<a href="#%EF%B8%8F-settings">Settings ⚙️</a>
|
||||||
•
|
•
|
||||||
<a href="#-license">License ⚖</a>
|
<a href="#-license">License ⚖</a>
|
||||||
</p>
|
</p>
|
||||||
@ -84,6 +86,9 @@ Install the addon directly from the [firefox addon store](https://addons.mozilla
|
|||||||
| [voe.sx](https://voe.sx) | ✔ | |
|
| [voe.sx](https://voe.sx) | ✔ | |
|
||||||
| [vupload.com](https://vupload.com) | ✔ | |
|
| [vupload.com](https://vupload.com) | ✔ | |
|
||||||
| [kwik.cx](https://kwik.cx) | ✔ | |
|
| [kwik.cx](https://kwik.cx) | ✔ | |
|
||||||
|
| [dropload.io](https://dropload.io) | ✔ | |
|
||||||
|
| [supervideo.tv](https://supervideo.tv) | ✔ | |
|
||||||
|
| [goodstream.uno](https://goodstream.uno) | ✔ | |
|
||||||
|
|
||||||
- ✔️: Everything ok.
|
- ✔️: Everything ok.
|
||||||
- ⚠: Included in the addon but will probably not work. See `Note` in this case, an explanation why will stand there in the most cases.
|
- ⚠: Included in the addon but will probably not work. See `Note` in this case, an explanation why will stand there in the most cases.
|
||||||
@ -100,7 +105,7 @@ Some sites put much effort in obfuscating their code / how they receive the vide
|
|||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## ⚙️ Building
|
## 🛠️ Building
|
||||||
|
|
||||||
If you want to build the addon from source and not using the [installation](#installation) way, follow the instructions.
|
If you want to build the addon from source and not using the [installation](#installation) way, follow the instructions.
|
||||||
|
|
||||||
@ -129,6 +134,36 @@ When using firefox, use the following:
|
|||||||
3. Under `Temporary Extensions`, click `Load Temporary Add-on`.
|
3. Under `Temporary Extensions`, click `Load Temporary Add-on`.
|
||||||
4. Choose any file in the directory where the compiled sources are.
|
4. Choose any file in the directory where the compiled sources are.
|
||||||
|
|
||||||
|
|
||||||
|
## ⚙️ Settings
|
||||||
|
|
||||||
|
### <ins>ff2mpv: use mpv to directly play streams</ins>
|
||||||
|
ff2mpv is located at this repository: https://github.com/woodruffw/ff2mpv
|
||||||
|
|
||||||
|
Steps to get it set up:
|
||||||
|
- In the [Usage](https://github.com/woodruffw/ff2mpv#usage) section of the ff2mpv repository pick the installation instruction for your operating system (Linux/Windows/macOS; you do not need the browser addon).
|
||||||
|
- Scroll down to `Install manually`
|
||||||
|
- Follow instructions for Firefox/Chrome
|
||||||
|
- Edit the `ff2mpv.json` you created:
|
||||||
|
- Firefox: Add `{55dd42e8-3dd9-455a-b4fe-86664881b10c}` to `allowed_extensions` ->
|
||||||
|
```
|
||||||
|
"allowed_extensions": [
|
||||||
|
"ff2mpv@yossarian.net",
|
||||||
|
"{55dd42e8-3dd9-455a-b4fe-86664881b10c}"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
- Chrome/Chromium:
|
||||||
|
- Go To: Settings -> Extensions
|
||||||
|
- Click on `Details` of the Stream Bypass extension and copy the ID
|
||||||
|
- Add `chrome-extension://your-id-here/` to `allowed_origins` ->
|
||||||
|
```
|
||||||
|
"allowed_origins": [
|
||||||
|
"chrome-extension://ephjcajbkgplkjmelpglennepbpmdpjg/",
|
||||||
|
"chrome-extension://your-id-her/"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## ⚖ License
|
## ⚖ License
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for more details.
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for more details.
|
||||||
|
@ -2,6 +2,12 @@ import {getMatch} from "./match/match";
|
|||||||
import {storageDelete, storageGet, storageSet} from "./store/store";
|
import {storageDelete, storageGet, storageSet} from "./store/store";
|
||||||
import {Match} from "./match/matches";
|
import {Match} from "./match/matches";
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener((message, sender) => {
|
||||||
|
if (message.action == "ff2mpv") {
|
||||||
|
chrome.runtime.sendNativeMessage("ff2mpv", {url: message.url})
|
||||||
|
.catch((error) => {console.error(error)})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
chrome.webRequest.onBeforeRedirect.addListener(async details => {
|
chrome.webRequest.onBeforeRedirect.addListener(async details => {
|
||||||
// check if redirects origins from a previous redirect
|
// check if redirects origins from a previous redirect
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {getMatch} from "./match/match";
|
import {getMatch} from "./match/match";
|
||||||
import {storageDelete, storageGet} from "./store/store";
|
import {storageDelete, storageGet, getSetting} from "./store/store";
|
||||||
import {Match, matches} from "./match/matches";
|
import {Match, matches} from "./match/matches";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
@ -21,6 +21,10 @@ async function main() {
|
|||||||
|
|
||||||
const url = await match.match(re)
|
const url = await match.match(re)
|
||||||
|
|
||||||
|
if (await getSetting("ff2mpv")) {
|
||||||
|
chrome.runtime.sendMessage({action: "ff2mpv", url: url})
|
||||||
|
}
|
||||||
|
|
||||||
if (match.replace && !url.includes('.m3u8')) {
|
if (match.replace && !url.includes('.m3u8')) {
|
||||||
const player = document.createElement('video')
|
const player = document.createElement('video')
|
||||||
player.style.width = '100%'
|
player.style.width = '100%'
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
"storage",
|
"storage",
|
||||||
"webRequest",
|
"webRequest",
|
||||||
|
"nativeMessaging",
|
||||||
"<all_urls>"
|
"<all_urls>"
|
||||||
],
|
],
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
|
@ -55,14 +55,14 @@ class Filemoon implements Match {
|
|||||||
id = 'filemoon'
|
id = 'filemoon'
|
||||||
reliability = Reliability.HIGH
|
reliability = Reliability.HIGH
|
||||||
domains = [
|
domains = [
|
||||||
'filemoon.sx'
|
'filemoon.sx',
|
||||||
|
'filemoon.in'
|
||||||
]
|
]
|
||||||
regex = new RegExp(/eval\(function\(p,a,c,k,e,d\).*?(?=\<\/script\>)/gms)
|
regex = new RegExp(/eval\(function\(p,a,c,k,e,d\).*?(?=\<\/script\>)/gms)
|
||||||
|
|
||||||
async match(match: RegExpMatchArray): Promise<string> {
|
async match(match: RegExpMatchArray): Promise<string> {
|
||||||
let unpacked = await unPack(match[0])
|
let unpacked = await unPack(match[0])
|
||||||
let url = unpacked.match(/(?<=file:").*(?=")/)[0]
|
let url = unpacked.match(/(?<=file:").*(?=")/)[0]
|
||||||
console.log(url)
|
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +99,6 @@ class Mp4Upload implements Match {
|
|||||||
|
|
||||||
async match(match: RegExpMatchArray): Promise<string> {
|
async match(match: RegExpMatchArray): Promise<string> {
|
||||||
let unpacked = await unPack(match[0])
|
let unpacked = await unPack(match[0])
|
||||||
console.log(unpacked)
|
|
||||||
let url = unpacked.match(/(?<=player.src\(").*(?=")/)[0]
|
let url = unpacked.match(/(?<=player.src\(").*(?=")/)[0]
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
@ -226,11 +225,56 @@ class Kwik implements Match {
|
|||||||
console.log(match[0]);
|
console.log(match[0]);
|
||||||
let unpacked = await unPack(match[0])
|
let unpacked = await unPack(match[0])
|
||||||
let url = unpacked.match(/(?<=source=').*(?=')/)[0]
|
let url = unpacked.match(/(?<=source=').*(?=')/)[0]
|
||||||
console.log(url)
|
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DropLoad implements Match {
|
||||||
|
name = 'Dropload'
|
||||||
|
id = 'dropload'
|
||||||
|
reliability = Reliability.HIGH
|
||||||
|
domains = [
|
||||||
|
'dropload.io'
|
||||||
|
]
|
||||||
|
regex = new RegExp(/eval\(function\(p,a,c,k,e,d\).*?(?=\<\/script\>)/gms)
|
||||||
|
|
||||||
|
async match(match: RegExpMatchArray): Promise<string> {
|
||||||
|
let unpacked = await unPack(match[0])
|
||||||
|
let url = unpacked.match(/(?<=file:").*(?=")/)[0]
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SuperVideo implements Match {
|
||||||
|
name = 'Supervideo'
|
||||||
|
id = 'supervideo'
|
||||||
|
reliability = Reliability.HIGH
|
||||||
|
domains = [
|
||||||
|
'supervideo.tv'
|
||||||
|
]
|
||||||
|
regex = new RegExp(/eval\(function\(p,a,c,k,e,d\).*?(?=\<\/script\>)/gms)
|
||||||
|
|
||||||
|
async match(match: RegExpMatchArray): Promise<string> {
|
||||||
|
let unpacked = await unPack(match[0])
|
||||||
|
let url = unpacked.match(/(?<=file:").*(?=")/)[0]
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GoodStream implements Match {
|
||||||
|
name = 'Goodstream'
|
||||||
|
id = 'goodstream'
|
||||||
|
reliability = Reliability.NORMAL
|
||||||
|
domains = [
|
||||||
|
'goodstream.uno'
|
||||||
|
]
|
||||||
|
regex = new RegExp(/(?<=file:\s+").*(?=")/g)
|
||||||
|
|
||||||
|
async match(match: RegExpMatchArray): Promise<string> {
|
||||||
|
return match[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const matches = [
|
export const matches = [
|
||||||
new Doodstream(),
|
new Doodstream(),
|
||||||
new Filemoon(),
|
new Filemoon(),
|
||||||
@ -243,5 +287,8 @@ export const matches = [
|
|||||||
new Vidoza(),
|
new Vidoza(),
|
||||||
new Voe(),
|
new Voe(),
|
||||||
new Vupload(),
|
new Vupload(),
|
||||||
new Kwik()
|
new Kwik(),
|
||||||
|
new DropLoad(),
|
||||||
|
new SuperVideo(),
|
||||||
|
new GoodStream()
|
||||||
]
|
]
|
||||||
|
27
src/store/settings.ts
Normal file
27
src/store/settings.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { storageSet, storageGet } from "./store"
|
||||||
|
|
||||||
|
export class Setting {
|
||||||
|
name: string
|
||||||
|
info_url?: string
|
||||||
|
|
||||||
|
constructor(name: string, info_url?: string) {
|
||||||
|
this.name = name
|
||||||
|
this.info_url = info_url
|
||||||
|
}
|
||||||
|
|
||||||
|
async enable() {
|
||||||
|
await storageSet(this.name, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
async disable() {
|
||||||
|
await storageSet(this.name, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_status() {
|
||||||
|
return await storageGet(this.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Settings = [
|
||||||
|
new Setting("ff2mpv", "https://github.com/ByteDream/stream-bypass/tree/master#ff2mpv-use-mpv-to-directly-play-streams")
|
||||||
|
]
|
@ -66,3 +66,5 @@ export async function disable(match: Match) {
|
|||||||
await storageSet('disabled', disabled)
|
await storageSet('disabled', disabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getSetting = storageGet
|
@ -13,8 +13,16 @@
|
|||||||
<a>On</a>
|
<a>On</a>
|
||||||
<a>Off</a>
|
<a>Off</a>
|
||||||
</div>
|
</div>
|
||||||
|
<p>Hosters</p>
|
||||||
|
<table id="sub-container">
|
||||||
|
</table>
|
||||||
|
<hr class="upper-hr">
|
||||||
|
<p>Settings</p>
|
||||||
|
<table id="settings-container">
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<table id="sub-container">
|
<table id="sub-container">
|
||||||
</table>
|
</table>
|
||||||
<a id="error" href="https://github.com/ByteDream/stream-bypass/issues">Something does not work</a>
|
<a id="error" href="https://github.com/ByteDream/stream-bypass/issues">Something does not work</a>
|
||||||
|
@ -40,16 +40,26 @@ a {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin: 3px 0;
|
margin: 3px 0;
|
||||||
|
|
||||||
|
&.upper-hr {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#all {
|
#all {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
margin: 10px 0
|
margin: 10px 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.low-reliability {
|
.low-reliability {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
text-decoration-color: rgb(255, 0, 0);
|
text-decoration-color: rgb(255, 0, 0);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {getDisabled, disable, enable, getAllDisabled, enableAll, disableAll} from "../../store/store";
|
import {getDisabled, disable, enable, getAllDisabled, enableAll, disableAll} from "../../store/store";
|
||||||
import {matches, Reliability} from "../../match/matches";
|
import {matches, Reliability} from "../../match/matches";
|
||||||
|
import { Settings, Setting } from "../../store/settings";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const disabled = await getDisabled()
|
const disabled = await getDisabled()
|
||||||
@ -52,6 +53,51 @@ async function main() {
|
|||||||
subContainer.append(row)
|
subContainer.append(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settingsContainer = document.getElementById("settings-container")
|
||||||
|
for (const s of Settings) {
|
||||||
|
const row = document.createElement('tr')
|
||||||
|
|
||||||
|
const name = document.createElement('td')
|
||||||
|
const nameValue = document.createElement('p')
|
||||||
|
nameValue.innerText = s.name
|
||||||
|
|
||||||
|
const buttons = document.createElement('td')
|
||||||
|
buttons.classList.add('buttons')
|
||||||
|
const on = document.createElement('a')
|
||||||
|
on.innerText = 'On'
|
||||||
|
const off = document.createElement('a')
|
||||||
|
off.innerText = 'Off'
|
||||||
|
const info = document.createElement('a')
|
||||||
|
info.target = "_blank"
|
||||||
|
info.href = s.info_url
|
||||||
|
info.innerText = "🛈"
|
||||||
|
|
||||||
|
await s.get_status() ? on.classList.add('active') : off.classList.add('active')
|
||||||
|
|
||||||
|
on.onclick = async function () {
|
||||||
|
if (!on.classList.contains('disabled')) {
|
||||||
|
await s.enable()
|
||||||
|
on.classList.add('active')
|
||||||
|
off.classList.remove('active')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
off.onclick = async function () {
|
||||||
|
if (!off.classList.contains('disabled')) {
|
||||||
|
await s.disable()
|
||||||
|
on.classList.remove('active')
|
||||||
|
off.classList.add('active')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name.append(nameValue)
|
||||||
|
buttons.append(on, off)
|
||||||
|
if (s.info_url) {
|
||||||
|
buttons.append(info)
|
||||||
|
}
|
||||||
|
row.append(name, buttons)
|
||||||
|
settingsContainer.append(row)
|
||||||
|
}
|
||||||
|
|
||||||
const allOnButton = document.getElementById('all').getElementsByTagName('a')[0]
|
const allOnButton = document.getElementById('all').getElementsByTagName('a')[0]
|
||||||
const allOffButton = document.getElementById('all').getElementsByTagName('a')[1]
|
const allOffButton = document.getElementById('all').getElementsByTagName('a')[1]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user