Coder Social home page Coder Social logo

chrisbenincasa / tunarr Goto Github PK

View Code? Open in Web Editor NEW
29.0 5.0 6.0 100.33 MB

Spiritual successor to dizqueTV

Home Page: https://tunarr.com/

License: zlib License

JavaScript 0.16% Dockerfile 0.41% CSS 0.18% TypeScript 99.22% HTML 0.03%
ffmpeg iptv local-streaming media-streaming plex self-hosted streaming tv

tunarr's Introduction

Tunarr

Create live TV channels from media on your Plex servers, and more!

Configure your channels, programs, commercials, and settings using the Tunarr web UI.

Access your channels by adding the spoofed Tunarr HDHomerun tuner to Plex, Jellyfin, or Emby. Or utilize the m3u Url with any 3rd party IPTV player app.

Disclaimer

  • ⚠️ Tunarr is under very active development.
  • ⚠️ Expect bugs and breaking changes!
  • ⚠️ We are certain there are bugs, given the scale of this rewrite.
  • ⚠️ At this point, we do NOT recommend replacing dizqueTV with Tunarr!
    • If you would like to try Tunarr, make sure to use a copy of your .dizquetv database folder!

What is this?

Tunarr is a fork / rewrite / rebrand of dizqueTV (which in itself was a fork of other projects!). This project was born out of both a love for TV and an appreciation for the work put into dizqueTV and its predecessors.

Tunarr has the following goals:

  • Modernize the stack, both backend and frontend
  • Provide an migration path for existing users
  • Stabilize the program, fix bugs, and improve performance
  • Modernize and "prettify" the Web UI
  • And of course, Add a ton great new features!

Features

  • "Spoofing" HDHR tuner and a IPTV channel list, providing a large amount of flexibility
  • Ease of setup for xteve and Plex playback by mocking a HDHR server.
  • Configure your channels once, and play them just the same in any of the other devices.
  • Customize your channels and what they play. Make them display their logo while they play. Play filler content ("commercials", music videos, prerolls, channel branding videos) at specific times to pad time.
  • Docker image and prepackage binaries for Windows, Linux and Mac.
  • Supports Nvidia for hardware encoding, including in Docker.
  • Select media (desired programs and commercials) across multiple Plex servers
  • Includes a WEB TV Guide where you can even play channels in your desktop by using your local media player.
  • Subtitle support.
  • Auto deinterlace any Plex media not marked "scanType": "progressive"
  • Can be configured to completely force Direct play, if you are ready for the caveats.
  • NEW Stream your channels directly in the browser using HLS (and soon MPEG-DASH)
  • NEW Dark mode!

Limitations

  • If you want to play the TV channels in Plex using the spoofed HDHR, Plex pass is required.
  • Like dizqueTV, Tunarr does not currently watch your Plex server for media updates/changes. You must manually remove and re-add your programs for any changes to take effect. Same goes for Plex server changes (changing IP, port, etc).. You'll have to update the server settings manually in that case. NOTE This feature is actively under development!
  • Most players (including Plex) will break after switching episodes if video / audio format is too different. Tunarr can be configured to use ffmpeg transcoding to prevent this, but that costs resources.

Releases

Wiki

  • For setup instructions, check the wiki

Development

pnpm and turbo are used for package management and development. More details on the development environment, setup, and contributing to come!

Start dev servers

Run from the root of the project:

pnpm turbo dev

License

  • The original dizqueTV is released under zlib license (c) 2020 Victor Hugo Soliz Kuncar: we've kept this.

tunarr's People

Contributors

benmcmath avatar boioboi16 avatar cbarbara avatar chrisbenincasa avatar defendore avatar dependabot[bot] avatar flying-sausages avatar jasongdove avatar jordankoehn avatar markdavella avatar mcclouds avatar powdermilkman avatar rafaelvieiras avatar spruceb avatar timebomb avatar timebomb0 avatar vexorian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tunarr's Issues

Add Plex request cache to backend

We should periodically cache results from Plex on the backend to reduce latency. The backend as a Plex proxy endpoint that we forward requests through.

Alternatively we could do this on the frontend with react-query and use the plex 'key' as part of the query key.

Precalculate millis offsets for channel lineup

