@@ -44,7 +44,7 @@ def __init__(self,
4444 self .width = None
4545 self .dim = None
4646 self .total_bytes = None
47- self .bytes = None
47+ self .file = None
4848 self .audio_filename = None
4949 self .flip_v = None
5050 self .flip_h = None
@@ -81,14 +81,19 @@ def __init__(self,
8181 def __del__ (self ):
8282 self .cleanup ()
8383
84+ def close_file (self ):
85+ if self .file is not None :
86+ self .file .close ()
87+ self .file = None
88+ self .filename = None
89+
8490 def set_filename (self , filename ):
8591 # Delete current audio file if it exists
8692 self .delete_audio ()
8793
8894 if filename is None :
89- # Reset all vars
90- self .filename = None
91- self .bytes = None
95+ # Reset all vars and close the file pointer
96+ self .close_file ()
9297 self .total_bytes = None
9398 self .audio_filename = None
9499 return
@@ -98,10 +103,11 @@ def set_filename(self, filename):
98103
99104 self .filename = os .path .realpath (filename )
100105
101- # Load bytes
102- with open (self .filename , "rb" ) as f :
103- self .bytes = f .read ()
104- self .total_bytes = len (self .bytes )
106+ # Open file
107+ self .file = open (self .filename , "rb" )
108+
109+ # Get total number of bytes
110+ self .total_bytes = os .stat (self .filename ).st_size
105111
106112 # Compute audio file name
107113 file_path , file_main_name = os .path .split (self .filename )
@@ -325,7 +331,8 @@ def compute_audio(self):
325331 f .setnchannels (self .num_channels )
326332 f .setsampwidth (self .sample_bytes )
327333 f .setframerate (self .sample_rate )
328- f .writeframesraw (self .bytes )
334+ for chunk in iter (lambda : self .file .read (4096 ), b"" ):
335+ f .writeframesraw (chunk )
329336
330337 if self .volume != 100 :
331338 # Reduce the audio volume
@@ -344,6 +351,10 @@ def change_filename(self, new_filename):
344351 self .set_filename (new_filename )
345352 self .compute_audio ()
346353
354+ def get_file_bytes (self , address , count ):
355+ self .file .seek (address )
356+ return self .file .read (count )
357+
347358 def get_address (self , ms ):
348359 # Get the size of a single "block" (a row, we only move in increments of 1 row)
349360 address_block_size = self .width * self .color_bytes
@@ -375,8 +386,15 @@ def get_frame_bytestring(self, ms):
375386 picture_bytes += b"\x00 " * 3 * round (- address / self .color_bytes )
376387 address = 0
377388
389+ # Get the maximum number of bytes that could be used for this frame
390+ frame_bytes = self .get_file_bytes (
391+ address = address ,
392+ count = (self .width * self .height * self .color_bytes )
393+ )
394+
378395 full_length = (self .width * self .height * 3 )
379396
397+ idx = 0
380398 for row in range (self .height ):
381399 for col in range (self .width ):
382400 # If we already have a full frame, stop the loops
@@ -387,27 +405,27 @@ def get_frame_bytestring(self, ms):
387405 this_byte = [b'\x00 ' , b'\x00 ' , b'\x00 ' ]
388406 for c in self .color_format :
389407 if c == constants .ColorFmtCode .RED :
390- this_byte [0 ] = self . bytes [ address : address + 1 ] # Red
408+ this_byte [0 ] = frame_bytes [ idx : idx + 1 ] # Red
391409 elif c == constants .ColorFmtCode .RED_INV :
392- this_byte [0 ] = helpers .invert_bytes (self . bytes [ address : address + 1 ]) # Red inverted
410+ this_byte [0 ] = helpers .invert_bytes (frame_bytes [ idx : idx + 1 ]) # Red inverted
393411 elif c == constants .ColorFmtCode .GREEN :
394- this_byte [1 ] = self . bytes [ address : address + 1 ] # Green
412+ this_byte [1 ] = frame_bytes [ idx : idx + 1 ] # Green
395413 elif c == constants .ColorFmtCode .GREEN_INV :
396- this_byte [1 ] = helpers .invert_bytes (self . bytes [ address : address + 1 ]) # Green inverted
414+ this_byte [1 ] = helpers .invert_bytes (frame_bytes [ idx : idx + 1 ]) # Green inverted
397415 elif c == constants .ColorFmtCode .BLUE :
398- this_byte [2 ] = self . bytes [ address : address + 1 ] # Blue
416+ this_byte [2 ] = frame_bytes [ idx : idx + 1 ] # Blue
399417 elif c == constants .ColorFmtCode .BLUE_INV :
400- this_byte [2 ] = helpers .invert_bytes (self . bytes [ address : address + 1 ]) # Blue inverted
418+ this_byte [2 ] = helpers .invert_bytes (frame_bytes [ idx : idx + 1 ]) # Blue inverted
401419 elif c == constants .ColorFmtCode .WHITE :
402- this_byte [0 ] = self . bytes [ address : address + 1 ] # Red
403- this_byte [1 ] = self . bytes [ address : address + 1 ] # Green
404- this_byte [2 ] = self . bytes [ address : address + 1 ] # Blue
420+ this_byte [0 ] = frame_bytes [ idx : idx + 1 ] # Red
421+ this_byte [1 ] = frame_bytes [ idx : idx + 1 ] # Green
422+ this_byte [2 ] = frame_bytes [ idx : idx + 1 ] # Blue
405423 elif c == constants .ColorFmtCode .WHITE_INV :
406- this_byte [0 ] = helpers .invert_bytes (self . bytes [ address : address + 1 ]) # Red inverted
407- this_byte [1 ] = helpers .invert_bytes (self . bytes [ address : address + 1 ]) # Green inverted
408- this_byte [2 ] = helpers .invert_bytes (self . bytes [ address : address + 1 ]) # Blue inverted
424+ this_byte [0 ] = helpers .invert_bytes (frame_bytes [ idx : idx + 1 ]) # Red inverted
425+ this_byte [1 ] = helpers .invert_bytes (frame_bytes [ idx : idx + 1 ]) # Green inverted
426+ this_byte [2 ] = helpers .invert_bytes (frame_bytes [ idx : idx + 1 ]) # Blue inverted
409427
410- address += 1
428+ idx += 1
411429
412430 picture_bytes += b"" .join (this_byte )
413431 else :
@@ -451,6 +469,7 @@ def get_frame_qimage(self, ms):
451469 return qimg
452470
453471 def cleanup (self ):
472+ self .close_file ()
454473 self .delete_audio ()
455474 shutil .rmtree (self .temp_dir )
456475
0 commit comments