This commit is contained in:
2023-11-11 21:07:44 +01:00
parent 0054f5da0e
commit 6e7410b088
60 changed files with 8809 additions and 1314 deletions

View File

@ -0,0 +1,24 @@
import type { Match } from '~/lib/match';
import { storageDelete, storageGet, storageSet } from '~/lib/settings';
import { getMatch } from '~/lib/match';
chrome.runtime.onMessage.addListener(async (message) => {
if (message.action == 'ff2mpv') {
await chrome.runtime.sendNativeMessage('ff2mpv', { url: message.url });
}
});
chrome.webRequest.onBeforeRedirect.addListener(
async (details) => {
// check if redirects origins from a previous redirect
if ((await storageGet('redirect')) === undefined) {
let match: Match;
if ((match = await getMatch(new URL(details.url).hostname)) !== undefined) {
await storageSet('redirect', match.id);
}
} else {
await storageDelete('redirect');
}
},
{ urls: ['<all_urls>'], types: ['main_frame', 'sub_frame'] }
);

View File

@ -0,0 +1,51 @@
import type { Match } from '~/lib/match';
import { getMatch } from '~/lib/match';
import { Other, Redirect } from '~/lib/settings';
import browser from 'webextension-polyfill';
async function main() {
let match: Match;
let redirect = false;
if ((match = await getMatch(window.location.host)) === null) {
if ((match = await Redirect.get()) === null) {
return;
}
redirect = true;
}
const re = document.body.innerHTML.match(match.regex);
if (re === null) {
return;
}
if (redirect) {
await Redirect.delete();
}
const url = await match.match(re);
// send the url to the ff2mpv (https://github.com/woodruffw/ff2mpv) application
if (await Other.getFf2mpv()) {
await browser.runtime.sendMessage({ action: 'ff2mpv', url: url });
}
if (match.replace && !url.includes('.m3u8')) {
const player = document.createElement('video');
player.style.width = '100%';
player.style.height = '100%';
player.controls = true;
player.src = url;
document.body.innerHTML = '';
document.body.append(player);
} else {
window.location.assign(
browser.runtime.getURL(
`src/entries/player/player.html?id=${match.id}&url=${encodeURIComponent(url)}&domain=${
window.location.hostname
}`
)
);
}
}
main();

View File

@ -0,0 +1,62 @@
<script lang="ts">
import { play } from '~/entries/player/player';
import { onMount } from 'svelte';
let errorMessage: string | null = null;
let videoElem: HTMLVideoElement;
onMount(async () => {
try {
await play(videoElem);
videoElem.controls = true;
} catch (e) {
errorMessage = e;
}
});
</script>
<!-- svelte-ignore a11y-media-has-caption -->
<video id="video" bind:this={videoElem} />
{#if errorMessage}
<div id="message-container">
<p>
{@html errorMessage}
</p>
</div>
{/if}
<style lang="scss" global>
body {
background-color: #131313;
}
html,
body,
video {
width: 100%;
height: 100%;
margin: 0;
}
video {
position: absolute;
top: 0;
left: 0;
}
#message-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: white;
text-align: center;
height: 100%;
& a,
& a:visited {
color: inherit;
text-decoration: underline;
}
}
</style>

View File

@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Stream Bypass</title>
</head>
<body>
<script type="module">
import Player from '~/entries/player/Player.svelte';
new Player({
target: document.body
});
</script>
</body>
</html>

View File

@ -0,0 +1,39 @@
import { matches } from '~/lib/match';
import Hls from 'hls.js';
async function playNative(url: string, videoElem: HTMLVideoElement) {
videoElem.src = url;
}
async function playHls(url: string, videoElem: HTMLVideoElement) {
if (videoElem.canPlayType('application/vnd.apple.mpegurl')) {
videoElem.src = url;
} else if (Hls.isSupported()) {
const hls = new Hls({
enableWorker: false
});
hls.loadSource(url);
hls.attachMedia(videoElem);
} else {
throw '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>';
}
}
export async function play(videoElem: HTMLVideoElement) {
const urlQuery = new URLSearchParams(window.location.search);
const id = urlQuery.get('id');
const url = decodeURIComponent(urlQuery.get('url'));
const domain = urlQuery.get('domain');
const match = matches[id];
if (match === undefined) {
throw `Invalid id: ${id}. Please report this <a href="https://github.com/ByteDream/stream-bypass/issues">here</a>`;
}
document.title = `Stream Bypass (${domain})`;
if (new URL(url).pathname.endsWith('.m3u8')) {
await playHls(url, videoElem);
} else {
await playNative(url, videoElem);
}
}

View File

