Using LosslessCut LLC file to update CDVR commercial skip markers

Happy Holidays CDVR people!

I'm hoping to be able to use LosslessCut LLC files to fix commercial skip points for files that CDVR's built-in commercial editor can't fix. It's fairly straightforward to create an LLC that only contains chapter markers for commercial breaks -- very similar to an EDL file.

They look like this:

{
  version: 1,
  mediaFileName: 'The Closer S01E09 2005-08-08 Good Housekeeping 2023-11-23-1900.mpg',
  cutSegments: [
    {
      start: 0,
      end: 23.52,
      name: '',
    },
    {
      start: 627.693733,
      end: 823.823,
      name: '',
    },
    {
      start: 1378.610567,
      end: 1542.774567,
      name: '',
    },
    {
      start: 1905.57,
      end: 2160.86,
      name: '',
    },
    {
      start: 2435.47,
      end: 2646.94,
      name: '',
    },
    {
      start: 2968.47,
      end: 3268.87,
      name: '',
    },
  ],
}

The above represents a fixed set of skip segments. The original EDL file for the same episode, for reference, looks like this:

0	23.52	3
1905.57	2160.86	3
2435.47	2646.94	3
2968.47	3268.87	3

So, I can clear all of the Comskip data for a given CDVR FileID using:
curl -XPOST "http://media-server6:8089/dvr/files/$fileID/comskip/edit?source=local" --data-raw "[]"
Is there something similar I can do to replace the current skip points, and would anything else be necessary besides that?

I have a basic script worked up to be able to turn the LLC into an EDL, which I imagine I'd need to do to keep the embedded skip points matched up with the EDL.

Simple. Change the raw data your POSTing "[]" to the start and end values you want
"[start,end,start,end,...]"

"[0,23.52,627.693733,823.823,1378.610567,1542.774567,1905.57,2160.86,2435.47,2646.94,2968.47,3268.87]"

If you have enabled EDL Export Integration, this will also update your EDL file next to the recording

2 Likes

This makes me wonder, if there is any data you could grab from Plex or Emby - for intro or credit markers for TV shows and Movies, and put them into CDVR as ‘commercials’.

I’m sure someone clever could make a script to automate that for all the files that match.

Wow does this ever work nicely! Credit to @chDVRuser for pointing me in the right direction.

I've now added this capability to OliveTin-for-Channels, and what this does is allow you to fix commercial skipping issues that can't be dealt with via the excellent CDVR "Edit Commercials" feature. It requires that you have EDL export integration enabled in Settings.

Here are some details:

Say you have one or more recorded shows, that have the "Interrupted" flag on them, but appear to be fine otherwise. This can result in issues with commercial skipping, that can't be fixed with a simple check or uncheck in the CDVR editor. And they might look something like this:

As you can see, there are commercials buried in blocks, with no way to fix them in this editor. LosslessCut to the rescue! Without actually making any changes to the video file itself, you can open the video and import the companion EDL file and modify the commercial breaks -- working with them as "chapters":

At this point, the main thing you want to check are the commercial breaks as they exist currently. So, click on the timeline within those colored chapters and make sure that each is actually all commercial. I like to click near the beginning, middle and end of this size chapter. Once you've done that, you want to "invert" the colored segments, using this dropdown:

After that, the show segments will become the colored blocks. Now you can start clicking on various points in the timeline, to determine where undetected commercials are located. There are forward and back keyframe buttons, and also one frame at a time buttons when you're closing in on the exact spot for the beginning of a commercial.

When you find the beginning of a commercial, use the "Split segment at cursor" button to set the beginning of a new segement. Do the same for the end of the commercial. Once the new segment is created, make sure it's the selected segment in the right-hand "Segments to export" area, and click the minus sign at the bottom of that area.

Once you have the segments correctly defined, you'll need invert the segments one last time so it's once again the commercials that are the colored blocks. From there you can close LosslessCut, and there's no need to save anything as LLC automatically updates the file containing the segment information whenever you make changes.

