DVRDesk a simple Windows and Linux client for Channels

error log

[2026-05-19T02:34:47.620Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T02:39:53.004Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T02:39:54.005Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T02:40:14.812Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T02:44:46.311Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T02:45:14.012Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T02:45:53.013Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T02:46:30.514Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T02:56:28.122Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:04:25.225Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:04:30.917Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:04:31.315Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T03:08:49.618Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:09:21.622Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T03:17:45.415Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:21:05.219Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:23:17.912Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:23:26.710Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T03:23:28.823Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T03:23:32.326Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T03:23:33.526Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T03:23:40.512Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T03:30:42.913Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T04:39:39.933Z] console.error
HLS error: mediaError fragParsingError false url: undefined response: undefined
[2026-05-19T04:42:15.141Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T04:42:34.746Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined
[2026-05-19T04:42:37.248Z] console.error
HLS error: mediaError bufferSeekOverHole false url: undefined response: undefined
[2026-05-19T04:52:07.841Z] console.error
HLS error: mediaError bufferStalledError false url: undefined response: undefined

Like I said, if I delete the CDVR video index it plays fine.

How do you delete the index?

Delete the Metadata/FILE_ID# folder
Metadata/3404 in this case

I reverted to v1.7.0 and same issue.

Have you tried this when playing recordings?
/dvr/files/file#/stream.mpg

Instead of
http://server-ip:port/dvr/files/3404/hls/master.m3u8?encoder=remux

Try
http://server-ip:port/dvr/files/3404/stream.mpg

That may require a different player. Before I look into that, do you know if the "Fix Video Timestamps" command does the job?

It doesn't happen with every recording and I'm not going to run that on my recordings.

I can search here for the few times I did that and it ruined my recordings, like Make backup of recording before rewriting video timestamps

If CDVR doesn't have the video index (because I deleted it) it plays fine in the web UI player and yours.
I'll just delete the video index folders. Probably will setup a cron job for that.

I made a backup copy and then remuxed the recording using ffmpeg which showed no erros.

ffmpeg -ignore_unknown -i %1 -map 0 -acodec copy -vcodec copy -scodec copy "%~dp0%~n1.ts" > "%~n1_remux_log.txt" 2>&1

Input #0, mpegts, from '\\nas-1019\ChDVR8489\TV\Massive Moves\Massive Moves Lottery Lodge 2026-05-18-0428.mpg':
  Duration: 00:27:49.67, start: 0.316733, bitrate: 3772 kb/s
  Program 1 
  Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], Closed Captions, 29.97 fps, 29.97 tbr, 90k tbn
  Stream #0:1[0x102](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 95 kb/s
  Stream #0:2[0x103]: Data: timed_id3 (ID3  / 0x20334449)
  Stream #0:3[0x108]: Data: bin_data (xVTT / 0x54545678)
Output #0, mpegts, to 'T:\skrach\Massive Moves Lottery Lodge 2026-05-18-0428.ts':
  Metadata:
    encoder         : Lavf59.27.100
  Stream #0:0: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 29.97 fps, 29.97 tbr, 90k tbn
  Stream #0:1(und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 95 kb/s
  Stream #0:2: Data: timed_id3 (ID3  / 0x20334449) (default)
  Stream #0:3: Data: bin_data (xVTT / 0x54545678)
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
  Stream #0:2 -> #0:2 (copy)
  Stream #0:3 -> #0:3 (copy)
video:723898kB audio:19566kB subtitle:0kB other streams:36kB global headers:0kB muxing overhead: 3.980067%

Copied the remuxed recording over the original and regenerated the video index and it plays without buffering.

So on the recordings that stall with the buffering, spinning circle.
Either deleting the video index, or remuxing w/ffmpeg and regenerating the video index fixes it.
I don't see issues looking at them with my video editor and no errors from the ffmpeg remux.

I found if I just remux the recording and don't touch the video index that it plays with artifacts, smearing, tearing, macro-blocking, etc. Either deleting the video index or regenerating it cures that. There's something wrong with CDVR and its video index. I wish they would offer a way to play a recording without using the video index.

Until then, I'll setup a cron job to delete the video indexes after they're created.

The app previously known as WinChannels shall henceforth be known as DVRDesk, a native Windows and Linux desktop client application for the Channels DVR server, developed by the Channels Community, and unsupported by Fancy Bits and Channels. Existing repository links will continue to work.

Am I missing a setting, or is this a feature request.

I can see the watched status of my recent recordings in Channels DVR, but in DVRDesk only the partially watched ones show a watched status. Some are also missing the channel logo.

DVRDesk v1.12.0

A handful of bug fixes and search improvements in this release.