Many times we need to calculate the 'offsets' to determine the timestamp of when a particular program begins relative to channel start time. This involves a loop where we continuously add the duration of a lineup item to a running total while keeping all intermediate results (generally called a 'scan', e.g. in Scala)

We can do this work upfront when generating lineup json files and return the offset array if necessary. Then, determining start time would be as simple as looking up the millis offset in the array of numbers (indexes between lineup items and offsets match) and then adding that offset to any timestamp.

Dynamic channels

Basic idea:

  • Configure some sort of "live" query
    • Ex: Items in collection
    • Ex: Plex search terms
    • Ex: Simply saying "sync" on a given TV show
  • Periodically scan Plex for new content and auto-add this content to an existing channel
  • Recalculate the schedule when new content added

Channel lineup converted to single flex program

This may just be a fragment of a recent update that won't happen again in the future, but just documenting here in case it's not. After the recent update this morning my initial channel ("Channel 1") had its lineup and programming replaced in the guide with a single Flex item. Screenshots below, you can see that the programming still exists on the channel itself but the guide is only returning a single flex item.

Guide showing Flex item (console log showing channelLineup):
image

Programming within the channel itself:
image

Plex Meta Manager webhook support

This goes along with dynamic channels - we could expose PMM webhooks to listen for updates to collections, etc and subsequently update channels

Programming editor state issues

Some running issues in programming state:

  • Adding programs in editor, navigating to time slot editor, then going back, sometimes clears programs

Guide page incorrectly rounding program pct

The guide page is currently dropping the decimal places when rounding each program % width. It's not really noticeable until you start zooming out. See "bluey" channel below. With so many episodes that rounding issues start to add up and it becomes visibily noticeable.

image

What happens when programming is updated while stream is active?

I've been wondering this for a while. Regenerating the lineup and guide is not something to new to this rewrite. If we start a stream and then start editing the channel, what happens to that stream??

My guess is that the current program may continue through but then the next slot might start a new program halfway through or something. Let's look into this and also brainstorm what acceptable behavior would be

Channel name changes not propagating to lineups API

I changed the names for channels 2 and 3 and they display correctly on the channels page:
image

However, if I navigate to the guide page, I can see the old names:
image

I confirmed that these are both being served up by the API, so it doesn't look like a state issue. I also went incognito and refetched the queries so it doesn't seem like a React Query cache issue.

Confirmed data is in the DB correctly:
image

Maybe some DB cache issue?

Add Plex Button to upcoming Guide Modal

My next PR will include a modal on the guide page. Creating this to track adding in the Plex button to access the program via Plex.

image

Example of data currently available

0: 
date: "2003-06-05"
duration: 6454864
id: "f3284d16-d0ed-44b7-9bad-c14382e2656f"
persisted: true
rating: "PG-13"
start: 1707657955296
stop: 1707664410160
subtype: "movie"
summary: "EX LAPD cop Brian O'Conner (Paul Walker) teams up with his ex-con friend Roman Pearce (Tyrese Gibson) and works with undercover U.S. Customs Service agent Monica Fuentes (Eva Mendes) to bring Miami-based drug lord Carter Verone (Cole Hauser) down."
title: "2 Fast 2 Furious"
type: "content"
uniqueId: "f3284d16-d0ed-44b7-9bad-c14382e2656f"

Example Plex URL of 2Fast2Furious:
http://192.168.1.16:32400/web/index.html#!/server/12c1dd6fd946e3fa810eb754ecc2efc77a6012d9/details?key=%2Flibrary%2Fmetadata%2F2

Add Error Handling for Plex Connection

"Add Programming" page currently does not load if Plex is not connected. There are no errors or messaging to indicate the cause so a.) if the user never connected Plex or b.) their Plex connection is destroyed for some reason, the user may not know the cause.

Add messaging to indicate that Plex needs to be connected in order to Add Programming

Ability to choose which Plex video stream to use

It currently chooses the first found video stream, but many people keep multiple versions of the same video file. We should add the choice to configure which file is used

Better yet, we could attempt to be smart and choose the "best" file based on current transcode settings in order to minimize the need to transcode, if possible.

Possibly related to: vexorian/dizquetv#445

Creating a new channel is currently broken

Repro steps:
1.) Navigate to channels tab
2.) Click "new" to add a new channel
3.) Click "Save"

