mirror of
https://github.com/bytedream/stream-bypass.git
synced 2025-05-11 13:15:13 +02:00
2 new websites + indicator for redirect reliability
This commit is contained in:
parent
99d4577d1d
commit
0916f1c637
@ -4,7 +4,9 @@ mixdrop.co
|
|||||||
streamtape.com
|
streamtape.com
|
||||||
streamzz.to
|
streamzz.to
|
||||||
thevideome.com
|
thevideome.com
|
||||||
|
upstream.to
|
||||||
vidlox.me
|
vidlox.me
|
||||||
|
vidstream.pro
|
||||||
vidoza.net
|
vidoza.net
|
||||||
vivo.st
|
vivo.st
|
||||||
vivo.sx
|
vivo.sx
|
||||||
|
2
build.py
2
build.py
@ -40,7 +40,7 @@ def write_manifest():
|
|||||||
toplevel = match.split('.')[-1]
|
toplevel = match.split('.')[-1]
|
||||||
if toplevel not in domains:
|
if toplevel not in domains:
|
||||||
domains.append(toplevel)
|
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)
|
json.dump(manifest, open('src/manifest.json', 'w'), indent=2)
|
||||||
|
|
||||||
|
10
src/index.ts
10
src/index.ts
@ -10,10 +10,12 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
|
|||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
for (let match of matches) {
|
for (let match of matches) {
|
||||||
if (window.location.href.indexOf(match[0]) !== -1) {
|
let domain = match[0] as string
|
||||||
if (keys.indexOf('disabled') === -1 || result['disabled'].indexOf(match[0]) === -1) {
|
if (window.location.href.indexOf(domain) !== -1) {
|
||||||
|
if (keys.indexOf('disabled') === -1 || result['disabled'].indexOf(domain) === -1) {
|
||||||
let regex = match[1] as RegExp
|
let regex = match[1] as RegExp
|
||||||
let matchClass = match[2] as Match
|
let matchClass = match[2] as Match
|
||||||
|
let reliability = match[3] as Reliability
|
||||||
|
|
||||||
let re
|
let re
|
||||||
if (regex !== null) {
|
if (regex !== null) {
|
||||||
@ -29,12 +31,12 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
|
|||||||
location.assign(document.body.innerHTML)
|
location.assign(document.body.innerHTML)
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @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 {
|
} else {
|
||||||
matchClass.match(re).then(function (path) {
|
matchClass.match(re).then(function (path) {
|
||||||
// @ts-ignore
|
// @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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Stream Bypass",
|
"name": "Stream Bypass",
|
||||||
"author": "ByteDream",
|
"author": "ByteDream",
|
||||||
"description": "",
|
"description": "",
|
||||||
"version": "1.1.4",
|
"version": "1.2.0",
|
||||||
"homepage_url": "https://github.com/ByteDream/stream-bypass",
|
"homepage_url": "https://github.com/ByteDream/stream-bypass",
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
@ -20,7 +20,9 @@
|
|||||||
"*://streamtape.com/*",
|
"*://streamtape.com/*",
|
||||||
"*://streamzz.to/*",
|
"*://streamzz.to/*",
|
||||||
"*://thevideome.com/*",
|
"*://thevideome.com/*",
|
||||||
|
"*://upstream.to/*",
|
||||||
"*://vidlox.me/*",
|
"*://vidlox.me/*",
|
||||||
|
"*://vidstream.pro/*",
|
||||||
"*://vidoza.net/*",
|
"*://vidoza.net/*",
|
||||||
"*://vivo.st/*",
|
"*://vivo.st/*",
|
||||||
"*://vivo.sx/*",
|
"*://vivo.sx/*",
|
||||||
@ -30,13 +32,14 @@
|
|||||||
"js": [
|
"js": [
|
||||||
"match.js",
|
"match.js",
|
||||||
"index.js"
|
"index.js"
|
||||||
]
|
],
|
||||||
|
"run_at": "document_end"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"storage"
|
"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": {
|
"browser_action": {
|
||||||
"default_icon": "icons/stream-bypass.png",
|
"default_icon": "icons/stream-bypass.png",
|
||||||
"default_title": "Stream Bypass",
|
"default_title": "Stream Bypass",
|
||||||
|
64
src/match.ts
64
src/match.ts
@ -1,3 +1,9 @@
|
|||||||
|
enum Reliability {
|
||||||
|
LOW = 1,
|
||||||
|
NORMAL,
|
||||||
|
HIGH
|
||||||
|
}
|
||||||
|
|
||||||
interface Match {
|
interface Match {
|
||||||
match(match: RegExpMatchArray): Promise<string>
|
match(match: RegExpMatchArray): Promise<string>
|
||||||
}
|
}
|
||||||
@ -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 {
|
class Vivo implements Match {
|
||||||
async match(match: RegExpMatchArray): Promise<string> {
|
async match(match: RegExpMatchArray): Promise<string> {
|
||||||
return this.rot47(decodeURIComponent(match[0]))
|
return this.rot47(decodeURIComponent(match[0]))
|
||||||
@ -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 = [
|
const matches = [
|
||||||
['evoload.io', null, new Evoload()],
|
['evoload.io', null, new Evoload(), Reliability.NORMAL],
|
||||||
['mcloud.to', new RegExp(/(?<=')\w+(?=';)/gm), new MCloud()],
|
['mcloud.to', new RegExp(/(?<=')\w+(?=';)/gm), new MCloud(), Reliability.NORMAL],
|
||||||
['mixdrop.co', new RegExp(/(?<=\|)\w{2,}/gm), new Mixdrop()],
|
['mixdrop.co', new RegExp(/(?<=\|)\w{2,}/gm), new Mixdrop(), Reliability.HIGH],
|
||||||
['streamtape.com', new RegExp(/id=\S*(?=')/gm), new Streamtape()],
|
['streamtape.com', new RegExp(/id=\S*(?=')/gm), new Streamtape(), Reliability.NORMAL],
|
||||||
['streamzz.to', new RegExp(/https?:\/\/get.streamz.tw\/getlink-\w+\.dll/gm), null],
|
['streamzz.to', new RegExp(/https?:\/\/get.streamz.tw\/getlink-\w+\.dll/gm), null, Reliability.NORMAL],
|
||||||
['thevideome.com', new RegExp(/(?<=\|)\w{2,}/gm), new TheVideoMe()],
|
['thevideome.com', new RegExp(/(?<=\|)\w{2,}/gm), new TheVideoMe(), Reliability.NORMAL],
|
||||||
['vidlox.me', new RegExp(/(?<=\[")\S+?(?=")/gm), null],
|
['upstream.to', new RegExp(/(?<=\|)\w{2,}/gm), new Upstream(), Reliability.LOW],
|
||||||
['vidoza.net', new RegExp(/(?<=src:(\s*)?")\S*(?=")/gm), null],
|
['vidlox.me', new RegExp(/(?<=\[")\S+?(?=")/gm), null, Reliability.NORMAL],
|
||||||
['vivo.st', new RegExp(/(?<=source:\s')(\S+)(?=')/gm), new Vivo()],
|
['vidstream.pro', new RegExp(/(?<=')\w+(?=';)/gm), new Vidstream(), Reliability.LOW],
|
||||||
['vivo.sx', new RegExp(/(?<=source:\s')(\S+)(?=')/gm), new Vivo()],
|
['vidoza.net', new RegExp(/(?<=src:(\s*)?")\S*(?=")/gm), null, Reliability.NORMAL],
|
||||||
['voe.sx', new RegExp(/https?:\/\/\S*m3u8(?=")/gm), null],
|
['vivo.st', new RegExp(/(?<=source:\s')(\S+)(?=')/gm), new Vivo(), Reliability.HIGH],
|
||||||
['vupload.com', new RegExp(/(?<=class\|)\w*/gm), new Vupload()]
|
['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]
|
||||||
]
|
]
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Title</title>
|
<title>Title</title>
|
||||||
<link rel="stylesheet" href="popup.css">
|
<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>
|
<script src="../match.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -5,13 +5,11 @@ body
|
|||||||
overflow-x: hidden
|
overflow-x: hidden
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
|
|
||||||
|
|
||||||
a, p
|
a, p
|
||||||
color: white
|
color: white
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
margin: 5px 0
|
margin: 5px 0
|
||||||
|
|
||||||
|
|
||||||
a
|
a
|
||||||
border: 1px solid #281515
|
border: 1px solid #281515
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
@ -26,7 +24,6 @@ a
|
|||||||
background-color: grey
|
background-color: grey
|
||||||
cursor: not-allowed
|
cursor: not-allowed
|
||||||
|
|
||||||
|
|
||||||
hr
|
hr
|
||||||
margin: 3px 0
|
margin: 3px 0
|
||||||
|
|
||||||
@ -35,3 +32,16 @@ hr
|
|||||||
display: flex
|
display: flex
|
||||||
justify-content: center
|
justify-content: center
|
||||||
margin: 10px 0
|
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
|
||||||
|
@ -51,12 +51,53 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
|
|||||||
let name = document.createElement('td')
|
let name = document.createElement('td')
|
||||||
let nameValue = document.createElement('p')
|
let nameValue = document.createElement('p')
|
||||||
nameValue.innerText = match[0]
|
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')
|
let buttons = document.createElement('td')
|
||||||
buttons.classList.add('buttons')
|
buttons.classList.add('buttons')
|
||||||
let on = document.createElement('a')
|
let on = document.createElement('a')
|
||||||
on.innerText = 'On'
|
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')
|
let off = document.createElement('a')
|
||||||
off.innerText = 'Off'
|
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')
|
disabled.has(match[0]) ? off.classList.add('active') : on.classList.add('active')
|
||||||
if (allDisabled) {
|
if (allDisabled) {
|
||||||
on.classList.add('disabled')
|
on.classList.add('disabled')
|
||||||
@ -85,6 +126,7 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let allButtons = document.getElementById('all').getElementsByTagName('a')
|
let allButtons = document.getElementById('all').getElementsByTagName('a')
|
||||||
|
let allOn = allButtons[0]
|
||||||
allButtons[0].onclick = function () {
|
allButtons[0].onclick = function () {
|
||||||
if (!allButtons[0].classList.contains('disabled')) {
|
if (!allButtons[0].classList.contains('disabled')) {
|
||||||
enableAll(true)
|
enableAll(true)
|
||||||
@ -92,6 +134,15 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
|
|||||||
allButtons[1].classList.remove('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 () {
|
allButtons[1].onclick = function () {
|
||||||
if (!allButtons[1].classList.contains('disabled')) {
|
if (!allButtons[1].classList.contains('disabled')) {
|
||||||
enableAll(false)
|
enableAll(false)
|
||||||
@ -99,5 +150,14 @@ chrome.storage.local.get(['all', 'disabled'], function (result) {
|
|||||||
allButtons[1].classList.add('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')
|
allDisabled ? allButtons[1].classList.add('active') : allButtons[0].classList.add('active')
|
||||||
})
|
})
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
|
|
||||||
<link rel="stylesheet" href="/res/hls.css">
|
|
||||||
<title>m3u8</title>
|
<title>m3u8</title>
|
||||||
|
<link rel="stylesheet" href="/res/hls.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
|
||||||
</head>
|
</head>
|
||||||
<body style="margin: 0">
|
<body>
|
||||||
<video id="video" style="width: 100%; height: 100%"></video>
|
<video id="video"></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>
|
<p id="message" hidden></p>
|
||||||
<script src="/res/hls.js"></script>
|
<script src="/res/hls.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,6 +1,9 @@
|
|||||||
html, body, video
|
html, body, video
|
||||||
height: 100%
|
|
||||||
width: 100%
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
margin: 0
|
||||||
|
|
||||||
video
|
video
|
||||||
margin: auto
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 0
|
@ -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() {
|
function loadHls() {
|
||||||
let url = window.location.hash.substring(1)
|
let url = window.location.hash.substring(1)
|
||||||
let video = document.getElementById('video') as HTMLVideoElement;
|
let video = document.getElementById('video') as HTMLVideoElement;
|
||||||
@ -11,9 +18,42 @@ function loadHls() {
|
|||||||
let hls = new Hls()
|
let hls = new Hls()
|
||||||
hls.loadSource(url)
|
hls.loadSource(url)
|
||||||
hls.attachMedia(video)
|
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 {
|
} else {
|
||||||
// shows a message if hls is not supported
|
// 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>`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es2015",
|
"target": "es2015",
|
||||||
|
"removeComments": true,
|
||||||
"lib": [
|
"lib": [
|
||||||
"dom",
|
"dom",
|
||||||
"es5",
|
"es5",
|
||||||
"scripthost",
|
"scripthost",
|
||||||
"es2015.collection"
|
"es2015.collection",
|
||||||
|
"es2015.promise"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user