Skip to content

Commit

Permalink
2 new websites + indicator for redirect reliability
Browse files Browse the repository at this point in the history
  • Loading branch information
bytedream committed Oct 23, 2021
1 parent 99d4577 commit 0916f1c
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 33 deletions.
2 changes: 2 additions & 0 deletions SUPPORTED
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ mixdrop.co
streamtape.com
streamzz.to
thevideome.com
upstream.to
vidlox.me
vidstream.pro
vidoza.net
vivo.st
vivo.sx
Expand Down
2 changes: 1 addition & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def write_manifest():
toplevel = match.split('.')[-1]
if toplevel not in domains:
domains.append(toplevel)
manifest['content_security_policy'] = f"script-src 'self' blob: https://cdn.jsdelivr.net {' '.join(f'*.{toplevel}' for toplevel in domains)}; object-src 'self'"
manifest['content_security_policy'] = f"script-src 'self' blob: https://cdn.jsdelivr.net https://unpkg.com {' '.join(f'*.{toplevel}' for toplevel in domains)}; object-src 'self'"

json.dump(manifest, open('src/manifest.json', 'w'), indent=2)

Expand Down
10 changes: 6 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
}
// @ts-ignore
for (let match of matches) {
if (window.location.href.indexOf(match[0]) !== -1) {
if (keys.indexOf('disabled') === -1 || result['disabled'].indexOf(match[0]) === -1) {
let domain = match[0] as string
if (window.location.href.indexOf(domain) !== -1) {
if (keys.indexOf('disabled') === -1 || result['disabled'].indexOf(domain) === -1) {
let regex = match[1] as RegExp
let matchClass = match[2] as Match
let reliability = match[3] as Reliability

let re
if (regex !== null) {
Expand All @@ -29,12 +31,12 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
location.assign(document.body.innerHTML)
} else {
// @ts-ignore
location.assign(hasSuffix(re[0], 'm3u8') ? chrome.runtime.getURL(`res/hls.html#${re[0]}`) : re[0])
location.assign(hasSuffix(re[0], 'm3u8') ? chrome.runtime.getURL(`res/hls.html?domain=${domain}&reliability=${reliability}#${re[0]}`) : re[0])
}
} else {
matchClass.match(re).then(function (path) {
// @ts-ignore
location.assign(hasSuffix(path, 'm3u8') ? chrome.runtime.getURL(`res/hls.html#${path}`) : path)
location.assign(hasSuffix(path, 'm3u8') ? chrome.runtime.getURL(`res/hls.html?domain=${domain}&reliability=${reliability}#${path}`) : path)
})
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Stream Bypass",
"author": "ByteDream",
"description": "",
"version": "1.1.4",
"version": "1.2.0",
"homepage_url": "https://github.com/ByteDream/stream-bypass",
"browser_specific_settings": {
"gecko": {
Expand All @@ -20,7 +20,9 @@
"*://streamtape.com/*",
"*://streamzz.to/*",
"*://thevideome.com/*",
"*://upstream.to/*",
"*://vidlox.me/*",
"*://vidstream.pro/*",
"*://vidoza.net/*",
"*://vivo.st/*",
"*://vivo.sx/*",
Expand All @@ -30,13 +32,14 @@
"js": [
"match.js",
"index.js"
]
],
"run_at": "document_end"
}
],
"permissions": [
"storage"
],
"content_security_policy": "script-src 'self' blob: https://cdn.jsdelivr.net *.io *.to *.co *.com *.me *.net *.st *.sx; object-src 'self'",
"content_security_policy": "script-src 'self' blob: https://cdn.jsdelivr.net https://unpkg.com *.io *.to *.co *.com *.me *.pro *.net *.st *.sx; object-src 'self'",
"browser_action": {
"default_icon": "icons/stream-bypass.png",
"default_title": "Stream Bypass",
Expand Down
64 changes: 51 additions & 13 deletions src/match.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
enum Reliability {
LOW = 1,
NORMAL,
HIGH
}

interface Match {
match(match: RegExpMatchArray): Promise<string>
}
Expand Down Expand Up @@ -50,6 +56,26 @@ class TheVideoMe implements Match {
}
}

class Upstream implements Match {
async match(match: RegExpMatchArray): Promise<string> {
return `https://${match[48]}.upstreamcdn.co/hls/,${match.sort((a, b) => {return b.length - a.length})[0]},.urlset/master.m3u8`
}
}

class Vidstream implements Match {
async match(match: RegExpMatchArray): Promise<string> {
const code = window.location.pathname.split('/').slice(-1)[0]
const response = await fetch(`https://vidstream.pro/info/${code}?skey=${match[0]}`, {
headers: {
'Content-Type': 'application/json'
},
referrer: `https://vidstream.pro/embed/${code}`
})
const json = await response.json()
return json['media']['sources'][0]['file']
}
}

class Vivo implements Match {
async match(match: RegExpMatchArray): Promise<string> {
return this.rot47(decodeURIComponent(match[0]))
Expand All @@ -76,18 +102,30 @@ class Vupload implements Match {
}
}

// every match HAS to be on an separate line
// all domains to match. the matches must be structured like this:
// [domain, regex match (can be null), class to call after match (can be null), reliability]
// => the domain which should be redirected
// => the regex gets called if the user visits a site with the given domain and matches the websites document body.
// if the regex is null, the complete document body gets handled as one big regex match
// => the class to call when the regex was parsed successfully. the class has to implement the `Match` interface.
// if the class is null, the user gets redirected to the first regex match element
// => the reliability shows how reliable a stream redirect is. for example, vivo.sx works nearly every time whereas
// upstream.to works only sometimes because of a security mechanism they're using (CORS) which currently can't be bypassed
//
// every match HAS to be on an separate line (for automatically manifest generation)
const matches = [
['evoload.io', null, new Evoload()],
['mcloud.to', new RegExp(/(?<=')\w+(?=';)/gm), new MCloud()],
['mixdrop.co', new RegExp(/(?<=\|)\w{2,}/gm), new Mixdrop()],
['streamtape.com', new RegExp(/id=\S*(?=')/gm), new Streamtape()],
['streamzz.to', new RegExp(/https?:\/\/get.streamz.tw\/getlink-\w+\.dll/gm), null],
['thevideome.com', new RegExp(/(?<=\|)\w{2,}/gm), new TheVideoMe()],
['vidlox.me', new RegExp(/(?<=\[")\S+?(?=")/gm), null],
['vidoza.net', new RegExp(/(?<=src:(\s*)?")\S*(?=")/gm), null],
['vivo.st', new RegExp(/(?<=source:\s')(\S+)(?=')/gm), new Vivo()],
['vivo.sx', new RegExp(/(?<=source:\s')(\S+)(?=')/gm), new Vivo()],
['voe.sx', new RegExp(/https?:\/\/\S*m3u8(?=")/gm), null],
['vupload.com', new RegExp(/(?<=class\|)\w*/gm), new Vupload()]
['evoload.io', null, new Evoload(), Reliability.NORMAL],
['mcloud.to', new RegExp(/(?<=')\w+(?=';)/gm), new MCloud(), Reliability.NORMAL],
['mixdrop.co', new RegExp(/(?<=\|)\w{2,}/gm), new Mixdrop(), Reliability.HIGH],
['streamtape.com', new RegExp(/id=\S*(?=')/gm), new Streamtape(), Reliability.NORMAL],
['streamzz.to', new RegExp(/https?:\/\/get.streamz.tw\/getlink-\w+\.dll/gm), null, Reliability.NORMAL],
['thevideome.com', new RegExp(/(?<=\|)\w{2,}/gm), new TheVideoMe(), Reliability.NORMAL],
['upstream.to', new RegExp(/(?<=\|)\w{2,}/gm), new Upstream(), Reliability.LOW],
['vidlox.me', new RegExp(/(?<=\[")\S+?(?=")/gm), null, Reliability.NORMAL],
['vidstream.pro', new RegExp(/(?<=')\w+(?=';)/gm), new Vidstream(), Reliability.LOW],
['vidoza.net', new RegExp(/(?<=src:(\s*)?")\S*(?=")/gm), null, Reliability.NORMAL],
['vivo.st', new RegExp(/(?<=source:\s')(\S+)(?=')/gm), new Vivo(), Reliability.HIGH],
['vivo.sx', new RegExp(/(?<=source:\s')(\S+)(?=')/gm), new Vivo(), Reliability.HIGH],
['voe.sx', new RegExp(/https?:\/\/\S*m3u8(?=")/gm), null, Reliability.HIGH],
['vupload.com', new RegExp(/(?<=class\|)\w*/gm), new Vupload(), Reliability.NORMAL]
]
2 changes: 2 additions & 0 deletions src/popup/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="popup.css">
<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://unpkg.com/tippy.js@6"></script>
<script src="../match.js"></script>
</head>
<body>
Expand Down
16 changes: 13 additions & 3 deletions src/popup/popup.sass
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ body
overflow-x: hidden
overflow-y: auto


a, p
color: white
font-size: 16px
margin: 5px 0


a
border: 1px solid #281515
cursor: pointer
Expand All @@ -26,7 +24,6 @@ a
background-color: grey
cursor: not-allowed


hr
margin: 3px 0

Expand All @@ -35,3 +32,16 @@ hr
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
60 changes: 60 additions & 0 deletions src/popup/popup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,53 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
let name = document.createElement('td')
let nameValue = document.createElement('p')
nameValue.innerText = match[0]
switch (match[3]) {
case 1: // low
nameValue.classList.add('low-reliability')
// @ts-ignore
tippy(nameValue, {
content: 'Low reliability: Errors may occur often'
})
break
case 2: // normal
nameValue.classList.add('normal-reliability')
// @ts-ignore
tippy(nameValue, {
content: 'Normal reliability: Save to use but errors may occur'
})
break
case 3: //high
nameValue.classList.add('high-reliability')
// @ts-ignore
tippy(nameValue, {
content: 'High reliability: Errors are very unlikely to happen'
})
break
}
let buttons = document.createElement('td')
buttons.classList.add('buttons')
let on = document.createElement('a')
on.innerText = 'On'
// @ts-ignore
let onTippy = tippy(on, {
content: `Enable ${match[0]}`,
onMount: () => {
if (on.classList.contains('active') || off.classList.contains('disabled')) {
onTippy.hide()
}
}
})
let off = document.createElement('a')
off.innerText = 'Off'
// @ts-ignore
let offTippy = tippy(off, {
content: `Disable ${match[0]}`,
onMount: () => {
if (off.classList.contains('active') || off.classList.contains('disabled')) {
offTippy.hide()
}
}
})
disabled.has(match[0]) ? off.classList.add('active') : on.classList.add('active')
if (allDisabled) {
on.classList.add('disabled')
Expand Down Expand Up @@ -85,19 +126,38 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
}

let allButtons = document.getElementById('all').getElementsByTagName('a')
let allOn = allButtons[0]
allButtons[0].onclick = function () {
if (!allButtons[0].classList.contains('disabled')) {
enableAll(true)
allButtons[0].classList.add('active')
allButtons[1].classList.remove('active')
}
}
// @ts-ignore
let allOnTippy = tippy(allOn, {
content: 'Enable all websites',
onMount: () => {
if (allButtons[0].classList.contains('active')) {
allOnTippy.hide()
}
}
})
allButtons[1].onclick = function () {
if (!allButtons[1].classList.contains('disabled')) {
enableAll(false)
allButtons[0].classList.remove('active')
allButtons[1].classList.add('active')
}
}
// @ts-ignore
let allOffTippy = tippy(allButtons[1], {
content: 'Disable all websites',
onMount: () => {
if (allButtons[1].classList.contains('active')) {
allOffTippy.hide()
}
}
})
allDisabled ? allButtons[1].classList.add('active') : allButtons[0].classList.add('active')
})
10 changes: 5 additions & 5 deletions src/res/hls.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<link rel="stylesheet" href="/res/hls.css">
<title>m3u8</title>
<link rel="stylesheet" href="/res/hls.css">
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body style="margin: 0">
<video id="video" style="width: 100%; height: 100%"></video>
<p id="not-supported" hidden>Filed to play m3u8 video. Try again or create a new issue <a href="https://github.com/ByteDream/stream-bypass/issues">here</a></p>
<body>
<video id="video"></video>
<p id="message" hidden></p>
<script src="/res/hls.js"></script>
</body>
</html>
7 changes: 5 additions & 2 deletions src/res/hls.sass
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
html, body, video
height: 100%
width: 100%
height: 100%
margin: 0

video
margin: auto
position: absolute
top: 0
left: 0
42 changes: 41 additions & 1 deletion src/res/hls.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
function showMessage(message: string) {
let messageElement = document.getElementById('message') as HTMLParagraphElement
messageElement.innerHTML = message
messageElement.hidden = false
document.getElementById('video').hidden = true
}

function loadHls() {
let url = window.location.hash.substring(1)
let video = document.getElementById('video') as HTMLVideoElement;
Expand All @@ -11,9 +18,42 @@ function loadHls() {
let hls = new Hls()
hls.loadSource(url)
hls.attachMedia(video)

let searchParams = new URLSearchParams(window.location.search)
let rawReliability = parseInt(searchParams.get('reliability'))

let thirdPartyFallback = setTimeout(() => {
let message: string

switch (rawReliability) {
case 1: // low
message = `The reliability for this domain is low, so errors like this are common.
Try to choose another streaming provider (if existent) or deactivate the addon for this domain (${searchParams.get('domain')}) and try again`
break
case 2: // normal
message = `The reliability for this domain is normal, errors like this can occur but are not very common. Try to refresh the page`
break
case 3: // high
message = `The reliability for this domains is high, errors like this are very unlikely to happen.
Try to refresh the page and if the error still exists you might want to open a new issue <a href="https://github.com/ByteDream/stream-bypass/issues">here</a>.
When your using <a href="https://www.torproject.org/">Tor</a> such errors have a slight chance to occur more often,
so if this is the case just try to reload the page and see if you it's working then`
break
}

// shows a message if hls could not be loaded
showMessage(`Could not load hls video. ${message}`)
}, rawReliability * 3000)

// @ts-ignore
hls.on(Hls.Events.MANIFEST_PARSED, () => {
clearTimeout(thirdPartyFallback)
document.getElementById('video').hidden = false
document.getElementById('message').hidden = true
})
} else {
// shows a message if hls is not supported
document.getElementById('not-supported').hidden = false
showMessage(`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">here</a>`)
}
}

Expand Down
Loading

0 comments on commit 0916f1c

Please sign in to comment.