Results:
Nothing seems to happen when you click Save. If you then navigate to any other tab you get stuck as optional fields appear to be marked as required. There is no save button and you cant navigate away.

When you click save there is an object for the new channel in the console log but now new channel created

image image

Style Guide Page

Current design:
image

Note to self: I've seen some users on reddit with upwards of 100 channels. Do testing to make sure high usage edge cases look good and feel snappy too.

Consolidate settings API endpoints into one

Not sure we need separate endpoints for every settings type

we should include the type of settiings we're updating in the API body and just have a single endpoint for settings

Media detail page

Click on a media item in the edit view and you get a preview of the item with the ability to edit details about it

Detect browser wakeup and re-fetch

When I open my laptop in the morning my guide page typically looks like this:
image

If I stay on the page it just stays like this. We coulddddd use the existing setInterval on the page to store the last time setInterval ran, then compare it to the current time and if its more than an hour we do a refetch.

Need to think on a good solution here but it would be nice for it to work when:
1.) User re-opens their laptop after a long while
2.) If the guide page stays open for hours, it continually refreshes the guide page. This would allow some users to have a dedicated "guide" screen if they wanted.

Existing Channel Info pre-populating fields on channel creation

Logging this so I remember to look into this more. Noticed that new channel fields will sometimes pre-populate with existing channel data.

Guide showing channel 3 has already been created:
image

New Channel fields pre-populated with channel 3 but take note of the "channel 4" at the top:
image

Deleting programs in config page on large lineups is really slow

Profiling shows a few things:

  1. Lots of time spent setting the new store state (recreating / slicing the huge list)
  2. Lots of time recalculating the start times of the new programs (ChannelProgrammingList)

We can start with #2 - we don't need to use dayjs addition here, we're just dealing with numbers. Add the numbers and lazily allocate dayjs objects, to start

Rework Plex server deletion

Right now, we have ported old code to handle Plex server deletion. This goes through and removes all of the associated programs that came from the server being deleted. We should probably continue doing this (or perhaps soft delete these items). We also need to go through the lineup JSON files and remove the defunct IDs, otherwise the guide service is gonna have a bad time.

UNIQUE CONSTRAINT db upsert failure when updating channel programs