Next you'll need to run the new OliveTin Action "Update Commercials Metadata from LosslessCut LLC File", and for that you'll need the "File ID" for the recording you just worked on. The File ID can be found multiple places, but for this project right in the "View Details" option from that same dropdown you used to get to "Edit Commercials" is a good place to find it. It's also shown at the top of the commercial editing dialog.

Run the OliveTin Action using that ID, and then check the Log for details. The companion EDL file will be updated automatically too.

screenshot-htpc6-2023.12.26-05_12_00

Lastly, you need to go back into the CDVR commercial editor, admire your handiwork, and then save at the bottom:

No video files were harmed during the making of this write-up. :slight_smile:

1 Like

:joy: Great line!

And great job, @bnhf, with help from @chDVRuser.

I have had EDL export enabled like forever but I have never done anything with them... Until now.
This is cool, I was always hoping for a way to be able to edit the cut points without having to actually touch the videos.

I will start doing this soon.

Thank you for sharing!

Script seems to get confused where things are on my *ix config but the llc is where the recording is:

  • recordingName=TV/CBS News Texas at 500 AM/CBS News Texas at 500 AM 2023-12-27-0500.mpg
  • recordingLLC=TV/CBS News Texas at 500 AM/CBS News Texas at 500 AM 2023-12-27-0500-proj.llc
  • cat /mnt/192.168.0.12-8089/TV/CBS News Texas at 500 AM/CBS News Texas at 500 AM 2023-12-27-0500-proj.llc
    cat: '/mnt/192.168.0.12-8089/TV/CBS News Texas at 500 AM/CBS News Texas at 500 AM 2023-12-27-0500-proj.llc': No such file or directory

The most likely thing is an issue with the way that you've bound your shared "dvr" directory to the OliveTin container.

Are you binding an NFS or SMB share that you setup through Portainer-Volumes, or is this a directory that's available on your Docker host and you're able to bind it directly? If you could post the bottom section of your compose here including the bindings, and any volumes you're defining, that would be helpful.

EDIT: If it's a directory that's available on your Docker host (as is the case for me using Proxmox) then you bind that directory to the container. Otherwise, if it's a network share, you need to create a Docker Volume using Portainer-Volumes which looks like this in Portainer:

And using this style of mount, the name you choose for the volume gets bound to the container. So, if your Docker Volume is called channels-dvr, then uncomment the lines in the very bottom "volumes" section. And the binding itself would look like this:

    volumes:
      - ${HOST_DIR}/olivetin:/config # Add the parent directory on your Docker you'd like to use
      - ${DVR_SHARE}:/mnt/192.168.0.12-8089 # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR network share
    restart: unless-stopped
volumes: # use this section if you've setup a docker volume named channels-dvr, with CIFS or NFS, to bind to /mnt/dvr inside the container
  channels-dvr:
    external: true

and the environment variable for DVR_SHARE would be:

DVR_SHARE=channels-dvr

Or, if it's a directory that's available directly on your Docker host -- for example, /media/dvr, then your compose would look like this:

    volumes:
      - ${HOST_DIR}/olivetin:/config # Add the parent directory on your Docker you'd like to use
      - ${DVR_SHARE}:/mnt/192.168.0.12-8089 # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR network share
    restart: unless-stopped
#volumes: # use this section if you've setup a docker volume named channels-dvr, with CIFS or NFS, to bind to /mnt/dvr inside the container
  #channels-dvr:
    #external: true

and the environment variable for DVR_SHARE would be:

DVR_SHARE=/media/dvr

Ahh, yes - my main instance of channels is not running in a container. Lots of other stuff is but not the original instance of cDVR.

That's fine -- it doesn't need to be. What we're talking about here is where your recordings can be found.

Thanks - fixed it up just fine. Interesting find the LosslessCut LLC approach.