diff --git a/README.md b/README.md index 53a546c..ce32fe4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
-Current version: **4.1.3** +Current version: **4.1.4** # About This takes ESPN+, ESPN, FOX Sports, CBS Sports, Paramount+, Gotham Sports, NFL, B1G+, NESN, Mountain West, FloSports, or MLB.tv programming and transforms it into a "live TV" experience with virtual linear channels. It will discover what is on, and generate a schedule of channels that will give you M3U and XMLTV files that you can import into something like [Jellyfin](https://jellyfin.org) or [Channels](https://getchannels.com). @@ -117,7 +117,6 @@ If you don't have an NFL+ subscription, you can use these providers to access ga | Provider Name | Description | |---|---| | Amazon Prime | Get TNF games from Amazon Prime | -| Twitch | Get TNF games from Twitch.tv (no auth required) | | Peacock | Get SNF games from Peacock | | TV Provider | Get in-market games from your TV Provider | | Sunday Ticket | Get out-of-market games from Youtube | diff --git a/package-lock.json b/package-lock.json index 3d1a51e..fd18b03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "eplustv", - "version": "4.1.3", + "version": "4.1.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "eplustv", - "version": "4.1.3", + "version": "4.1.4", "license": "MIT", "dependencies": { "@hono/node-server": "^1.13.1", diff --git a/package.json b/package.json index 6cd1687..58dbc58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eplustv", - "version": "4.1.3", + "version": "4.1.4", "description": "", "scripts": { "start": "ts-node -r tsconfig-paths/register index.tsx", diff --git a/services/nfl-handler.ts b/services/nfl-handler.ts index 3e2aa0d..f7758bd 100644 --- a/services/nfl-handler.ts +++ b/services/nfl-handler.ts @@ -5,12 +5,12 @@ import axios from 'axios'; import moment from 'moment'; import jwt_decode from 'jwt-decode'; -import {okHttpUserAgent, userAgent} from './user-agent'; +import {okHttpUserAgent} from './user-agent'; import {configPath} from './config'; import {useNfl} from './networks'; import {ClassTypeWithoutMethods, IEntry, IHeaders, IProvider} from './shared-interfaces'; import {db} from './database'; -import {getRandomHex, getRandomUUID} from './shared-helpers'; +import {getRandomUUID} from './shared-helpers'; import {useLinear} from './channels'; import {debug} from './debug'; @@ -119,39 +119,6 @@ const CLIENT_SECRET = ['q', 'G', 'h', 'E', 'v', '1', 'R', 't', 'I', '2', 'S', 'f const TV_CLIENT_SECRET = ['u', 'o', 'C', 'y', 'y', 'k', 'y', 'U', 'w', 'D', 'b', 'f', 'Q', 'Z', 'r', '2'].join(''); -const TWITCH_CLIENT_ID = [ - 'k', - 'i', - 'm', - 'n', - 'e', - '7', - '8', - 'k', - 'x', - '3', - 'n', - 'c', - 'x', - '6', - 'b', - 'r', - 'g', - 'o', - '4', - 'm', - 'v', - '6', - 'w', - 'k', - 'i', - '5', - 'h', - '1', - 'k', - 'o', -].join(''); - const DEVICE_INFO = { capabilities: {}, ctvDevice: 'AndroidTV', @@ -194,7 +161,7 @@ const DEFAULT_CATEGORIES = ['NFL', 'NFL+', 'Football']; const nflConfigPath = path.join(configPath, 'nfl_tokens.json'); -export type TOtherAuth = 'prime' | 'tve' | 'peacock' | 'sunday_ticket' | 'twitch'; +export type TOtherAuth = 'prime' | 'tve' | 'peacock' | 'sunday_ticket'; interface INFLJwt { dmaCode: string; @@ -202,19 +169,6 @@ interface INFLJwt { networks?: {[key: string]: string}; } -interface ITwitchAccessTokenRes { - data: ITwitchAccessToken; -} - -interface ITwitchAccessToken { - streamPlaybackAccessToken: ITwitchStreamToken; -} - -interface ITwitchStreamToken { - value: string; - signature: string; -} - const parseAirings = async (events: INFLEvent[]) => { const now = moment(); const endDate = moment().add(2, 'days').endOf('day'); @@ -291,7 +245,6 @@ class NflHandler { public peacockUUID?: string; public youTubeUserId?: string; public youTubeUUID?: string; - public twitchDeviceId?: string; public initialize = async () => { const setup = (await db.providers.count({name: 'nfl'})) > 0 ? true : false; @@ -444,24 +397,10 @@ class NflHandler { this.checkTVEEventAccess(i) || // Peacock (i.authorizations.peacock && this.checkPeacockAccess()) || - // Prime || Twitch.tv - (i.authorizations.amazon_prime && (this.checkPrimeAccess() || this.checkTwitchAccess())) + // Prime + (i.authorizations.amazon_prime && this.checkPrimeAccess()) ) { - if (i.authorizations.amazon_prime) { - if (this.checkTwitchAccess()) { - events.push({ - ...i, - externalId: `${i.externalId}-twitch`, - networks: ['Twitch'], - }); - } - - if (this.checkPrimeAccess()) { - events.push(i); - } - } else { - events.push(i); - } + events.push(i); } } else if ( i.callSign === 'NFLNRZ' && @@ -520,97 +459,31 @@ class NflHandler { const isGame = event.channel !== 'NFLNETWORK' && event.channel !== 'NFLDIGITAL1_OO_v3' && event.channel !== 'NFLNRZ'; - const isTwitch = event.feed === 'Twitch'; - - if (!isTwitch) { - const url = ['https://', 'api.nfl.com/', 'play/v1/asset/', id].join(''); - - const {data} = await axios.post( - url, - { - ...(this.checkTVEAccess() && { - idp: this.mvpdIdp, - mvpdUUID: this.mvpdUUID, - mvpdUserId: this.mvpdUserId, - networks: event.feed || 'NFLN', - }), - }, - { - headers: { - 'Content-Type': 'application/json', - 'User-Agent': okHttpUserAgent, - authorization: `Bearer ${isGame ? this.access_token : this.tv_access_token}`, - }, - }, - ); - - return [data.accessUrl, {}]; - } else { - try { - const channel = event.name.indexOf('Vision') > -1 ? 'primevision' : 'primevideo'; - - const accessToken = await this.getTwitchAccessToken(channel); - - const url = [ - 'https://usher.ttvnw.net', - '/api/channel/hls/', - `${channel}.m3u8`, - '?client_id=', - TWITCH_CLIENT_ID, - '&token=', - accessToken.value, - '&sig=', - accessToken.signature, - '&allow_source=true', - '&allow_audio_only=false', - ].join(''); - - return [url, {}]; - } catch (e) { - console.error(e); - console.log('Could not start playback from Twitch'); - } - } - } catch (e) { - console.error(e); - console.log('Could not start playback'); - } - }; + const url = ['https://', 'api.nfl.com/', 'play/v1/asset/', id].join(''); - private getTwitchAccessToken = async (channel: string): Promise