previous SqliteError: insert into `program` (`created_at`, `duration`, `episode`, `external_key`, `external_source_id`, `file_path`, `grandparent_external_key`, `parent_external_key`, `plex_file_path`, `plex_rating_key`, `show_title`, `source_type`, `summary`, `title`, `type`, `updated_at`, `uuid`) select 1707049284592 as `created_at`, 450838 as `duration`, 1499 as `episode`, '/library/metadata/20318' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e01499 - 🎄 Christmas for kids! Cutting tree, decorating, gingerbread, holiday lights | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20389/1697234134/file.mp4' as `plex_file_path`, '20318' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 1499' as `title`, 'episode' as `type`, 1707049284592 as `updated_at`, '4f595a34-3b66-48ad-9013-403e214e4b54' as `uuid` union all select 1707049284593 as `created_at`, 189056 as `duration`, 2199 as `episode`, '/library/metadata/20319' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e02199 - Tow truck tug of war challenge and power wheels tug of war tournament. How traction works | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20390/1697234082/file.mp4' as `plex_file_path`, '20319' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 2199' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, '0ef0a5a3-60d8-48f6-b3de-efdcc96ce1ac' as `uuid` union all select 1707049284593 as `created_at`, 360373 as `duration`, 2899 as `episode`, '/library/metadata/20320' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e02899 - Tow truck rescue with kids ride on toy truck and tractor. Educational how winches work | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20391/1697234042/file.mp4' as `plex_file_path`, '20320' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 2899' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, '2b73eb08-403b-4158-9e64-9881b2cb0272' as `uuid` union all select 1707049284593 as `created_at`, 322339 as `duration`, 3599 as `episode`, '/library/metadata/20321' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e03599 - Airplanes for kids with pretend play in a real cockpit. Educational how planes fly | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20392/1697233992/file.mp4' as `plex_file_path`, '20321' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 3599' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, '41f3ab1c-9c10-4798-a516-85c2ebe0301b' as `uuid` union all select 1707049284593 as `created_at`, 360443 as `duration`, 4299 as `episode`, '/library/metadata/20299' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e04299 - Helping farm animals with kids toy truck and tractor. Educational how milking cows work | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20371/1697233951/file.mp4' as `plex_file_path`, '20299' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 4299' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, '5a76c403-e409-443a-b97e-415da365bddf' as `uuid` union all select 1707049284593 as `created_at`, 480629 as `duration`, 5099 as `episode`, '/library/metadata/20300' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e05099 - Caring for chickens with kids ride on truck, collect eggs, feed. Educational cooking eggs | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20372/1697233888/file.mp4' as `plex_file_path`, '20300' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 5099' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, '3f5c331e-6bd3-4ace-b33d-1512fde047ff' as `uuid` union all select 1707049284593 as `created_at`, 607991 as `duration`, 5799 as `episode`, '/library/metadata/20301' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e05799 - Camping adventure in Power Wheels RV, roof tent on Barbie car Dream Camper, campfire | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20373/1697233831/file.mp4' as `plex_file_path`, '20301' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 5799' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, '49ebcd1b-71c8-4e9b-9371-3b5e72f657d6' as `uuid` union all select 1707049284593 as `created_at`, 360280 as `duration`, 6499 as `episode`, '/library/metadata/20302' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e06499 - Harvesting vegetables from the garden with kids tractor. Educational how greenhouses work | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20374/1697233758/file.mp4' as `plex_file_path`, '20302' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 6499' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, '22398d53-a5aa-4e05-864f-9a6551277845' as `uuid` union all select 1707049284593 as `created_at`, 265032 as `duration`, 7799 as `episode`, '/library/metadata/20303' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e07799 - Fixing our ride on power wheels 1 8V toy truck. Educational how gears work | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20375/1697233696/file.mp4' as `plex_file_path`, '20303' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 7799' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, 'ab60e6dc-2a97-4afd-a1bd-f6df2467fec8' as `uuid` union all select 1707049284593 as `created_at`, 302857 as `duration`, 8499 as `episode`, '/library/metadata/20304' as `external_key`, 'dionysus' as `external_source_id`, '/data/youtube/Kid Crew/Season 2022/s2022.e08499 - Kids use construction vehicles! Educational how excavators ⧸ diggers ⧸ backhoes work | Kid Crew.mp4' as `file_path`, '20297' as `grandparent_external_key`, '20298' as `parent_external_key`, '/library/parts/20376/1697233654/file.mp4' as `plex_file_path`, '20304' as `plex_rating_key`, 'Kid Crew' as `show_title`, 'plex' as `source_type`, '' as `summary`, 'Episode 8499' as `title`, 'episode' as `type`, 1707049284593 as `updated_at`, 'c43a968a-ae02-4b81-ad0c-2d6d7951c8ee' as `uuid` where true on conflict (`uuid`) do update set `created_at` = excluded.`created_at`, `updated_at` = excluded.`updated_at`, `source_type` = excluded.`source_type`, `duration` = excluded.`duration`, `episode` = excluded.`episode`, `file_path` = excluded.`file_path`, `external_source_id` = excluded.`external_source_id`, `external_key` = excluded.`external_key`, `plex_rating_key` = excluded.`plex_rating_key`, `plex_file_path` = excluded.`plex_file_path`, `parent_external_key` = excluded.`parent_external_key`, `grandparent_external_key` = excluded.`grandparent_external_key`, `show_title` = excluded.`show_title`, `summary` = excluded.`summary`, `title` = excluded.`title`, `type` = excluded.`type` returning `original_air_date`, `episode_icon`, `icon`, `rating`, `season`, `season_icon`, `show_icon`, `year`, `custom_order` - UNIQUE constraint failed: program.source_type, program.external_source_id, program.external_key
    at Client_BetterSQLite3._query (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/[email protected][email protected]/node_modules/knex/lib/dialects/better-sqlite3/index.js:39:40)
    at Object.executeQuery (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/[email protected][email protected]/node_modules/knex/lib/execution/internal/query-executioner.js:37:17)
    at Client_BetterSQLite3.Client.query (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@mikro-orm/knex/AbstractSqlConnection.js:199:71)
    at Runner.query (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/[email protected][email protected]/node_modules/knex/lib/execution/runner.js:141:36)
    at ensureConnectionCallback (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/[email protected][email protected]/node_modules/knex/lib/execution/internal/ensure-connection-callback.js:13:17)
    at Runner.ensureConnection (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/[email protected][email protected]/node_modules/knex/lib/execution/runner.js:318:20)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Runner.run (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/[email protected][email protected]/node_modules/knex/lib/execution/runner.js:30:19)
    at async executeQuery.query (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@mikro-orm/knex/AbstractSqlConnection.js:119:25)
    at async BetterSqliteConnection.executeQuery (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/@[email protected]/node_modules/@mikro-orm/core/connections/Connection.js:102:25)
    at async QueryBuilder.execute (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@mikro-orm/knex/query/QueryBuilder.js:601:21)
    at async SqlEntityManager.upsertMany (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/@[email protected]/node_modules/@mikro-orm/core/EntityManager.js:816:21)
    at async SqlEntityManager.upsertMany (/Users/christianbenincasa/Code/projects/dizquetv/node_modules/.pnpm/@[email protected]/node_modules/@mikro-orm/core/EntityManager.js:738:29)
    at async Object.<anonymous> (file:///Users/christianbenincasa/Code/projects/dizquetv/server/api/v2/channelsApiV2.ts:264:32) {
  code: 'SQLITE_CONSTRAINT_UNIQUE',
  errno: undefined,
  sqlState: undefined,
  sqlMessage: undefined,
  errmsg: undefined
}

Unclear why this is happeningn since we should have an ON CONFLICT clause

Hookup 'Delete' Channels

I previously removed the delete icon from the Channels page. It wasn't hooked up to the API yet. Need to add it back and hook it up or add it into the edit screen flow.

Overall the Channel page needs some TLC & decisions re: buttons/icons etc.

Cannot build the frontend without OOM

> @tunarr/[email protected] build /home/christian/code/tunarr/web2
> tsc --noEmit && vite build


<--- Last few GCs --->

[7863:0x6f03c70]    18517 ms: Scavenge 2044.9 (2083.7) -> 2044.1 (2087.9) MB, 5.7 / 0.0 ms  (average mu = 0.296, current mu = 0.332) allocation failure; 
[7863:0x6f03c70]    19091 ms: Mark-sweep (reduce) 2047.7 (2087.9) -> 2046.2 (2083.7) MB, 175.1 / 0.0 ms  (+ 231.9 ms in 53 steps since start of marking, biggest step 4.8 ms, walltime since start of marking 425 ms) (average mu = 0.308, current mu = 0.322) 

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
 1: 0xb87bc0 node::Abort() [node]
 2: 0xa96834  [node]
 3: 0xd687f0 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xd68b97 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xf462a5  [node]
 6: 0xf5878d v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 7: 0xf32e8e v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 8: 0xf34257 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 9: 0xf1542a v8::internal::Factory::NewFillerObject(int, v8::internal::AllocationAlignment, v8::internal::AllocationType, v8::internal::AllocationOrigin) [node]
10: 0x12da78f v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [node]
11: 0x170a079  [node]
 ELIFECYCLE  Command failed with exit code 134.

API does not return programs that started playing before the guide 'start' time

It looks like the API currently returns programs that start between FROM and TO. However, in some cases, like the Bluey episode in the screenshot below, the episode started before the FROM time but ends between FROM and TO. This creates a situation where we don't have the episode to display so the first program is made to look artificially longer than the rest. Even though the missing episode already ended, we should still show it since that time period is visible in the guide.

See first ep of Bluey:
image

Add 'artificial throttling' as an option in config

dizquetv added artificial throttling in several backend services, seemingly because when they ran it would affect the video stream (perhaps when hardware transcoding is not enabled). For folks that are running the new version on beefier machines, or are using hardware transcodings, we shouldn't artificially throttle the backend. We can give them the option of turning this on.

Create Welcome Screen for New Users

Create a welcome screen with a checklist for new users.

Get started with Tunarr:

  1. Connect your Plex account (include direct link to connect it right there)
  2. Create a Channel
  3. Add Programming to a channel

Screen can be manually dismissed or will automatically dismiss when checklist is completed.

The goal here to make a seamless onboarding experience so there is no confusion on what users need to do to get started

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.