@ -0,0 +1,217 @@
<script lang="ts">
import { matches, Reliability } from '~/lib/match';
import { Hosters, Other } from '~/lib/settings';
let hostersEnabled: boolean;
let hosters = [];
(async () => {
hostersEnabled = !(await Hosters.getAllDisabled());
const disabled = await Hosters.getDisabled();
hosters = Object.values(matches).map((m) => {
m['active'] = disabled.findIndex((p) => p.id == m.id) == -1;
m['disabled'] = !hostersEnabled;
return m;
});
})();
let ff2mpvEnabled: boolean;
(async () => {
ff2mpvEnabled = await Other.getFf2mpv();
})();
</script>
<main>
<div>
<h3 class="header">Hosters</h3>
<div class="buttons super-buttons">
<button
class:active={hostersEnabled}
on:click={async () => {
await Hosters.enableAll();
hostersEnabled = true;
hosters = hosters.map((m) => {
m['disabled'] = false;
return m;
});
}}>On</button
>
<button
class:active={!hostersEnabled}
on:click={async () => {
await Hosters.disableAll();
hostersEnabled = false;
hosters = hosters.map((m) => {
m['disabled'] = true;
return m;
});
}}>Off</button
>
</div>
<table class="setting-table">
{#each hosters as hoster}
<tr>
<td class="setting-name">
<p
class:reliability-low={hoster.reliability === Reliability.LOW}
class:reliability-normal={hoster.reliability === Reliability.NORMAL}
class:reliability-high={hoster.reliability === Reliability.HIGH}
>
{hoster.name}
</p>
</td>
<td class="buttons">
<button
class:disabled={hoster.disabled}
class:active={hoster.active}
on:click={async () => {
if (hoster.disabled) return;
await Hosters.enable(hoster);
hoster.active = true;
}}>On</button
>
<button
class:disabled={hoster.disabled}
class:active={!hoster.active}
on:click={async () => {
if (hoster.disabled) return;
await Hosters.disable(hoster);
hoster.active = false;
}}>Off</button
>
</td>
</tr>
{/each}
</table>
</div>
<hr />
<div>
<h3 class="header">Other</h3>
<table>
<tr>
<td class="setting-name">
<p>ff2mpv</p>
</td>
<td class="buttons">
<button
class:active={ff2mpvEnabled}
on:click={async () => {
await Other.setFf2mpv(true);
ff2mpvEnabled = true;
}}>On</button
>
<button
class:active={!ff2mpvEnabled}
on:click={async () => {
await Other.setFf2mpv(false);
ff2mpvEnabled = false;
}}>Off</button
>
<a
href="https://github.com/ByteDream/stream-bypass/tree/master#ff2mpv-use-mpv-to-directly-play-streams"
>🛈</a
>
</td>
</tr>
</table>
</div>
<hr />
<a id="bug-notice" href="https://github.com/ByteDream/stream-bypass/issues"
>Something does not work</a
>
</main>
<style lang="scss" global>
body {
background-color: #2b2a33;
color: white;
font-weight: bold;
overflow-x: hidden;
overflow-y: auto;
}
#bug-notice {
border: none;
color: white;
display: block;
font-weight: lighter;
font-size: 0.8rem;
text-align: center;
padding: 5px 0;
}
.settings {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px 0;
}
.header {
font-size: 16px;
margin: 5px 0;
text-align: center;
}
.setting-table {
border-collapse: collapse;
border-spacing: 0;
}
.setting-name {
height: 34px;
p {
margin: 0;
cursor: default;
}
}
.buttons {
display: flex;
flex-direction: row;
height: 34px;
button,
a {
border: 1px solid #281515;
background-color: transparent;
color: white;
cursor: pointer;
padding: 5px 8px;
margin: 0;
text-decoration: none;
&.active {
background-color: rgba(255, 65, 65, 0.74);
cursor: default;
}
&.disabled {
background-color: gray;
cursor: not-allowed;
}
}
&.super-buttons {
display: flex;
justify-content: center;
gap: 4px;
width: 100%;
margin-bottom: 10px;
}
}
.reliability-low {
text-decoration: underline;
text-decoration-color: red;
}
.reliability-normal {
text-decoration: underline;
text-decoration-color: yellow;
}
.reliability-high {
text-decoration: underline;
text-decoration-color: #00ff00;
}
</style>

View File

@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Stream Bypass</title>
</head>
<body style="width: fit-content; height: 500px">
<script type="module">
import Popup from '~/entries/popup/Popup.svelte';
new Popup({
target: document.body
});
</script>
</body>
</html>

View File

@ -0,0 +1,5 @@
import App from './Popup.svelte';
new App({
target: document.getElementById('app')
});