Skip to content

Reintroducing Hardsubs #1

Description

@familyfriendlymikey

In response to a github user who messaged me elsewhere about reintroducing the hardsubs feature:

I think I may have a great idea regarding this, sort of similar to what you mentioned. I'm assuming you're familiar with the fact that the script generates a "cut list" text file, which you can feed to the included Python script make_cuts to make the cuts. It was already somewhat of a pain to jump in a terminal, navigate to the correct directory, and run make_cuts. But what if we were to forego the cut list and make_cuts files entirely, and instead have mpv-cut generate a Python file, such as LIST_CHANNEL_NAME_Source_Video_File_Name.mkv.py, which would act as both the cut list for backup purposes and as the make_cuts script:

filename = "LIST_CHANNEL_NAME_Source_Video_File_Name.mkv"
timestamps = [
	(105.67, 108),
	(156, 187),
	(256, 270.12432)
]

hardsubs = True

import ffmpeg
...

To be clear, this would mean that the "hardsubs" option wouldn't actually generate a video file with hardsubs. Instead, by default mpv-cut would generate a cut list which would now be a self-contained python file that gets placed in the same directory as the source video, which you would simply double click to execute once you're done watching your video, and enabling the "hardsubs" option would generate a script where hardsubs = True.

This has several pros:

  • We're no longer limited to mpv's API, so we can use some Python ffmpeg wrapper to deal with all the ffmpeg/ffprobe crap.
  • The cut list backup files are now self-contained. As long as the user has the source video file in the same directory, all they have to do is double click, no more fiddling with a make_cuts executable.
  • If the ffmpeg command fails or produces an undesirable output for whatever reason (which will undoubtedly happen, no matter how much we tune the ffmpeg command), it'll be much easier to modify the resulting script for a niche use case to fix it, a fix which will then persist with the cut list itself!
  • If there's an uncaught exception with the mpv script, IIRC the script stops running. Even if we catch all exceptions, displaying errors with the OSD is inelegant, whereas with a python script the exception is displayed very clearly, and does not interrupt further use of mpv.
  • If the user wants to do something programmatic with the cut list, doing so would now be really easy because it's already in Python as opposed to an arbitrary text file format, and there would already be an underlying foundation of ffmpeg-related code. Even further with this point, we could change the formatting of the generated python script to be like so:
files = [
	{
		filename: "LIST_CHANNEL_NAME_Source_Video_File_Name.mkv",
		timestamps = [
			(105.67, 108),
			(156, 187),
			(256, 270.12432)
		]
	}
]

hardsubs = True

import ffmpeg
...

and instead of dealing with just one file, we loop through the filenames list. This way, the user can easily combine multiple cut lists together by pasting additional file objects into the files dict (I have some ideas to make this even more convenient but maybe later).

Furthermore, if the user wants to change the behavior of the generated script or supply some flags to ffmpeg without having to edit the script, we could allow easy passing of args by doing something like:

files = [
	...
]

import sys

if len(sys.argv) > 2:
	args = sys.argv[2:]
else:
	# this else block would contain the options the user chose
	# inside of mpv, for example having hardsubs toggled on
	args = ["hardsubs"]

import ffmpeg
...

This way, we could potentially add even more functionality, such as a concat option or a framerate option (not inside of mpv-cut, but as commandline args to the generated cut list script).

The drawbacks, which IMO are completely negligible, are that

  • The user now has to perform one single extra action (double clicking the .py file after they're done watching the video in mpv).
  • The user has to install Python, pip, and the ffmpeg wrapper globally.
  • The cut list files will take up more space because they have python in them.
  • If the user chooses to use the global option, the cut list and cut will be placed at the global dir, so double clicking the cut list Python file won't work. If someone does want that functionality, we could store the absolute path to the source file and check if it exists, and if not use the current directory.

Let me know if you disagree with anything. I know for some people one extra step can be a dealbreaker, but compared to the reduced complexity in mpv/increased modularity and flexibility this provides, I think this seems like a great workflow. There are some technicalities to deal with but this shouldn't be too hard. I'm open to discussion though.

If you do like this idea, I'd be down to implement it if you figure out the Python ffmpeg wrapper queries for hardsubs, assuming they exist.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions