Virtual linear channels for ESPN+

Overview

EPlusTV

Current version: 0.9.0

About

This takes ESPN+ 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 or VLC.

Notes

  • This was not made for pirating streams. This is made for using your own credentials and have a different presentation than the ESPN+ app currently gives.
  • Currently this software is in a very beta state. It hasn't been fully tested and relies on some lame workarounds to get the data needed to start a stream. There are some questions about how boundies work when a scheduled entry ends or when a new entry starts if it will pick it up automatically.
  • The Mouse might not like it and it could be taken down at any minute. Enjoy it while it lasts. ¯\(ツ)

Using

The server exposes 2 main endpoints:

Endpoint Description
/channels.m3u The channel list you'll import into your client
/xmltv.xml The schedule that you'll import into your client

Running

The recommended way of running is to pull the image from Docker Hub.

Docker Setup

Environement Variables

Environment Variable Description Required?
ACCESS_URI What accessable URL your clients will be connecting from. For example: http://192.168.0.1:8000 Yes
ESPN_USER Your ESPN+ Username Yes
ESPN_PASS Your ESPN+ Password Yes
START_CHANNEL What the first channel number should be. Keep in mind this generates 100 channels to keep a healthy buffer. No. If not set, the start channel will default to 1.

Volumes

Volume Name Description Required?
/app/config Used to store DB and application state. No. But channel schedules will not be persisted.
/app/tmp Used to store temporary segments generated by the streams. Recommended to use something like /dev/shm. No

Docker Run

By default, the easiest way to get running is:

