diff --git a/DOCS/interface-changes/sub-text-ass-full.txt b/DOCS/interface-changes/sub-text-ass-full.txt new file mode 100644 index 0000000000..e0f4206af8 --- /dev/null +++ b/DOCS/interface-changes/sub-text-ass-full.txt @@ -0,0 +1 @@ +add `sub-text/ass-full` sub-property diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index d1a090c24a..7863090c59 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -2833,8 +2833,11 @@ Property list with line breaks. Contains only the "Text" part of the events. This property is not enough to render ASS subtitles correctly, because ASS - header and per-event metadata are not returned. You likely need to do - further filtering on the returned string to make it useful. + header and per-event metadata are not returned. Use ``/ass-full`` for that. + + ``sub-text/ass-full`` + Like ``sub-text-ass``, but return the full event with all fields, formatted as + lines in a .ass text file. Use with ``sub-ass-extradata`` for style information. ``sub-text-ass`` (deprecated) Deprecated alias for ``sub-text/ass``. diff --git a/player/command.c b/player/command.c index 39cb9d8720..38009a94b0 100644 --- a/player/command.c +++ b/player/command.c @@ -3026,6 +3026,8 @@ static int mp_property_sub_text(void *ctx, struct m_property *prop, if (!strcmp(ka->key, "ass")) type = SD_TEXT_TYPE_ASS; + else if (!strcmp(ka->key, "ass-full")) + type = SD_TEXT_TYPE_ASS_FULL; else return M_PROPERTY_UNKNOWN; diff --git a/sub/dec_sub.h b/sub/dec_sub.h index eb8406cb14..a40aa9bbfd 100644 --- a/sub/dec_sub.h +++ b/sub/dec_sub.h @@ -24,6 +24,7 @@ enum sd_ctrl { enum sd_text_type { SD_TEXT_TYPE_PLAIN, SD_TEXT_TYPE_ASS, + SD_TEXT_TYPE_ASS_FULL, }; struct sd_times { diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 07e336f4c2..41c14623a1 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -795,6 +795,28 @@ static bstr get_text_buf(struct sd *sd, double pts, enum sd_text_type type) int start = b->len; if (type == SD_TEXT_TYPE_PLAIN) { ass_to_plaintext(b, event->Text); + } else if (type == SD_TEXT_TYPE_ASS_FULL) { + long long s = event->Start; + long long e = s + event->Duration; + + ASS_Style *style = (event->Style < 0 || event->Style >= track->n_styles) ? NULL : &track->styles[event->Style]; + + int sh = (s / 60 / 60 / 1000); + int sm = (s / 60 / 1000) % 60; + int ss = (s / 1000) % 60; + int sc = (s / 10) % 100; + int eh = (e / 60 / 60 / 1000); + int em = (e / 60 / 1000) % 60; + int es = (e / 1000) % 60; + int ec = (e / 10) % 100; + + bstr_xappend_asprintf(NULL, b, "Dialogue: %d,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s,%s,%04d,%04d,%04d,%s,%s", + event->Layer, + sh, sm, ss, sc, + eh, em, es, ec, + (style && style->Name) ? style->Name : "", event->Name, + event->MarginL, event->MarginR, event->MarginV, + event->Effect, event->Text); } else { bstr_xappend(NULL, b, bstr0(event->Text)); }