MCPcopy Create free account
hub / github.com/smacke/ffsubsync / PGSSpeechTransformer

Class PGSSpeechTransformer

ffsubsync/speech_transformers.py:1103–1208  ·  view source on GitHub ↗

Use PGS (Presentation Graphic Stream) subtitle timings as a sync reference. PGS subtitles are bitmap-based (e.g. Blu-ray / HDMV) and cannot be converted to text by ffmpeg, so they can't be fed through the normal subtitle pipeline. However, when muxed into an MKV the container still stor

Source from the content-addressed store, hash-verified

1101
1102
1103class PGSSpeechTransformer(TransformerMixin, ComputeSpeechFrameBoundariesMixin):
1104 """Use PGS (Presentation Graphic Stream) subtitle timings as a sync reference.
1105
1106 PGS subtitles are bitmap-based (e.g. Blu-ray / HDMV) and cannot be converted
1107 to text by ffmpeg, so they can't be fed through the normal subtitle pipeline.
1108 However, when muxed into an MKV the container still stores a presentation
1109 timestamp (``pts_time``) and ``duration_time`` for every subtitle packet, so
1110 we can recover *when* each caption is on screen without decoding the bitmaps
1111 or parsing the raw SUP/PCS binary at all.
1112
1113 This transformer reads those per-packet timings via ``ffprobe`` (see
1114 :func:`_get_pgs_timings_via_ffprobe`), filtering out the tiny "clear" packets
1115 that carry no image, and builds the same kind of sparse binary speech signal
1116 that :class:`SubtitleSpeechTransformer` produces for text subtitles: 1.0 while
1117 a caption is displayed, 0.0 otherwise. That signal can then be aligned against
1118 the input subtitle file by the normal ffsubsync pipeline.
1119
1120 The reference stream may be given explicitly via ``ref_stream`` (with or
1121 without a leading ``0:``), or left as ``None`` to auto-detect the first
1122 ``hdmv_pgs_subtitle`` track in the file.
1123 """
1124
1125 # PGS is already in the MKV timebase so its duration cannot be compared
1126 # against the SRT to infer a framerate ratio. Returning None here prevents
1127 # the duration-based framerate inference in try_sync from running.
1128 @property
1129 def num_frames(self) -> None:
1130 return None
1131
1132 def __init__(
1133 self,
1134 sample_rate: int,
1135 start_seconds: int = 0,
1136 ffmpeg_path: Optional[str] = None,
1137 ref_stream: Optional[str] = None,
1138 gui_mode: bool = False,
1139 ) -> None:
1140 super(PGSSpeechTransformer, self).__init__()
1141 self.sample_rate: int = sample_rate
1142 self.start_seconds: int = start_seconds
1143 self.ffmpeg_path: Optional[str] = ffmpeg_path
1144 self.ref_stream: Optional[str] = ref_stream
1145 self.gui_mode: bool = gui_mode
1146 self.pgs_speech_results_: Optional[np.ndarray] = None
1147
1148 def fit(self, fname: str, *_) -> "PGSSpeechTransformer":
1149 if self.ref_stream is None:
1150 stream = find_pgs_stream(fname, self.ffmpeg_path, self.gui_mode)
1151 if stream is None:
1152 raise ValueError(
1153 "No hdmv_pgs_subtitle stream found in {}. "
1154 "Specify one explicitly with --pgs-ref-stream.".format(fname)
1155 )
1156 else:
1157 stream = self.ref_stream
1158 if not stream.startswith("0:"):
1159 stream = "0:" + stream
1160

Callers 1

make_reference_pipeFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected