Sagnac/streamsave

Subtitle tracks prevent saving.

Closed this issue · 15 comments

Hi, after much troubleshooting I've discovered that subtitle tracks prevent saving, causing the
"Cache dumping stopped due to an error" msg. Could streamsave ignore subtitle tracks, so toggling them off is not required every time? Thank you

Sagnac commented

Edit:
Okay nevermind, I'm able to reproduce this with local files if the file has muxed in subs and I attempt to write it out to mp4; it doesn't seem to be a problem with external subs or other containers such as mkv, so it's quite the edge case for the intended use of this script.

As it doesn't appear to be an issue with live streams or online videos and toggling subs back on after executing a continuous write will error and halt the recording then I think the right solution is adding an option instead; universally disabling subs automatically on cache write can't be done because there are plenty of streams which do contain external subtitles (e.g. WebVTT) and won't error on write so we shouldn't be disabling subtitles if you're watching the stream with them enabled.

I'll add a toggle_subs option which will default to no and will have to be enabled in streamsave.conf. If enabled this option will disable subtitles on cache write and re-enable them when cache writing is finished. How does that sound?

Edit:
On second thought, I think a more general solution is appropriate if this really only happens in this specific case.

  • Do you only experience this if the output file is MP4?
  • Is this an issue if external subtitles are selected?

If this really only happens with internal subs and mp4 output then we can just check for that and not need an option. But I'm unsure as to whether this happens with other combinations; from my testing it doesn't.

Sagnac commented

I think I've settled on an appropriate solution. I've tested .ts and .mkv ouputs with and without internal subs and I don't see the issue with these combinations. If you can confirm this only happens with MP4 output and internal subs and this version of the script works for you then I'll go ahead and merge it. If this issue occurs with other combinations then I'll add the option instead.

Sagnac commented

So this also happens with WebM if the subs are internal and not WebVTT. I think I've covered all cases now.

Thanks for looking at this so quickly. The files I have available all have internal subs. The youtube files were sourced with yt-dlp. I can test a specific file if it helps. These are the results from the dev branch (2023-11-21).

youtube.mkv errors
youtube-h264.mkv errors
iptv.mkv working
film.mkv working

Input #0, matroska,webm, from 'youtube.mkv':
Metadata:
ENCODER : Lavf59.27.100
Duration: 00:30:19.48, start: -0.007000, bitrate: 2006 kb/s
Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv, bt709), 1920x1080, SAR 1:1 DAR 16:9, 50 fps, 50 tbr, 1k tbn (default)
Metadata:
DURATION : 00:30:19.467000000
Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
DURATION : 00:30:19.481000000
Stream #0:2(eng): Subtitle: webvtt
Metadata:
title : English
HANDLER_NAME : English
DURATION : 00:30:19.480000000

Input #0, matroska,webm, from 'youtube-h264.mkv':
Metadata:
MINOR_VERSION : 0
COMPATIBLE_BRANDS: iso6avc1mp41
MAJOR_BRAND : dash
ENCODER : Lavf59.27.100
Duration: 00:32:02.08, start: 0.000000, bitrate: 727 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 1k tbn (default)
Metadata:
HANDLER_NAME : VideoHandler
VENDOR_ID : [0][0][0][0]
DURATION : 00:32:02.020000000
Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp (default)
Metadata:
HANDLER_NAME : SoundHandler
VENDOR_ID : [0][0][0][0]
DURATION : 00:32:02.078000000
Stream #0:2(eng): Subtitle: webvtt
Metadata:
title : English
HANDLER_NAME : English
DURATION : 00:23:41.680000000

Input #0, matroska,webm, from 'iptv.mkv':
Metadata:
ENCODER : Lavf60.12.101
Duration: 00:00:06.50, start: 0.000000, bitrate: 4893 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 1k tbn
Metadata:
DURATION : 00:00:06.496000000
Stream #0:1: Audio: mp2, 48000 Hz, stereo, s16p, 128 kb/s
Metadata:
DURATION : 00:00:06.144000000
Stream #0:2: Subtitle: dvb_subtitle
Metadata:
DURATION : 00:00:06.034000000