docker run -p 8000:8000 -v /config_dir:/app/config -v /dev/shm:/app/tmp -e ACCESS_URI='http://192.168.0.10:8000' -e ESPN_USER='...' -e ESPN_PASS='...'  m0ngr31/eplustv
Comments
  • Error During Installation

    Error During Installation

    When I do the docker run process I get the following error:

    _(node:21) UnhandledPromiseRejectionWarning: Error: EACCES: permission denied, open '/app/config/state.json' at Object.openSync (fs.js:497:3) at Object.writeFileSync (fs.js:1528:35) at initDirectories (/app/services/init-directories.ts:26:8) at /app/index.ts:178:18 at Generator.next () at /app/index.ts:8:71 at new Promise () at _awaiter (/app/index.ts:4:12) at /app/index.ts:177:13 at Object. (/app/index.ts:184:3) (Use node --trace-warnings ... to show where the warning was created) (node:21) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:21) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

    I have tried to run as user and sudo. Same result occurs. A container is added but it is not fully setup and doesn't work.

    How do I bypass this error?

    Thanks in advance!

    opened by m181999 16
  • Streams not working

    Streams not working

    i have eventhing installed and logged in with my account but when i got to play a stream i get the eplustv loading and nothing else

    when i check my logs i see the following

    'x-amz-cf-id': 'oY7G920a6ypCneh-90JDzd0JO1slDRubzjks56rbTHn0rDL7hoOYuA==' }, config: { transitional: [Object], adapter: [Function: httpAdapter], transformRequest: [Array], transformResponse: [Array], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object], method: 'post', url: 'https://us.edge.bamgrid.com/token', data: 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&latitude=0&longitude=0&platform=browser&setCookie=false&subject_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIyZWZkYWJiYS0zMWMxLTRmNWYtODE3Yi1kNjAwYzdiM2NhYjYiLCJhdWQiOiJ1cm46YmFtdGVjaDpzZXJ2aWNlOnRva2VuIiwibmJmIjoxNjcwMTA4MjQzLCJpc3MiOiJ1cm46YmFtdGVjaDpzZXJ2aWNlOmRldmljZSIsImV4cCI6MjUzNDEwODI0MywiaWF0IjoxNjcwMTA4MjQzLCJqdGkiOiJiOTJmZGUzZi02ZjU2LTRlZjYtOGVjNC02N2Y2Y2NlNzUyMzYifQ.NEd81x-2wYLqJBRpCJj_PFSdMrt_SRvpPDOjd5jbbUwcQ4-f6XushmsHk9AtRviv25SvarPwk2RfhidD44Ej2A&subject_token_type=urn%3Abamtech%3Aparams%3Aoauth%3Atoken-type%3Adevice' }, request: <ref *1> ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: false, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, _contentLength: null, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: false, socket: [TLSSocket], Could not get BAM access token _header: 'POST /token HTTP/1.1\r\n' + 'Accept: application/json\r\n' + 'Content-Type: application/x-www-form-urlencoded\r\n' + 'Authorization: Bearer ZXNwbiZicm93c2VyJjEuMC4w.ptUt7QxsteaRruuPmGZFaJByOoqKvDP2a5YkInHrc7c\r\n' + 'User-Agent: axios/0.27.2\r\n' + 'Content-Length: 617\r\n' + 'Host: us.edge.bamgrid.com\r\n' + 'Connection: close\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [Agent], socketPath: undefined, method: 'POST', maxHeaderSize: undefined, insecureHTTPParser: undefined, path: '/token', _ended: true, res: [IncomingMessage], aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'us.edge.bamgrid.com', protocol: 'https:', _redirectable: [Writable], [Symbol(kCapture)]: false, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(kUniqueHeaders)]: null }, data: { errors: [Array] } } } TypeError: Cannot read properties of undefined (reading 'refresh_token') at EspnHandler.<anonymous> (/app/services/espn-handler.ts:807:53) at Generator.next (<anonymous>) at fulfilled (/app/services/espn-handler.ts:5:58) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5) TypeError: Cannot read properties of undefined (reading 'access_token') at EspnHandler.<anonymous> (/app/services/espn-handler.ts:763:38) at Generator.next (<anonymous>) at fulfilled (/app/services/espn-handler.ts:5:58) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5) TypeError: Cannot read properties of undefined (reading 'assertion') at EspnHandler.<anonymous> (/app/services/espn-handler.ts:829:46) at Generator.next (<anonymous>) at fulfilled (/app/services/espn-handler.ts:5:58) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5)

    opened by BluchipStudio 8
  • Upgrade playwright to latest  version; add docker-compose; switch browser to firefox

    Upgrade playwright to latest version; add docker-compose; switch browser to firefox

    For some background, my goal was to run this docker container on a 64-bit Raspberry Pi 4. However, the original image (playwright 1.15) doesn't have an arm64 image available.

    I originally switched to a generic arm64 base image and manually installed playwright. However, I quickly realized that MS added arm64 support in playwright v1.17

    I also had to switch the browser used from chrome to firefox. playwright doesn't offer any chrome builds from arm64 to use with browser install. Next, I tried base chromium, but that didn't work on my rpi4. Finally, I tried firefox, which does have arm64 builds, and everything works as expected.

    So far, I tested these changes on:

    • 64-bit rpi4
    • Chromebook

    I haven't tested on x86_64, but I assume everything should work as expected. I'm not sure exactly what changes are needed, but I think you will need to modify your github action to build/push the image for multiple architectures: https://pet2cattle.com/2021/09/build-multiarch-container-github-action

    Until you push new images, you won't be able to pull images from Docker Hub for arm64.

    opened by nkm8 6
  • Getting a failed to parse stream

    Getting a failed to parse stream

    Running in docker on linux. I get the following when trying to launch a stream

    There is an active event. Going to start the stream. Getting stream for event: ca34ba2a-8324-479c-9df5-e67e500639bb Failed to parse the stream

    Any thoughts? I put the container in privileged mode just in case and am still seeing it. Any thoughts?

    opened by ssimpson89 6
  • [Enhancement Requests] - stream origin, filter by sport, Fox Sports integration

    [Enhancement Requests] - stream origin, filter by sport, Fox Sports integration

    Hello -

    Thank you for this software! I have three requests:

    1. Can we have an option to see the source of the stream in the title (ESPN+/ESPN3, other future ESPN streams). I notice that the ESPN3 streams don't always work and I'd like to easily identify which streams come from where.

    2. Can we have a way to filter by sport? For example, I'm typically interested in college football, college basketball and college hockey.

    3. Any chance to add Fox Sports digital streams to this?

    I'm using this software through tvheadend and it's really neat!

    opened by lionsnob 4
  • Failed to parse Stream on Active Event

    Failed to parse Stream on Active Event

    ` Server started on port 8000

    There is an active event. Going to start the stream.

    Getting stream for event: 9a046ce9-abe4-4319-a596-9a66e0a8d8f8

    Failed to parse the stream

    Failed to parse the stream

    There is an active event. Going to start the stream.

    Getting stream for event: 9a046ce9-abe4-4319-a596-9a66e0a8d8f8`

    Screen Shot 2022-05-02 at 10 45 13 AM
    opened by McPeebs 4
  • First Time Setup Question w/xTeVe & Plex + unRaid

    First Time Setup Question w/xTeVe & Plex + unRaid

    Hello!

    First off thanks for the very awesome sounding piece of software. I've been running into a bit of an issue on I believe the final steps to get everything working.

    My setup is currently entirely in unRaid

    EPlus seems to be up and running fine "Server started on port 8000" I then added the address http://10.0.1.98:8000/channels.m3u to xTeVe which came up showing 100 streams. Followed the same steps for XMLTV with xTeVe entering http://10.0.1.98:8000/xmltv.xml

    On Plex I then added my xTeVe tuner which properly showed my newly assigned channels.

    However when I go to access the channel I receive an error statingCould not tune channel. Please check your tuner or antenna. From xTeVe logs I see: EPlusTV 9 [xTeVe] Client User-Agent: Lavf/LIBAVFORMAT_VERSION [xTeVe] Streaming URL: http://10.0.1.98:8000/channels/9.m3u8 [xTeVe] Streaming Info: URL was passed to the client. [xTeVe] Streaming Info: xTeVe is no longer involved, the client connects directly to the streaming server.

    Navigating to http://10.0.1.98:8000/channels/9.m3u8 I do get a clip that can be opened within VLC but no luck connecting via Plex.

    Appreciate any tips to over come this final hurdle. Let me know if there are any additional details I can provide. Thanks

    opened by ConnorEMacLean 3
  • Added server port env variable

    Added server port env variable

    Allows you to specify a custom port on the docker container (it would be the right-hand-side of the port mapping). I needed this because I want to route this container's traffic through gluetun and port 8000 is already taken.

    opened by reeseovine 3
  • Differentiate local streams

    Differentiate local streams

    Thanks for this, it has been working great so far with Channels!

    I'm watching Hockey, which generally has two streams for each game (with the local team's announcers and graphics). Right now, I don't see any way to filter to my team's broadcast based on data in the xmltv file. Any chance we could parse that data while generating the listings?

    opened by PaulMcMillan 2
  • Disabling ESPNPLUS With Any Other Channel Enabled Crashes Container

    Disabling ESPNPLUS With Any Other Channel Enabled Crashes Container

    Whenever you disable ESPNPLUS but enable other channels such as ESPN on first run, it allows you to authenticate with a TV Provider but then crashes. Nothing is in the log when it crashes. When you re-enable ESPNPLUS, it has you authenticate for ESPN+ and then it works.

    > [email protected] start
    > ts-node index.ts
    
    :: TV Provider Auth ::
    Please open a browser window and go to: https://www.espn.com/watch/activate
    Enter code:  xxxxxx
    App will start when login has completed...
    
    > [email protected] start
    > ts-node index.ts
    

    EDIT: I will also note, when you re-enable ESPNPLUS, you cannot watch your ESPN stream.

    opened by thompatry 2
  • Streams freezing a jittery

    Streams freezing a jittery

    streams are working but seems very jittery and freeze often anyway to improve this

    i have it on an 19 with nvidea 2060 super and 32 gb ram with a 1gbps fiber line i tested the website and it plays fine

    opened by Rob2k9 2
  • [Enhancement] Off Air for EPG

    [Enhancement] Off Air for EPG

    Would it be possible to add a option to have the EPG to show Off Air or something to show that the ESPN+ channel is empty instead of the guide just being empty?

    opened by GameEnder 4
Releases(v2.0.0-beta.13)
  • v2.0.0-beta.13(Jan 4, 2023)

  • v2.0.0-beta.12(Jan 3, 2023)

    What's changed?

    • No longer using ffmpeg to replay the stream by reading the manifests and segments from the hard drive. I wrote an HLS proxy that will handle parsing the master playlist and selecting the appropriate chunklist and proxying requests for the segments and saving them in memory. This change should increase speed to start stream and performance while it's playing.
    • Fixed error on some ESPN events not starting streams properly
    • Added NBC Sports as a new provider
    • Added a check to see if FOX Sports token is expired. If it is, it will kill the server. This is a workaround until I can figure out how to renew the authn token from Adobe
    • Added a MAX_RESOLUTION environment variable
    • Cleaned up unneeded environment variables
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.9(Dec 13, 2022)

    What's new?

    • Added Longhorn Network as an option
    • Added support for FOX Streams to get 4K HDR streams

    What's fixed?

    • There was an issue where I was needlessly checking for certain CDNs for playback on FOX events and certain events weren't using those CDNs
    • Scheduler will now pick up sporting events that are on regular FOX network
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.10(Dec 13, 2022)

  • v2.0.0-beta.8(Dec 12, 2022)

  • v2.0.0-beta.7(Dec 5, 2022)

    What's new?

    • Added information about what network an event is on to the event title in EPG (if more than one provider is set)
    • Added home broadcast information to event title in EPG (if provided)

    What's fixed?

    • Fixed issue with ESPN+ being disabled #34
    • Hopefully fixed issue with ESPN streams not working because of TV provider differences
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.6(Nov 25, 2022)

    What's new?

    • Added support for TV Provider login. This will allow users to select events from other ESPN offerings. Please see README for how to use!
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.5(Nov 16, 2022)

  • v2.0.0-beta.4(Nov 8, 2022)

    What's new?

    • Moved to a patched version of ffmpeg that supports HLS EXT-X-DISCONTINUITY tags
    • Added rtbufsize and hls_time arguments for ffmpeg
    • Fixed folder permission issues by allowing users to pass in PUID and PGID arguments
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.3(Nov 3, 2022)

  • v2.0.0-beta.2(Nov 2, 2022)

    What's new?

    • Removed Streamlink dependency and now only using ffmpeg (Thanks for the suggestion @BluchipStudio)
    • Added STREAM_RESOLUTION environment variable. Will allow users on slower connections to not have as much buffering
    • Changed token refresh schedule to avoid race condition
    • Added User Agent switching
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.1(Oct 5, 2022)

    What's new?

    This is a major shift for how the app works. Gone are the days of passing in USERNAME and PASSWORD variables, and having a Chrome browser attempt to login and the sniff out the correct data. Now we're using proper APIs to get the stream data much faster and reliably. Another nice improvement is since we're no longer relying on trying to load a Widevine stream in Chrome, there are now containers available for multiple platforms!

    Source code(tar.gz)
    Source code(zip)
  • v0.9.6(Sep 12, 2022)

  • v0.9.5(Apr 19, 2022)

  • v0.9.4(Apr 19, 2022)

  • v0.9.3(Apr 19, 2022)

  • v0.9.2(Apr 18, 2022)

    What's fixed?

    • Login flow/getting stream credentials should be faster, more reliable, and more streamlined
    • Getting live and scheduled events should be faster, more reliable, and more streamlined
    • Defaulting to 720p 60fps streams now #17
    • Hopefully cleaning up orphaned Chrome processes now #16
    • Fixed issue where sometimes an m3u8 file would be orphaned after a channels ts files had been cleaned out
    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Feb 18, 2022)

