mirror of
https://github.com/bytedream/stream-bypass.git
synced 2025-06-27 18:40:31 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
dd9bf71a5c | |||
6da0050df4 | |||
1a7c22ec0e | |||
175862b098 | |||
fd5a532d0f | |||
8c43eedb23 | |||
e027c2e09e | |||
f9a0656d4d | |||
382d8b1268 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "stream-bypass",
|
"name": "stream-bypass",
|
||||||
"version": "2.1.3",
|
"version": "2.1.5",
|
||||||
"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",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -21,12 +21,12 @@
|
|||||||
"homepage": "https://github.com/ByteDream/stream-bypass#readme",
|
"homepage": "https://github.com/ByteDream/stream-bypass#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^22.0.0",
|
"@rollup/plugin-commonjs": "^22.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^13.3.0",
|
"@rollup/plugin-node-resolve": "^14.0.1",
|
||||||
"@rollup/plugin-replace": "^4.0.0",
|
"@rollup/plugin-replace": "^4.0.0",
|
||||||
"@rollup/plugin-typescript": "^8.3.3",
|
"@rollup/plugin-typescript": "^8.3.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.27.1",
|
"@typescript-eslint/eslint-plugin": "^5.27.1",
|
||||||
"@typescript-eslint/parser": "^5.27.1",
|
"@typescript-eslint/parser": "^5.27.1",
|
||||||
"@types/chrome": "^0.0.190",
|
"@types/chrome": "^0.0.196",
|
||||||
"@types/node-sass": "^4.11.2",
|
"@types/node-sass": "^4.11.2",
|
||||||
"@types/yazl": "^2.4.2",
|
"@types/yazl": "^2.4.2",
|
||||||
"eslint": "^8.17.0",
|
"eslint": "^8.17.0",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {getMatch} from "./match/match";
|
import {getMatch} from "./match/match";
|
||||||
import {storageGet, storageSet} from "./store/store";
|
import {storageDelete, storageGet, storageSet} from "./store/store";
|
||||||
import {Match} from "./match/matches";
|
import {Match} from "./match/matches";
|
||||||
|
|
||||||
chrome.webRequest.onBeforeRedirect.addListener(async details => {
|
chrome.webRequest.onBeforeRedirect.addListener(async details => {
|
||||||
@ -9,6 +9,8 @@ chrome.webRequest.onBeforeRedirect.addListener(async details => {
|
|||||||
if ((match = await getMatch(new URL(details.url).host)) !== undefined) {
|
if ((match = await getMatch(new URL(details.url).host)) !== undefined) {
|
||||||
await storageSet('redirect', match.id)
|
await storageSet('redirect', match.id)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await storageDelete('redirect')
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
urls: ['<all_urls>'],
|
urls: ['<all_urls>'],
|
||||||
|
@ -4,20 +4,20 @@ import {Match, matches} from "./match/matches";
|
|||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
let match: Match;
|
let match: Match;
|
||||||
|
let redirect = false;
|
||||||
if ((match = await getMatch(window.location.host)) === undefined) {
|
if ((match = await getMatch(window.location.host)) === undefined) {
|
||||||
let id: string
|
let id: string
|
||||||
if ((id = await storageGet('redirect')) !== undefined) {
|
if ((id = await storageGet('redirect')) !== undefined) {
|
||||||
|
redirect = true
|
||||||
match = matches.find(m => m.id === id)
|
match = matches.find(m => m.id === id)
|
||||||
await storageDelete('redirect')
|
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const re = document.body.innerHTML.match(match.regex)
|
const re = document.body.innerHTML.match(match.regex)
|
||||||
if (re === null) {
|
if (re === null) return
|
||||||
return
|
if (redirect) await storageDelete('redirect')
|
||||||
}
|
|
||||||
|
|
||||||
const url = await match.match(re)
|
const url = await match.match(re)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Stream Bypass",
|
"name": "Stream Bypass",
|
||||||
"author": "ByteDream",
|
"author": "ByteDream",
|
||||||
"description": "A multi-browser addon / extension for multiple streaming providers which redirects directly to the source video.",
|
"description": "A multi-browser addon / extension for multiple streaming providers which redirects directly to the source video.",
|
||||||
"version": "2.1.3",
|
"version": "2.1.5",
|
||||||
"homepage_url": "https://github.com/ByteDream/stream-bypass",
|
"homepage_url": "https://github.com/ByteDream/stream-bypass",
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
|
@ -19,11 +19,12 @@ export abstract class Match {
|
|||||||
class Doodstream implements Match {
|
class Doodstream implements Match {
|
||||||
name = 'Doodstream'
|
name = 'Doodstream'
|
||||||
id = 'doodstream'
|
id = 'doodstream'
|
||||||
reliability = Reliability.HIGH
|
reliability = Reliability.NORMAL
|
||||||
domains = [
|
domains = [
|
||||||
'doodstream.com',
|
'doodstream.com',
|
||||||
'dood.pm',
|
'dood.pm',
|
||||||
'dood.ws'
|
'dood.ws',
|
||||||
|
'dood.wf'
|
||||||
]
|
]
|
||||||
replace = true
|
replace = true
|
||||||
regex = new RegExp(/(\/pass_md5\/.*?)'.*(\?token=.*?expiry=)/s)
|
regex = new RegExp(/(\/pass_md5\/.*?)'.*(\?token=.*?expiry=)/s)
|
||||||
@ -139,7 +140,7 @@ class Streamtape implements Match {
|
|||||||
class Streamzz implements Match {
|
class Streamzz implements Match {
|
||||||
name = 'Streamzz'
|
name = 'Streamzz'
|
||||||
id = 'streamzz'
|
id = 'streamzz'
|
||||||
reliability = Reliability.NORMAL
|
reliability = Reliability.LOW
|
||||||
domains = [
|
domains = [
|
||||||
'streamzz.to',
|
'streamzz.to',
|
||||||
'streamz.ws'
|
'streamz.ws'
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
body
|
|
||||||
background-color: #131313
|
|
||||||
|
|
||||||
html, body, video
|
|
||||||
width: 100%
|
|
||||||
height: 100%
|
|
||||||
margin: 0
|
|
||||||
|
|
||||||
video
|
|
||||||
position: absolute
|
|
||||||
top: 0
|
|
||||||
left: 0
|
|
||||||
|
|
||||||
#message-container
|
|
||||||
visibility: hidden
|
|
||||||
display: flex
|
|
||||||
justify-content: center
|
|
||||||
align-items: center
|
|
||||||
flex-direction: column
|
|
||||||
color: white
|
|
||||||
text-align: center
|
|
||||||
height: 100%
|
|
||||||
|
|
||||||
& *
|
|
||||||
visibility: inherit
|
|
||||||
|
|
||||||
& a, & a:visited
|
|
||||||
color: red
|
|
34
src/ui/player/player.scss
Normal file
34
src/ui/player/player.scss
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
body {
|
||||||
|
background-color: #131313;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body, video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
video {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#message-container {
|
||||||
|
visibility: hidden;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& * {
|
||||||
|
visibility: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
& a, & a:visited {
|
||||||
|
color: red
|
||||||
|
}
|
||||||
|
}
|
@ -8,33 +8,15 @@ function show_message(message: string) {
|
|||||||
document.getElementById('video').hidden = true
|
document.getElementById('video').hidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
async function play_native(url: string, match: Match) {
|
async function check_loaded(match: Match, check: Promise<boolean>) {
|
||||||
const video = document.getElementById('video') as HTMLVideoElement
|
const loaded = await new Promise((resolve, _) => {
|
||||||
video.controls = true
|
|
||||||
video.src = url
|
|
||||||
}
|
|
||||||
|
|
||||||
async function play_hls(url: string, match: Match) {
|
|
||||||
const video = document.getElementById('video') as HTMLVideoElement
|
|
||||||
video.controls = true
|
|
||||||
|
|
||||||
if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
|
||||||
video.src = url
|
|
||||||
} else if (Hls.isSupported()) {
|
|
||||||
const hls = new Hls({
|
|
||||||
enableWorker: false
|
|
||||||
})
|
|
||||||
hls.loadSource(url)
|
|
||||||
hls.attachMedia(video)
|
|
||||||
|
|
||||||
const loaded = await new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resolve(false)
|
resolve(false)
|
||||||
}, match.reliability * 3000)
|
}, match.reliability * 3000)
|
||||||
|
|
||||||
hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
check
|
||||||
resolve(true)
|
.then(value => resolve(value))
|
||||||
})
|
.catch(_ => resolve(false))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
@ -56,6 +38,38 @@ async function play_hls(url: string, match: Match) {
|
|||||||
}
|
}
|
||||||
show_message(`Could not load video. ${message}`)
|
show_message(`Could not load video. ${message}`)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function play_native(url: string, match: Match) {
|
||||||
|
const video = document.getElementById('video') as HTMLVideoElement
|
||||||
|
video.controls = true
|
||||||
|
video.src = url
|
||||||
|
|
||||||
|
const readyState = new Promise<boolean>((resolve, _) => {
|
||||||
|
video.onloadeddata = () => resolve(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
await check_loaded(match, readyState)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function play_hls(url: string, match: Match) {
|
||||||
|
const video = document.getElementById('video') as HTMLVideoElement
|
||||||
|
video.controls = true
|
||||||
|
|
||||||
|
if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
|
video.src = url
|
||||||
|
} else if (Hls.isSupported()) {
|
||||||
|
const hls = new Hls({
|
||||||
|
enableWorker: false
|
||||||
|
})
|
||||||
|
hls.loadSource(url)
|
||||||
|
hls.attachMedia(video)
|
||||||
|
|
||||||
|
const readyState = new Promise<boolean>((resolve, _) => {
|
||||||
|
video.onloadeddata = () => resolve(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
await check_loaded(match, readyState)
|
||||||
} else {
|
} else {
|
||||||
show_message('Failed to play m3u8 video (hls is not supported). Try again or create a new issue <a href="https://github.com/ByteDream/stream-bypass/issues/new">here</a>')
|
show_message('Failed to play m3u8 video (hls is not supported). Try again or create a new issue <a href="https://github.com/ByteDream/stream-bypass/issues/new">here</a>')
|
||||||
}
|
}
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
body
|
|
||||||
background-color: #2b2a33
|
|
||||||
font-weight: bold
|
|
||||||
max-height: 500px
|
|
||||||
overflow-x: hidden
|
|
||||||
overflow-y: auto
|
|
||||||
|
|
||||||
a, p
|
|
||||||
color: white
|
|
||||||
font-size: 16px
|
|
||||||
margin: 5px 0
|
|
||||||
cursor: default
|
|
||||||
|
|
||||||
a
|
|
||||||
border: 1px solid #281515
|
|
||||||
cursor: pointer
|
|
||||||
font-weight: normal
|
|
||||||
padding: 5px 8px
|
|
||||||
|
|
||||||
&.active
|
|
||||||
background-color: rgba(255, 65, 65, 0.74)
|
|
||||||
cursor: default
|
|
||||||
|
|
||||||
&.disabled
|
|
||||||
background-color: grey
|
|
||||||
cursor: not-allowed
|
|
||||||
|
|
||||||
&#error
|
|
||||||
border: none
|
|
||||||
display: block
|
|
||||||
font-weight: lighter
|
|
||||||
font-size: 0.8rem
|
|
||||||
text-align: center
|
|
||||||
padding: 10px 0 5px 0
|
|
||||||
|
|
||||||
hr
|
|
||||||
margin: 3px 0
|
|
||||||
|
|
||||||
|
|
||||||
#all
|
|
||||||
display: flex
|
|
||||||
justify-content: center
|
|
||||||
margin: 10px 0
|
|
||||||
|
|
||||||
|
|
||||||
.low-reliability
|
|
||||||
text-decoration: underline
|
|
||||||
text-decoration-color: rgb(255, 0, 0)
|
|
||||||
|
|
||||||
.normal-reliability
|
|
||||||
text-decoration: underline
|
|
||||||
text-decoration-color: yellow
|
|
||||||
|
|
||||||
.high-reliability
|
|
||||||
text-decoration: underline
|
|
||||||
text-decoration-color: #00ff00
|
|
66
src/ui/popup/popup.scss
Normal file
66
src/ui/popup/popup.scss
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
body {
|
||||||
|
background-color: #2b2a33;
|
||||||
|
font-weight: bold;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a, p {
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 5px 0;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
border: 1px solid #281515;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 5px 8px;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: rgba(255, 65, 65, 0.74);
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
background-color: grey;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
&#error {
|
||||||
|
border: none;
|
||||||
|
display: block;
|
||||||
|
font-weight: lighter;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#all {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 10px 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.low-reliability {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: rgb(255, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.normal-reliability {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high-reliability {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: #00ff00;
|
||||||
|
}
|
@ -47,8 +47,8 @@ async function buildHtml() {
|
|||||||
|
|
||||||
async function buildCss() {
|
async function buildCss() {
|
||||||
const files = {
|
const files = {
|
||||||
'src/ui/popup/popup.sass': 'build/ui/popup/popup.css',
|
'src/ui/popup/popup.scss': 'build/ui/popup/popup.css',
|
||||||
'src/ui/player/player.sass': 'build/ui/player/player.css'
|
'src/ui/player/player.scss': 'build/ui/player/player.css'
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [src, dst] of Object.entries(files)) {
|
for (const [src, dst] of Object.entries(files)) {
|
||||||
|
Reference in New Issue
Block a user