Input #0, matroska,webm, from 'film.mkv':
Metadata:
ENCODER : Lavf60.12.101
Duration: 00:01:03.06, start: 0.000000, bitrate: 11417 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 24.42 fps, 23.98
tbr, 1k tbn
Metadata:
DURATION : 00:01:02.020000000
Stream #0:1: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
Metadata:
DURATION : 00:01:01.694000000
Stream #0:2: Subtitle: subrip
Metadata:
DURATION : 00:01:03.062000000

streamsave.conf

save_directory=.
dump_mode=ab
output_label=range
force_extension=.mkv
force_title=no
range_marks=no

autostart=no
autoend=no
hostchange=no
quit=no
piecewise=no

I just deleted force_extension=.mkv from streamsave.conf and I'm now able to write youtube.mkv & youtube-h264.mkv with the dev branch, however the subtitles are missing (fine with me). Meanwhile it errors with version 2022-7-22

Sagnac commented

Hmm, what error do you get? From my testing choosing mkv as output is the most flexible and even includes the subs.

with force_extension=no youtube.mkv should write to webm and it shouldn't have an issue with webvtt subtitles. The workaround commit excludes this case so there shouldn't be a difference v0.24.1 and v0.25.0

youtube-h264.mkv should choose mp4 by default which will error without the workaround, that one makes sense.

what I'm confused about is why force_extension=.mkv should error and why there's a difference between the dev branch and the master branch for webm output with webvtt subtitles

It's the usual "Cache dumping stopped due to an error"
I favour mkv, but I just deleted that line on a whim after posting.

with force_extension=no youtube.mkv should write to webm and it shouldn't have an issue with webvtt subtitles. The workaround commit excludes this case so there shouldn't be a difference v0.24.1 and v0.25.0

youtube-h264.mkv should choose mp4 by default which will error without the workaround, that one makes sense.

They do write to webm/mp4 respectively, but the webvtt subtitles are missing.
Somehow with force_extension=.mkv the youtube-sourced files fail to write with webvtt subtitles enabled.

edit. Maybe a toggle is the best solution? Personally I only care about clipping and I don't wish to drive you mad with this.

Sagnac commented

That's odd, webm is a subset of mkv, if it works for the former it should work for the latter. There isn't a more descriptive error message accompanying the usual? With mp4 I get the codec tag error, with webm I would get the unsupported format error. I've tested WebVTT in MKV and have no problem writing to MKV and including the subs, so no idea why that would fail.

If you disable the subtitles those particular files will write correctly with force_extension=.mkv right?

To be certain if you delete the force_extension line youtube.mkv fails on master but writes with the dev version? The output is webm for both, right? The only thing I can think of that's causing a difference there is somehow the sub codec isn't being read as webvtt, meaning that if it's detected correctly our workaround would fail.

I could add the option, but I think leaving in the workaround anyway is a good idea since from the looks of it mp4 output always fails with internal subs and WebM only supports WebVTT so we know that at least in those cases it'll always fail.

Is there a log? I've only ever had the same error message.

If you disable the subtitles those particular files will write correctly with force_extension=.mkv right?

Yes

To be certain if you delete the force_extension line youtube.mkv fails on master but writes with the dev version? The output is webm for both, right?

dev
force_extension=.mkv deleted
subs enabled
result: success. webm written (without subs)

master
force_extension=.mkv deleted
subs enabled
result: error. empty webm written

Sagnac commented

--msg-level in mpv sets how verbose printed console messages are; these types of more specific error messages should show in the terminal on the default of status and if you're getting any error messages they should show unless you've raised the log level for that specific module; usually the module for these types of errors is ffmpeg or recorder. You can also output a log with --log-file.

For this youtube.mkv file what does mpv detect the subtitle type as in the console? Your metadata says they're webvtt subs, but I'm thinking mpv is detecting this differently because it's the only way I can think of the workaround would fire; in other words the file is working when it's not supposed to. If you query the current-tracks/sub/codec property it should show it; you can run mpv with something like

