mifi/lossless-cut

Improve support for external post-process programs

Yoooi0 opened this issue · 10 comments

This is a loose feature request but I recently had a project in mind recently that required me to cut/merge video files and I didnt want to reinvent the wheel with video processing so I wanted to use LosslessCut for that, and write a simple "post-process" application that would do the stuff I need on the exported files.
While writing I noticed that it is actually somewhat tricky to use .llc project files from external programs.

For example there is no way to know what files were actually exported. The external program could try to create the file names if it knows the segment export format that the user configured, and the .llc project file, but due to float inaccuracies I actually encountered a case where the segment time in the filename was off by 1ms.
I think the project file could contain information on the last export, something like this:

{
  ...
  "lastExport": {
    "type": "merge+separate",
    "path": "C:\\Videos",
    "segmentFormat": "${FILENAME}-${CUT_FROM}-${CUT_TO}${SEG_SUFFIX}${EXT}",
    "output": [
      "video-00.01.17.230-00.02.12.465-seg1.mp4",
      "video-00.03.36.232-00.05.17.917-seg2.mp4",
      "13793562_720p-cut-merged-1641853512921.mp4"
    ]
  }
}

As a bonus, LosslessCut could allow users to specify an executable to run after each export that would pass the .llc project file path as argument. This way advanced users could create small post-process plugins/applications and rely on LosslessCut on the actual cutting/merging.

mifi commented

Thanks for your feature request

  • I think it's the first time I've heard a request for running an external program after the export, but we can leave this open in case it is something that more people would want to do.
  • I'm not sure if lastExport is something that belongs in the project file, but maybe we could improve the output file format so you can more easily correlate the project file's content with the output file names. Doesn't cutSegments array index equal to the template variable ${SEG_NUM}?

I'm not sure if lastExport is something that belongs in the project file, but maybe we could improve the output file format so you can more easily correlate the project file's content with the output file names.

True, but it would make sense if the project would include all/most of the options you can configure when exporting, maybe not the actual file names but stuff like segment format, export type, and the path. Those would be then auto set when loading a project in LosslessCut.

But one issue would remain with start/end segment times being saved as floats, like i mentioned there are cases where converting the float value to time string can result in 1ms differences.
Ideally I think they should be saved in some specific string time format like "hh.mm.ss.fff".

I think it's the first time I've heard a request for running an external program after the export, but we can leave this open in case it is something that more people would want to do.

Yea I figured that this would be an super edge case request.
But it could be used to make tools or python scripts to for example automatically cut subtitles (i think i saw a request for that), metadata or other additional tracks. Maybe automatically move exported files to some archive, batch open each segment in some video processing software.
Just spit balling some stuff that can be automated but which doesnt belong to be added as a feature to LosslessCut.

mifi commented

True, but it would make sense if the project would include all/most of the options you can configure when exporting, maybe not the actual file names but stuff like segment format, export type, and the path. Those would be then auto set when loading a project in LosslessCut.

Yes I agree that some of these options could be saved in the project file, that is something I have to consider.

Ideally I think they should be saved in some specific string time format like "hh.mm.ss.fff".

I'm not sure why you need the time to be exact, but I agree that such a format makes sense. Or just the calculated frame number (which we are already showing inside the UI)

But it could be used to make tools or python scripts to for example automatically cut subtitles (i think i saw a request for that), metadata or other additional tracks. Maybe automatically move exported files to some archive, batch open each segment in some video processing software.

That's true, and also why I want to leave the feature request open

I'm not sure why you need the time to be exact, but I agree that such a format makes sense. Or just the calculated frame number (which we are already showing inside the UI)

I assumed you don't like the idea of saving the list of latest exported files to the project file itself, so for the tool/script to reconstruct the exported file names based on the project file and do the stuff it does, it needs the "segment format" and segment time/start times.
But there also cant be a mismatch between the start/end times in the file names saved by LosslessCut and times that the tool will be able to create from the float value.
For example:

project file:

{
  ...
  cutSegments: [
    {
      start: 1023.023,
      end: 1123.023,
      name: '',
    },
  ]
}

exported file: video-00.17.03.023-00.18.43.022.mp4
C# tool:

//outputs 00.17.03.023
TimeSpan.FromSeconds(1023.023).ToString(@"hh\.mm\.ss\.fff");

//outputs 00.18.43.023
TimeSpan.FromSeconds(1123.023).ToString(@"hh\.mm\.ss\.fff");

As you can see there is a 1ms mismatch.
So I think the float value is fine for precision, but can be unreliable when trying to create the correct file names.

mifi commented

Could you instead use the ${SEG_NUM} in your output file format as suggested above, and then I believe SEG_NUM should correspond with the index inside the cutSegments array

Yes that will work fine but requires me to use some special format. Or I could use the default format to get the seg1, seg2 etc. suffix but then you can't label your segments.
If the tool was just for me then there would be no problem with me using some custom format in LosslessCut, but if I were to share it then I can't really assume what the user settings are.

This feature request was so that the tools/scripts could be more generic and not rely on assumptions, just parse the project file to get all the info they need. There is no problem in getting this to work if I hardcode some stuff.

mifi commented

Ah, so you want to kknd of build an application or tool around losslesscut and distribute it as one working unit? Then yea i agree it would be better to have a programmatic api. I have created an issue for gathering these kinds of programmatic requests #980

More or less yes, it doesn't have to be distributed as one, it would use output from losslesscut to do its thing on the exported segments files and/or merged file. The output I suggested that could be used would the the project file since it is always created, and just needs a few tweaks.

I didn't even think to suggest an api because I knew that it will be a bigger task, but for sure it will be more flexible and could provide even more data/events that would not be fit for the project file.
Thanks!

mifi commented

How does your program know that the export is finished if there is no API?

It doesn't, I just drag drop the project file manually after the export is done.