diff --git a/hydrus/core/HydrusVideoHandling.py b/hydrus/core/HydrusVideoHandling.py index 820eb393..160268cf 100644 --- a/hydrus/core/HydrusVideoHandling.py +++ b/hydrus/core/HydrusVideoHandling.py @@ -1,8 +1,10 @@ import numpy +import numpy.typing import os import re import struct import subprocess +from typing import Optional from hydrus.core import HydrusAudioHandling from hydrus.core import HydrusConstants as HC @@ -43,7 +45,7 @@ def CheckFFMPEGError( lines ): raise HydrusExceptions.DamagedOrUnusualFileException( 'FFMPEG could not parse.' ) -def GetAPNGChunks( file_header_bytes: bytes ): +def GetAPNGChunks( file_header_bytes: bytes ) ->list: # https://wiki.mozilla.org/APNG_Specification # a chunk is: @@ -72,7 +74,7 @@ def GetAPNGChunks( file_header_bytes: bytes ): return chunks -def GetAPNGACTLChunkData( file_header_bytes: bytes ): +def GetAPNGACTLChunkData( file_header_bytes: bytes ) -> Optional[bytes]: # the acTL chunk can be in different places, but it has to be near the top # although it is almost always in fixed position (I think byte 29), we have seen both pHYs and sRGB chunks appear before it @@ -92,7 +94,7 @@ def GetAPNGACTLChunkData( file_header_bytes: bytes ): return None -def GetAPNGDuration( apng_bytes: bytes ): +def GetAPNGDuration( apng_bytes: bytes ) -> float: frame_control_chunk_name = b'fcTL' @@ -122,7 +124,7 @@ def GetAPNGDuration( apng_bytes: bytes ): return total_duration -def GetAPNGNumFrames( apng_actl_bytes: bytes ): +def GetAPNGNumFrames( apng_actl_bytes: bytes ) -> int: ( num_frames, ) = struct.unpack( '>I', apng_actl_bytes[ : 4 ] ) @@ -565,7 +567,7 @@ def GetMime( path ): return HC.APPLICATION_UNKNOWN -def HasVideoStream( path ): +def HasVideoStream( path ) -> bool: lines = GetFFMPEGInfoLines( path ) @@ -823,7 +825,7 @@ def ParseFFMPEGFPSPossibleResults( video_line ): return ( possible_results, confident ) -def ParseFFMPEGHasVideo( lines ): +def ParseFFMPEGHasVideo( lines ) -> bool: try: @@ -893,7 +895,7 @@ def ParseFFMPEGMimeText( lines ): raise HydrusExceptions.DamagedOrUnusualFileException( 'Error reading file type!' ) -def ParseFFMPEGNumFramesManually( lines ): +def ParseFFMPEGNumFramesManually( lines ) -> int: frame_lines = [ line for line in lines if line.startswith( 'frame=' ) ] @@ -950,7 +952,7 @@ def ParseFFMPEGVideoFormat( lines ): return ( True, video_format ) -def ParseFFMPEGVideoLine( lines, png_ok = False ): +def ParseFFMPEGVideoLine( lines, png_ok = False ) -> str: if png_ok: @@ -974,7 +976,7 @@ def ParseFFMPEGVideoLine( lines, png_ok = False ): return line -def ParseFFMPEGVideoResolution( lines, png_ok = False ): +def ParseFFMPEGVideoResolution( lines, png_ok = False ) -> tuple[int,int]: try: @@ -1023,7 +1025,7 @@ def ParseFFMPEGVideoResolution( lines, png_ok = False ): raise HydrusExceptions.DamagedOrUnusualFileException( 'Error parsing resolution!' ) -def VideoHasAudio( path, info_lines ): +def VideoHasAudio( path, info_lines ) -> bool: ( audio_found, audio_format ) = HydrusAudioHandling.ParseFFMPEGAudio( info_lines ) @@ -1127,7 +1129,7 @@ class VideoRendererFFMPEG( object ): self.initialize() - def close( self ): + def close( self ) -> None: if self.process is not None: @@ -1224,7 +1226,7 @@ class VideoRendererFFMPEG( object ): - def skip_frames( self, n ): + def skip_frames( self, n ) -> None: n = int( n ) @@ -1243,7 +1245,7 @@ class VideoRendererFFMPEG( object ): - def read_frame( self ): + def read_frame( self ) -> numpy.typing.ArrayLike: if self.pos == self._num_frames: @@ -1300,7 +1302,7 @@ class VideoRendererFFMPEG( object ): return result - def set_position( self, pos ): + def set_position( self, pos ) -> None: rewind = pos < self.pos jump_a_long_way_ahead = pos > self.pos + 60 @@ -1315,7 +1317,7 @@ class VideoRendererFFMPEG( object ): - def Stop( self ): + def Stop( self ) -> None: self.close()