lisamelton / other_video_transcoding

Other tools to transcode videos.
MIT License
555 stars 26 forks source link

New option needed for adding subtitles where only some of the frames are forced. #196

Open AthanVigil opened 11 months ago

AthanVigil commented 11 months ago

I have a large number of mkv files which have vobsub subtiles where on a given track the subtitle contains both forced and non-forced frames. The forced frames are the foreign language transaltion, so ideally I need to be able to add the subtitle track BUT ONLY THE FORCED FRAMES.

The current --add-subtitle x=forced option does not support that since it requires the 'forced' flag to be set on the whole track and this is impossible for this subtitle track. Setting the flag will force the ENTIRE track to be forced which is not the desired result.

Having examined the documentation for ffmpeg it appears that this is what the -forced_subs_only option is intended to support: -

forced_subs_only Only decode subtitle entries marked as forced. Some titles have forced and non-forced subtitles in the same track. Setting this flag to 1 will only keep the forced subtitles. Default value is 0

For one of my problem files the --dry-run option produces the following output: -

Verifying "ffprobe" availability...
Verifying "ffmpeg" availability...
Verifying "mkvpropedit" availability...
Finding encoders...
Trying "hevc_nvenc" video encoder...
C:/Ruby32-x64/bin/other-transcode: output file already exists: S02E16.mkv
Scanning media...
duration = 00:39:39.76
Stream mapping:
 0 = hevc_nvenc / 1000 Kbps
 1 = copy
 3 = dvd_subtitle
Command line:
ffmpeg -loglevel error -stats -i "J:\Shows\The Blacklist (2013)\Season 02\S02E16.mkv" -map 0:0 -filter:v yadif -c:v hevc_nvenc -pix_fmt:v p010le -b:v 1000k -maxrate:v 6000k -bufsize:v 6000k -color_primaries:v bt470bg -color_trc:v bt709 -colorspace:v smpte170m -metadata:s:v title= -disposition:v default -map 0:1 -c:a:0 copy -metadata:s:a:0 title= -disposition:a:0 default -map 0:3 -c:s:0 copy -disposition:s:0 0 -metadata:g title= -default_mode passthrough S02E16.mkv

If I add the -forced_subs_only 1 option into the command and change '-c:a:0 copy' to '-c:a:0 dvd_subtitle' I get the desired result of an mkv file that has only the forced frames in the subtitle track. The full command I used to produce the desired result is shown below: -

ffmpeg -loglevel error -stats -forced_subs_only 1 -i "J:\Shows\The Blacklist (2013)\Season 02\S02E16.mkv" -map 0:0 -filter:v yadif -c:v hevc_nvenc -pix_fmt:v p010le -b:v 1000k -maxrate:v 6000k -bufsize:v 6000k -color_primaries:v bt470bg -color_trc:v bt709 -colorspace:v smpte170m -metadata:s:v title= -disposition:v default -map 0:1 -c:a:0 copy -metadata:s:a:0 title= -disposition:a:0 default -map 0:3 -c:s:0 dvd_subtitle -disposition:s:0 0 -metadata:g title= -default_mode passthrough S02E16.mkv

This command correctly produces a subtitle track with only 44 of the original 674 frames these being the frames which are marked as forced.

Since the encoding of subtitles to include both forced and non-forced within the same track appears to be a common practice (at least in my library) an option to support this scenario would be very much appreciated.

Many thanks for producing this excellent tool which has greatly eased the encoding task while I re-encode my library from handbrake produced h264 to hevc. Just wish I'd known about it previously.

AthanVigil commented 11 months ago

In my example command I neglected to turn on the forced flag, so the command for my use case would actually be: -

ffmpeg -loglevel error -stats -forced_subs_only 1 -i "J:\Shows\The Blacklist (2013)\Season 02\S02E16.mkv" -map 0:0 -filter:v yadif -c:v hevc_nvenc -pix_fmt:v p010le -b:v 1000k -maxrate:v 6000k -bufsize:v 6000k -color_primaries:v bt470bg -color_trc:v bt709 -colorspace:v smpte170m -metadata:s:v title= -disposition:v default -map 0:1 -c:a:0 copy -metadata:s:a:0 title= -disposition:a:0 default -map 0:3 -c:s:0 dvd_subtitle -disposition:s:0 default+forced -metadata:g title= -default_mode passthrough S02E16.mkv

Both suggested commands have been tested and do produce the expected output.

For maximum usability this suggests that there are probably 3 ways a mixed forced/non-forced subtitle track is likely be processed: -

  1. Use only the forced original subtitle frames to produce a non-forced subtitle track
  2. Use only the forced original subtitle frames to produces a forced subtitle track
  3. Use only the forced original subtitle frames to produce a burned in subtitle