Загрузка данных


def play_animation(display, filename, width=240, height=240, fps=30, fg_color=0xFFFF, bg_color=0x0000):
    bytes_per_row = width // 8
    frame_bytes = bytes_per_row * height
    raw_buf = bytearray(frame_bytes)
    chunk_rows = 20
    chunk_raw_bytes = bytes_per_row * chunk_rows
    chunk_rgb = bytearray(width * chunk_rows * 2)

    fg_h = (fg_color >> 8) & 0xFF
    fg_l = fg_color & 0xFF
    bg_h = (bg_color >> 8) & 0xFF
    bg_l = bg_color & 0xFF

    x_offset = (320 - width) // 2
    y_offset = (240 - height) // 2
    delay_ms = int(1000 / fps) if fps > 0 else 0

    try:
        with open(filename, 'rb') as f:
            while True:
                # Проверяем, не пришла ли команда остановки
                if sp.any():
                    break
                
                # Читаем данные кадра
                read_bytes = f.readinto(raw_buf)
                
                # --- НОВАЯ ЗАЩИТА ---
                # Если прочитано меньше байт, чем нужно для одного полного кадра,
                # значит, файл закончился или он поврежден. Выходим из цикла.
                if read_bytes < frame_bytes:
                    break
                
                t_start = time.ticks_ms()
                display.set_window(x_offset, y_offset, x_offset + width - 1, y_offset + height - 1)
                
                for offset in range(0, frame_bytes, chunk_raw_bytes):
                    chunk_mem = memoryview(raw_buf)[offset : offset + chunk_raw_bytes]
                    decode_chunk_normal(chunk_mem, chunk_rgb, chunk_raw_bytes, fg_h, fg_l, bg_h, bg_l)
                    display.write_data(chunk_rgb)
                
                if delay_ms > 0:
                    elapsed = time.ticks_diff(time.ticks_ms(), t_start)
                    sleep_time = delay_ms - elapsed
                    if sleep_time > 0:
                        time.sleep_ms(sleep_time)
    except OSError:
        print(f"Ошибка: Файл {filename} не найден!")