Owner
Joe Ipson
Joe Ipson
Convert a CSS linear gradient function to expo-linear-gradient props

@bacons/css-to-expo-linear-gradient Demo: snack Convert a CSS linear gradient function to expo-linear-gradient props. Add the package to your npm depe

Evan Bacon 15 Dec 15, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Material Progress —Google Material Design Progress linear bar. By using CSS3 and vanilla JavaScript.

MProgress.js Google Material Design Progress Linear bar. It uses CSS3 and vanilla JavaScript which doesn't depend on any other libraries. Types and pr

gc 1.5k Nov 30, 2022
WebGL-accelerated ML // linear algebra // automatic differentiation for JavaScript.

This repository has been archived in favor of tensorflow/tfjs. This repo will remain around for some time to keep history but all future PRs should be

null 8.5k Dec 31, 2022
Chart.js plugin to calculate and draw statistical linear, exponential, power, logarithmic, and polynomial regressions.

chartjs-plugin-regression Chart.js plugin to calculate and draw statistical linear, exponential, power, logarithmic, and polynomial regressions using

Wilfredo Pomier 14 Dec 18, 2022
Linear Regression library in pure Javascript

Lyric Linear Regression library in pure Javascript Lyric can help you analyze any set of x,y series data by building a model that can be used to: Crea

