diff --git a/av/subtitles/subtitle.py b/av/subtitles/subtitle.py index bd2629fa4..957803131 100644 --- a/av/subtitles/subtitle.py +++ b/av/subtitles/subtitle.py @@ -294,8 +294,9 @@ def dialogue(self): Extract the plain text from the ASS dialogue line. Override tags and comments (``{...}`` blocks) are removed, ``\\N`` - becomes a newline, and ``\\n`` and ``\\h`` become a space. A ``{`` - with no closing ``}`` is kept as literal text. + becomes a newline, ``\\n`` and ``\\h`` become a space, and ``\\{`` + and ``\\}`` become literal braces. A ``{`` with no closing ``}`` is + kept as literal text. """ ass_text: bytes = self.ass text_len: cython.Py_ssize_t = len(ass_text) @@ -325,6 +326,10 @@ def dialogue(self): result.append(b" "[0]) i += 2 continue + if char == b"\\"[0] and (next_char == b"{"[0] or next_char == b"}"[0]): + result.append(next_char) + i += 2 + continue if char == b"{"[0] and i < last_close: in_block = True else: diff --git a/scripts/ffmpeg-8.1.json b/scripts/ffmpeg-8.1.json index 58dc5ae29..580cd6f40 100644 --- a/scripts/ffmpeg-8.1.json +++ b/scripts/ffmpeg-8.1.json @@ -1,3 +1,3 @@ { - "url": "https://github.com/PyAV-Org/pyav-ffmpeg/releases/download/8.1.2-1/ffmpeg-{platform}.tar.gz" + "url": "https://github.com/PyAV-Org/pyav-ffmpeg/releases/download/8.1.3-1/ffmpeg-{platform}.tar.gz" } diff --git a/scripts/ffmpeg-latest.json b/scripts/ffmpeg-latest.json index dfe3a5975..a5fdc7f08 100644 --- a/scripts/ffmpeg-latest.json +++ b/scripts/ffmpeg-latest.json @@ -1,3 +1,3 @@ { - "url": "https://github.com/PyAV-Org/pyav-ffmpeg/releases/download/9.0.2-1/ffmpeg-{platform}.tar.gz" + "url": "https://github.com/PyAV-Org/pyav-ffmpeg/releases/download/9.0.2-4/ffmpeg-{platform}.tar.gz" } diff --git a/tests/test_subtitles.py b/tests/test_subtitles.py index 51cf3f3b2..f3a458b6a 100644 --- a/tests/test_subtitles.py +++ b/tests/test_subtitles.py @@ -171,6 +171,9 @@ def dialogue(text: bytes) -> bytes: assert dialogue(prefix + b"a\\Nb") == b"a\nb" assert dialogue(prefix + b"a\\nb") == b"a b" assert dialogue(prefix + b"a\\hb") == b"a b" + # Escaped braces are literal and don't open a block. + assert dialogue(prefix + b"a\\{b\\}c") == b"a{b}c" + assert dialogue(prefix + b"\\{x{\\i1}y") == b"{xy" # A stray '{' with no closing '}' is literal text. assert dialogue(prefix + b"cost is {5") == b"cost is {5" # Commas in the Text field are kept.