--osd-msg1=${current-tracks/sub/codec}

Do you get the streamsave warning message about incompatible subtitles when it works?

..
[streamsave] .webm output format is incompatible with internal subtitles being selected.
[streamsave] Subs will be disabled while writing and enabled again when finished.
Track switched:
(+) Video --vid=1 () (vp9 1920x1080 50.000fps)
(+) Audio --aid=1 --alang=eng (
) (opus 2ch 48000Hz)
Subs --sid=1 --slang=eng 'English' (webvtt-webm)
Cache dumping started.
[recorder] This is an experimental feature. Output files might be broken or not play correctly with various
players (including mpv itself).
[recorder] Source stream misses DTS on at least some packets!
[recorder] If the target file format requires DTS, the written file will be invalid.
[recorder] Discontinuity at timestamp 0.000000.
[ffmpeg] webm: Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
Cache dumping successfully ended.
..

--osd-msg1=${current-tracks/sub/codec}

webvtt-webm

Well I don't see what more can be done. The dev branch achieves clipping without disabling subs, and I'm reluctant to push others into chasing edge cases. Thank you for the script and your support

Sagnac commented

webvtt-webm

Oh that's interesting, apparently there are two codecs, webvtt and webvtt-webm and it's the latter which seems to cause problems with mkv. The reason the workaround works is because it's not webvtt specifically.

So I guess that tells us this webvtt-webm shouldn't ever work, since it doesn't even work with WebM. All that needs to be done is to check against that and the MKV outputs should work too. I'll push a commit addressing this in a while. Out of curiosity, what's the log message when it does fail (youtube.mkv on master branch without force_extension)?

Sagnac commented

I've updated the dev branch with the fix, if that version works for you (especially when writing to MKV) I'll go ahead and merge it. Feel free to report if there any other issues with this, I'll add the toggle option if there are; that way we'll have a baseline workaround for known incompatibilities and a way to guarantee writes when the user doesn't care about subtitles.

At the moment if these webvtt-webm subtitles do work with some outputs (for whatever reason) then there's no way to include them; not a big deal, but if this isn't as straightforward as the three internal subtitle cases we're looking at now (mp4 universally, non-webvtt in webm, and webvtt-webm universally) then the option is preferable as a direct alternative.

what's the log message when it does fail (youtube.mkv on master branch without force_extension)?

[cplayer] Cache dumping started.
[recorder] Can't mux one of the input streams.
[cplayer] Cache dumping stopped due to error.
[streamsave] error running command
[statusline] (Paused) AV: 00:00:30.007 / 00:52:44.181 (1%) A-V:  0.000
[streamsave] Possibly broken file created at:./youtube.mkv-[00.00.00 - 00.00.30]-2.webm

Here's my yt-dlp config if you'd like to test webvtt-webm further.

-f "bv*[ext=webm]+ba[ext=webm]/b[ext=webm] / bv*+ba/b"
--merge-output-format mkv
--embed-chapters
--embed-subs
--sub-langs "en.*"
--no-write-auto-subs

I've updated the dev branch with the fix

dev seems good, it's writing regardless of whether the extension is forced or not. Thanks again for working on this, my initial post was poor and I couldn't predict that ffmpeg and mpv would report the subtitle format differently.

Sagnac commented

--embed-subs
I couldn't predict that ffmpeg and mpv would report the subtitle format differently

Yeah, I had no idea either. There's two different WebVTT formats apparently even when both are internal subtitles; it appears you can mux the VTT in a different way when you embed them, I think that's what this page is talking about. If I create a .vtt file and mux it into an mkv it'll differ from how yt-dlp is embedding them and mpv has issues with this latter form.

Anyway, if you experience any more issues with this let me know as I have a local branch rebased on top of dev which adds a three-valued toggle_subs=<yes|no|auto> option which can easily be merged. I'd prefer not to add that complexity unless necessary (as long as our current workaround works universally), but if any issues with internal subtitles persist I think this option is the best approach going forward and should iron things out.

Thanks for reporting the issue.