Flurry, Inc. 43 Dec 22, 2020
This project is an attempt at recreating the WebGL animation featured in the 2021 Linear release page.

Linear Vaporwave Three.js scene This project is an attempt at recreating the WebGL animation featured in the 2021 Linear release page. Demo Head over

Maxime Heckel 31 Dec 28, 2022
End-to-End sync Linear.app and GitHub

Initially created by Spacedrive, now maintained by Cal.com and Neat.run Linear to GitHub Sync This is a system to synchronize Linear issues to GitHub

Cal.com, Inc. 87 Jan 3, 2023
CSP channels for Javascript (like Clojurescript's core.async, or Go) THIS IS AN UPSTREAM FORK

js-csp Communicating sequential processes for Javascript (like Clojurescript core.async, or Go). Examples var csp = require("js-csp"); Pingpong (porte

James Long 283 Sep 22, 2022
Lightweight WebSocket lib with socket.io-like event handling, requests, and channels

ws-wrapper Lightweight and isomorphic Web Socket lib with socket.io-like event handling, Promise-based requests, and channels. What? Much like Socket.

Blake Miner 70 Dec 23, 2022
App that allows you to control and watch YouTube videos using hand gestures. Additionally, app that allows you to search for videos, playlists, and channels.

YouTube Alternative Interaction App An app I made with Edward Wu that allows you to search and watch videos from YouTube. Leverages Google's YouTube D

Aaron Lam 2 Dec 28, 2021
A web app for seeing your recent Twitch chat mentions and/or other tracked words amongst channels you follow.

Mentions A web app for seeing your recent Twitch chat mentions and/or other tracked words amongst channels you follow. Requirements NodeJS. Client ID

Ravenbtw 3 Dec 22, 2022
🚀 Blazing fast thread channels integration for all Discord.js versions

djs-threads ?? Blazing fast thread integration for all Discord.js versions ?? THIS PROJECT IS ARCHIVED this project is archived because Discord will c

SpongeBed 4 Feb 28, 2022
A NodeJS package for voice channel interactions on Revolt. This package lets you join voice channels, play music and more!

Revoice.js - A Voice Module for Revolt This package is still in developement and lacks many features. You still are able to play sound to a voice chan

ShadowLp174 13 Dec 25, 2022
The simplest implementation of Golang channels, selects and wait groups

TypeScript Channels The simplest implementation of Golang channels, selects and wait groups Installation You can use one of the following package mana

Dimitar Ruskov 9 Dec 8, 2022
Displays all hidden Channels, which can't be accessed due to Role Restrictions, this won't allow you to read them (impossible)

Who is the Creator ? The creator of this plugin is DevilBro I have completely reworked the plugin so that it can use the BDFDB library from DevilBro !

Flavien 18 Dec 29, 2022
Displays all hidden Channels, which can't be accessed due to Role Restrictions, this won't allow you to read them (impossible)

ShowHiddenChannels Plugin Returns DevilBro, author of this plugin, and BetterDiscord developers have deleted ShowHiddenChannels plugin from the offici

NotCapengeR 177 Sep 17, 2022