Watched status bar fix The progress bar on episode and movie cards, list rows, and the detail pane was only appearing for partially watched content — fully watched items showed nothing. That's fixed. Fully watched items now show a solid green bar at 100%, so you can distinguish "never touched," "in progress," and "finished" at a glance across all views.

Search: watched status filtering The Search page now has a Watched Status filter with four checkboxes — Not watched, Partially watched, Watched, and Include Series — all enabled by default. Uncheck any combination to narrow results. TV Series are controlled independently by the Include Series toggle; the other three checkboxes only affect episodes, movies, and library videos.

Search: watched progress in results table Each search result row now shows a small progress bar in the Type column, directly below the type label (TV Episode, Movie, etc.). It uses the same style as the rest of the app — blue/accent gradient for in-progress, green for fully watched. The Type column is also fixed-width so labels never wrap.

As always, download the latest release from the GitHub releases page. Let me know if you run into anything.

That was a bug! Thanks for reporting, please see the update announcement I just posted.

Thanks!
That took care of the watched status.
I still have some recordings not displaying the channel logo.
When I look at the image url, it's not the same as the one that appears in Channels DVR Recordings.
For instance, this was recorded from Smithsonian Channel

The channel logo image url in Channels DVR is http://192.168.1.4:8089/tmsimg/assets/s58532_ll_h15_aa.png?w=360&h=270 which is the Smithsonian logo

The channel logo image url in DVRDesk is http://192.168.1.4:8089/tmsimg/assets/s82695_ll_h15_ab.png?w=360&h=270 which is a single white pixel (1x1) png image


Screenshot 2026-06-14 125024

From the recorded file json http://192.168.1.4:8089/dvr/files/3488
Airing.Raw.stationId=82695

