def create_sample() -> None: with tempfile.TemporaryDirectory() as dir_name: subs_path = Path(dir_name) / "tmp.ass" with open(subs_path, "w") as handle: write_ass(self.api.subs.ass_file, handle) command = [ "ffmpeg", "-i", str(self.api.video.current_stream.path), "-y", "-crf", str(self.args.crf), "-b:v", "0", "-ss", ms_to_str(start), "-to", ms_to_str(end), ] if self.args.include_subs: command += ["-vf", "ass=" + str(subs_path)] command += [str(path)] subprocess.run(command)
async def run(self) -> None: start = await self.args.start.get() end = await self.args.end.get() if end < start: end, start = start, end if start == end: raise CommandUnavailable("nothing to sample") assert self.api.video.current_stream.path path = await self.args.path.get_save_path( file_filter="Webm Video File (*.webm)", default_file_name="video-{}-{}..{}.webm".format( self.api.video.current_stream.path.name, ms_to_str(start), ms_to_str(end), ), ) def create_sample() -> None: with tempfile.TemporaryDirectory() as dir_name: subs_path = Path(dir_name) / "tmp.ass" with open(subs_path, "w") as handle: write_ass(self.api.subs.ass_file, handle) command = [ "ffmpeg", "-i", str(self.api.video.current_stream.path), "-y", "-crf", str(self.args.crf), "-b:v", "0", "-ss", ms_to_str(start), "-to", ms_to_str(end), ] if self.args.include_subs: command += ["-vf", "ass=" + str(subs_path)] command += [str(path)] subprocess.run(command) # don't clog the UI thread self.api.log.info(f"saving video sample to {path}...") await asyncio.get_event_loop().run_in_executor(None, create_sample) self.api.log.info(f"saved video sample to {path}")
async def run(self) -> None: start = await self.args.start.get(align_to_near_frame=False) end = await self.args.end.get(align_to_near_frame=False) path = await self.args.path.get_save_path( file_filter="Waveform Audio File (*.wav)", default_file_name="audio-{}-{}..{}.wav".format( self.api.audio.current_stream.path.name, ms_to_str(start), ms_to_str(end), ), ) self.api.audio.current_stream.save_wav(path, start, end) self.api.log.info(f"saved audio sample to {path}")
def create_sample(): subprocess.run( [ "ffmpeg", "-i", self.api.video.path, "-y", "-crf", "20", "-ss", ms_to_str(start), "-to", ms_to_str(end), str(path), ] )
def _set_end(self, end: T.Optional[int]) -> None: if not self._api.playback.is_ready: return if end is None: self._mpv.set_option("end", "none") else: end = max(0, end - 1) self._mpv.set_option("end", ms_to_str(end))
def _set_end(self, end: Optional[int]) -> None: if not self._api.playback.is_ready: return if end is None: ret = "none" else: end = max(0, end - 1) ret = ms_to_str(end) if self.mpv.end != ret: self.mpv.end = ret
async def run(self) -> None: subs = await self.args.target.get_subtitles() if not subs: raise CommandUnavailable("nothing to copy") if self.args.subject == "text": QtWidgets.QApplication.clipboard().setText("\n".join( sub.text for sub in subs)) elif self.args.subject == "notes": QtWidgets.QApplication.clipboard().setText("\n".join( sub.note for sub in subs)) elif self.args.subject == "times": QtWidgets.QApplication.clipboard().setText("\n".join( "{} - {}".format(ms_to_str(sub.start), ms_to_str(sub.end)) for sub in subs)) elif self.args.subject == "all": QtWidgets.QApplication.clipboard().setText(_pickle(subs)) else: raise AssertionError
async def run(self) -> None: start = await self.args.start.get() end = await self.args.end.get() if end < start: end, start = start, end if start == end: raise CommandUnavailable("nothing to sample") assert self.api.video.path path = await self.args.path.get_save_path( file_filter="Webm Video File (*.webm)", default_file_name="video-{}-{}..{}.webm".format( self.api.video.path.name, ms_to_str(start), ms_to_str(end) ), ) def create_sample(): subprocess.run( [ "ffmpeg", "-i", self.api.video.path, "-y", "-crf", "20", "-ss", ms_to_str(start), "-to", ms_to_str(end), str(path), ] ) # don't clog the UI thread self.api.log.info(f"saving video sample to {path}...") await asyncio.get_event_loop().run_in_executor(None, create_sample) self.api.log.info(f"saved video sample to {path}")
def set_value(self, value: int) -> None: """Set current PTS. :param value: PTS to set """ if value == self._value: return self._value = value text = ms_to_str(value) if self._allow_negative and value >= 0: text = "+" + text if text != self._edit.text(): self._edit.setText(text) self._edit.setCursorPosition(0) self.value_changed.emit(self._value)
async def run(self) -> None: pts = await self.args.pts.get() path = await self.args.path.get_save_path( file_filter="Portable Network Graphics (*.png)", default_file_name="shot-{}-{}.png".format( self.api.video.current_stream.path.name, ms_to_str(pts) ), ) self.api.video.current_stream.screenshot( pts, path, self.args.include_subs, self.args.width, self.args.height, ) self.api.log.info(f"saved screenshot to {path}")
def _on_request_playback(self, start: Optional[int], end: Optional[int]) -> None: if start is not None: self.mpv.seek(ms_to_str(start), "absolute") self._set_end(end) self.mpv.pause = False
def _on_request_seek(self, pts: int, precise: bool) -> None: self._set_end(None) # mpv refuses to seek beyond --end self.mpv.seek(ms_to_str(pts), "absolute", "exact")
def _on_request_playback(self, start: T.Optional[int], end: T.Optional[int]) -> None: if start is not None: self._mpv.command("seek", ms_to_str(start), "absolute") self._set_end(end) self._mpv.set_property("pause", False)
def _on_request_seek(self, pts: int, precise: bool) -> None: self._set_end(None) # mpv refuses to seek beyond --end self._mpv.command("seek", ms_to_str(pts), "absolute+exact" if precise else "absolute")
def display(self, sub: AssEvent) -> Any: return ms_to_str(sub.duration)
def display(self, sub: AssEvent) -> Any: return ms_to_str(getattr(sub, self._property_name))