FastChannels - FAST Channels aggregator/manager

IMPORTANT UPDATE

  1. Plex is doing something funny. It's creating duplicate channels and EPG isn't working. I suspect API changed.

  2. The upstream data we use for Samsung TV+ is down at the moment. I don't have a workaround currently short of matching all the Channels to Gracenote. I think I have a lead on this ...

I'm working on Plex now and hopefully I can figure it out and get a hotfix out.

2 Likes

This post did not age well :upside_down_face:

lol it’s all your fault!

edit: oops, spun up a second channels by accident instead of fast channels.

ok, im a doofus, i forgot the fix the data directory to my docker subdirectory.

and now of course now i see the db file.

now back to our regularly scheduled portainer struggle...

of course now replacing the db file bombs out the new container because my original fastchannels db is out of date and i cant get into my original portainer to update it.

if it isnt one thing, its another..

hmm....i got them both to the same version, but replacing the fastchannels.db bombs out the new container.

There are both on 3.9.0

heres the log

   ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 122, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 176, in _do_get
    return self._create_connection()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 389, in _create_connection
    return _ConnectionRecord(self)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 674, in __init__
    self.__connect()
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 914, in __connect
    )._exec_w_sync_on_first_run(self.dbapi_connection, self)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 502, in _exec_w_sync_on_first_run
    self(*args, **kw)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 516, in __call__
    fn(*args, **kw)
  File "/app/app/__init__.py", line 68, in _set_sqlite_pragmas
    dbapi_conn.execute("PRAGMA journal_mode=WAL")
sqlite3.DatabaseError: database disk image is malformed

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/app/app/__init__.py", line 74, in create_app
    db.create_all()
  File "/usr/local/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 900, in create_all
    self._call_for_binds(bind_key, "create_all")
  File "/usr/local/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 881, in _call_for_binds
    getattr(metadata, op_name)(bind=engine)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/sql/schema.py", line 5930, in create_all
    bind._run_ddl_visitor(
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3269, in _run_ddl_visitor
    with self.begin() as conn:
         ^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3259, in begin
    with self.connect() as conn:
         ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3295, in connect
    return self._connection_cls(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 146, in __init__
    Connection._handle_dbapi_exception_noconnection(
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 2450, in _handle_dbapi_exception_noconnection
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 144, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3319, in raw_connection
    return self.pool.connect()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 448, in connect
    return _ConnectionFairy._checkout(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 1272, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 712, in checkout
    rec = pool._do_get()
          ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 178, in _do_get
    with util.safe_reraise():
         ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 122, in __exit
__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 176, in _do_get
    return self._create_connection()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 389, in _create_connection
    return _ConnectionRecord(self)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 674, in __init__
    self.__connect()
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 914, in __connect
    )._exec_w_sync_on_first_run(self.dbapi_connection, self)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 502, in _exec_w_sync_on_first_run
    self(*args, **kw)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 516, in __call__
    fn(*args, **kw)
  File "/app/app/__init__.py", line 68, in _set_sqlite_pragmas
    dbapi_conn.execute("PRAGMA journal_mode=WAL")
sqlalchemy.exc.DatabaseError: (sqlite3.DatabaseError) database disk image is malformed
(Background on this error at: https://sqlalche.me/e/20/4xp6)
πŸš€ Starting FastChannels...
βœ… Redis started
⏳ Waiting for Redis...
βœ… Redis ready
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 144, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3319, in raw_connection
    return self.pool.connect()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 448, in connect
    return _ConnectionFairy._checkout(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 1272, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 712, in checkout
    rec = pool._do_get()
          ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 178, in _do_get
    with util.safe_reraise():
         ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 122, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 176, in _do_get
    return self._create_connection()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 389, in _create_connection
    return _ConnectionRecord(self)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 674, in __init__
    self.__connect()
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 914, in __connect
    )._exec_w_sync_on_first_run(self.dbapi_connection, self)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 502, in _exec_w_sync_on_first_run
    self(*args, **kw)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 516, in __call__
    fn(*args, **kw)
  File "/app/app/__init__.py", line 68, in _set_sqlite_pragmas
    dbapi_conn.execute("PRAGMA journal_mode=WAL")
sqlite3.DatabaseError: database disk image is malformed

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/app/app/__init__.py", line 74, in create_app
    db.create_all()
  File "/usr/local/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 900, in create_all
    self._call_for_binds(bind_key, "create_al
l")
  File "/usr/local/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 881, in _call_for_binds
    getattr(metadata, op_name)(bind=engine)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/sql/schema.py", line 5930, in create_all
    bind._run_ddl_visitor(
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3269, in _run_ddl_visitor
    with self.begin() as conn:
         ^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3259, in begin
    with self.connect() as conn:
         ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3295, in connect
    return self._connection_cls(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 146, in __init__
    Connection._handle_dbapi_exception_noconnection(
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 2450, in _handle_dbapi_exception_noconnection
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 144, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3319, in raw_connection
    return self.pool.connect()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 448, in connect
    return _ConnectionFairy._checkout(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 1272, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 712, in checkout
    rec = pool._do_get()
          ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 178, in _do_get
    with util.safe_reraise():
         ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 122, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 176, in _do_get
    return self._create_connection()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 389, in _create_connection
    return _ConnectionRecord(self)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 674, in __init__
    self.__connect()
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 914, in __connect
    )._exec_w_sync_on_first_run(self.dbapi_connection, self)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 502, in _exec_w_sync_on_first_run
    self(*args, **kw)
  File "/usr/local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 516, in __call__
    fn(*args, **kw)
  File "/app/app/__init__.py", line 68, in _set_sqlite_pragmas
    dbapi_conn.execute("PRAGMA journal_mode=WAL")
sqlalchemy.exc.DatabaseError: (sqlite3.DatabaseError) database disk image is malformed
(Background on this error at: https://sqlalche.me/e/20/4xp6)

Hate to suggest it, but you may need to start fresh….

that would suck, it took me hours to set up all the feeds.

Can you post the docker run command or yaml you used to originally setup FastChannels, and the same for your new setup?

There's more than just fastchannels.db in my Docker/Portainer Volume:

i used neither completly

I couldnt get yaml to work (it didnt like my volumes, and i couldnt figure out how to fix them) and i used your docker run command in the first post to create the image but didnt modify the volumes in the command so i deleted the container and used the app to recreate it with the correct volumes.

i created the final containers through docker desktop (windows)/docker app (ugreen)

ill try replacing them all now just for funzies...

edit: ooff, this might take a bit, there is 19000 files in the data directory....

Those cache directories do have a lot of files, but I believe they're fairly small. The files, not including those cache subdirectories, are likely the most important.

yeah, the ugreen no likey small files...its poking along at 12KBps

and thats to an internal nvme over a 2.5gbe connection, not the rust spinners...

it must be doing something to process them as they get written.

i did drag and drop to the ugreen app rather than ssh, so perhaps there is a buffering issue somewhere. it went pretty fast when i added all my large media files to rust spinners.

i guess this is why. should have zipped it first and unzipped on the nas.

"If transferring thousands of tiny documents, photos, or code snippets, your file transfers will drop to a crawl. Every single file requires its own system overhead (checking permissions, locating disk space), overwhelming the system's input/output."

yup, that was stupid. over 2 hours and only 75%

just zipped it transferred it up, and decompressed in less than a minute....

New version pushed - 4.0.0

New Sources

  • Frndly TV β€” live TV scraper with targeted EPG enrichment; requires credentials; disabled by default (Premium badge)
  • Fubo TV FAST β€” has access to most premium channels, but also their FAST channels. Credentials required, but if you sign up for a trial account then cancel, it gives you choice to downgrade to free FAST channels.

Plex Fixes

  • Fixed duplicate channels caused by server-prefix rotation β€” deduplicates on boot and carries forward the active stream URL
  • Fixed dead EPG endpoint β€” updated to current API
  • Fixed channels with no category β€” name-inference fallback now consults the full override table (this release)

Pluto TV

  • Re-exposed the local region selector in the UI (had been hidden); local region sorts to the bottom of the list

Stream Audit / Playback

  • Fixed DRM false positive for CMAF multi-DRM streams β€” Widevine+SAMPLE-AES combos no longer wrongly marked as DRM-only
  • WURL DRM channels now rejected at resolve time instead of silently failing
  • 5xx CDN errors during stream audit treated as transient (not permanent dead)

Admin / UI

  • DB restore-from-backup endpoint and UI page
  • Stream preview in the custom channel editor
  • Channels DVR push: test connection button, better error UX
  • Dead channel modal: option to delete when the scraper has also lost the channel

Bug Fixes

  • ~60 Fubo category overrides corrected across all content types
  • Several smaller category overrides
  • Favicon added; noisy health-check endpoints suppressed from access logs
3 Likes

edit: i hosed the copy. retrying.

ok, that worked. had to restart the container a couple times. it coulnd find the network on initial startup, but on a restart it found it.

1 Like

any way to add a dynamic list of enabled, but unassigned sources to the feed screen?

with so many sources, and more coming all the time, its hard to keep track of what i have and havent added to the feeds.

On the Channels tab, click the drop down for Feeds...