{
  "ID": "3488",
  "JobID": "1781117940-276",
  "RuleID": "276",
  "GroupID": "25005731",
  "Path": "TV/How Did They Fix That/How Did They Fix That S02E01 2023-07-30 Powerships 2026-06-10-1159.mpg",
  "Checksum": "aSgveOxIh1OTKvxs_fp4jqCw-cWeB74mSMC9E7Etp64",
  "CreatedAt": 1781117940,
  "FileSize": 3979291284,
  "Duration": 3731.807333,
  "Completed": true,
  "Processed": true,
  "Airing": {
    "Source": "tms",
    "Channel": "10123",
    "OriginalDate": "2023-07-30",
    "Time": 1781118000,
    "Duration": 3600,
    "Title": "How Did They Fix That?",
    "EpisodeTitle": "Powerships",
    "Summary": "Mike Davidson heads to Brazil, where an offshore crew is setting up giant power ships.",
    "FullSummary": "Mike Davidson heads to Brazil, where an offshore crew is racing the clock to set up giant power ships to deliver electricity to a country in desperate need.",
    "Image": "https://tmsimg.fancybits.co/assets/p25005731_b_h9_aa.jpg?w=720&h=540",
    "Categories": [
      "Episode",
      "Series"
    ],
    "Genres": [
      "Documentary"
    ],
    "Tags": [
      "HD",
      "Stereo"
    ],
    "SeriesID": "25005731",
    "ProgramID": "EP047817620007",
    "SeasonNumber": 2,
    "EpisodeNumber": 1,
    "ReleaseYear": 2023,
    "ContentRating": "TV-G",
    "Raw": {
      "startTime": "2026-06-10T19:00Z",
      "endTime": "2026-06-10T20:00Z",
      "duration": 60,
      "channels": [
        "10123"
      ],
      "stationId": "82695",

From http://192.168.1.4:8089/dvr/guide/stations

"82695": {
  "type": "Satellite",
  "name": "Smithsonian Network HD (Pacific)",
  "callSign": "SMITHPH",
  "stationId": "82695",
  "bcastLangs": [
    "en"
  ],
  "preferredImage": {
    "uri": "https://tmsimg.fancybits.co/assets/s58532_ll_h15_aa.png?w=360&h=270",
    "height": "270",
    "width": "360",
    "primary": "true",
    "category": "Logo",
    "text": "",
    "tier": ""
  },
  "videoQuality": {
    "signalType": "Digital",
    "videoType": "HDTV",
    "truResolution": "HD 1080i"
  }
},

On second thought that only works for recordings from a channel with a gracenote station ID.
Have to think some more how to handle those channels using non-gracenote ID's to find the channel logo.

I got ahead of myself and pushed before finishing that part. That should be fixed now as well in v1.13. If there actually is no logo to display, it displays the channel number instead. I have a couple of those that are caused by recordings made from channels that I subsequently removed.

1 Like

Awesome. Looking great!

I was wondering about that. I only have HDHomeRun, TVE, and cc4c sources. The cc4c channels are matched to Gracenote, so logos are available for all of those. On the other hand, other sources might not have any kind of logo readily available. How does the Channels client handle it? Maybe it would be useful to have a personal library of logo images? I think the Channels clients could be configured to use that as well...

I know you can create custom channel logos, but not sure how to find those in the API tied to a channel.
I haven't created any.

It appears Channels DVR is using the files json device and channel recorded from

  "ChannelNumber": "10123",
  "DeviceID": "M3U-PrismCastmacmini",

and looking it up in http://192.168.1.4:8089/dvr/guide/channels to get the logo

  "10123": {
    "CallSign": "SMITHPH",
    "Categories": [
      "Documentary"
    ],
    "ChannelID": "smithsonianp",
    "DeviceID": "M3U-PrismCastmacmini",
    "Genres": [],
    "HD": true,
    "Hidden": false,
    "ID": "smithsonianp",
    "Image": "https://tmsimg.fancybits.co/assets/s58532_ll_h15_aa.png?w=360&h=270",
    "Name": "Smithsonian Channel (Pacific)",
    "Number": "10123",
    "Station": "82695",
    "Tags": []
  },

I assume if you uploaded a channel logo into CDVR it would appear in http://192.168.1.4:8089/dvr/uploads so the above /dvr/guide/channels Image url would be replaced by http://192.168.1.4:8089/dvr/uploads/#/content

I posed that question to Claude and added the link to the instructions for setting up custom channels: Channels Support - Add Custom Channels with M3U Playlists. I also asked if it would be a good idea to create a personal metadata library. Here's his response:

This clarifies the picture significantly. There are three distinct ways a custom channel can carry metadata:

  1. tvg-logo — an explicit logo URL embedded in the M3U #EXTINF line. Channels DVR exposes this as logo_url in /api/v1/channels. We already use this first.
  2. tvc-guide-stationid — a Gracenote station ID. When set, Channels DVR fetches full guide data AND a correct logo from TMS automatically. This is what drives the Image field in /dvr/guide/channels that we're now using.
  3. Neither — the M3U just has a stream URL and a name. No logo, no guide data. This is the category your deleted channel 9110 and the May 6 recordings fall into — and it's where a metadata library would help.

On the metadata library idea:

It's a real approach but has a scope problem. Channels DVR supports arbitrary streams worldwide — IPTV providers, local streams, IP cameras, hobbyist setups. A library that covers the long tail of global IPTV would be enormous and would need constant maintenance.

The realistic targets for a library are:

  • US cable/broadcast networks — CNN, MSNBC, Fox News, ESPN, etc. These are finite (~200 channels), stable, and have well-known logos. A bundled JSON of { "CNN": "url", "MSNBC": "url", ... } keyed by tvg-name or channel-id would cover a large portion of US user setups.
  • Community-maintained sources — there are existing open M3U logo packs (e.g., the tv-logos GitHub repo at mitchellkrogza/Phishing.Database — actually more relevant is the tv-logos community repo) that map channel names/IDs to logos. DVRDesk could fetch from one of these at startup.

The practical approach I'd recommend:

Don't build a library in DVRDesk itself. Instead, expose a user-configurable field in Settings: a URL to a supplemental XMLTV or JSON logo map. Power users who have channels with missing logos can point it at a community logo pack or their own mapping file. The app falls back to the channel number badge (which you already have) for anything not covered.

That keeps DVRDesk lean, gives users control, and doesn't require you to maintain channel metadata. The hard-core IPTV community already maintains these logo packs for exactly this problem.

Want to explore that settings-based approach, or would a bundled US cable channel map be more useful for your current user base?

As I mentioned, I don't have any good test cases for sources that inherently have no metadata, but I think the settings-based solution for IPTV etc., is useful if there is any need for it...

I would just upload a channel logo to Channels DVR if I needed it.
Or add the logo url in the m3u

#EXTINF:-1 channel-id="custom.aa0cfa74-6b50-43ca-8143-ce79a05f96c3" tvg-name="Kitten Academy" group-title="Ambiance" tvg-logo="http://nas-1019:5523/logos/86e71541776894c03a86e06696a199e2.jpg" tvc-guide-description="Kitten Academy is where kittens learn to cat! This channel features videos of and about our foster cats - and the foster failures that live with us forever now.",Kitten Academy

Which comes from https://yt3.googleusercontent.com/ytc/AIdro_nqnFVoqK87F4XbteaL4OiYkasCt4WI2V3IwXQY2Ei8AEI=s160-c-k-c0x00ffffff-no-rj
Screenshot 2026-06-14 at 14-48-54 Channels Guide

Works for me!