Потоковая загрузка видео с серверов телеграм. Telethon

Задача: скачать только 5мб из видео не зависимо от размера. При этом файл должен быть не битый, т.е спокойно открываться. На один запрос не должно тратиться более 1мб озу.

Проблема в том, что при загрузке через client.iter_download я не могу найти атом moov, который отвечает за расположение кадров, без него видео не загружается корректно. Атомы ftyp и mdat присутствуют. Так же присутствуют атомы stsz, stco, trak. В итоге видео получается битое и не воспроизводится.

Мой код:

if event.video:
            logger.debug("Start processing video...")
            flag = -1
            frames_count = [0, 0]  # all frames, loaded
            ftyp, mdat, stsz, stco, trak = bytearray(), bytearray(), bytearray(), bytearray(), bytearray()
            gen_pos = 0
                
            async for chunk in client.iter_download(media, chunk_size=CHUNK_SIZE):
                pos = 0
                while pos < len(chunk) - 8:
                    part = bytearray(chunk[pos: pos+8])
                    size, atom = struct.unpack('>I4s', part)
                        
                    if size == 1:
                        part.extend(chunk[pos+8: pos+16])
                        size = struct.unpack('>Q', chunk[pos+8: pos+16])[0]

                    if atom == b"ftyp":
                        flag = 0
                        ftyp.extend(part)
                        logger.debug(f"ftyp atom size: {size}")
                            
                    elif atom == b"mdat":
                        flag = 1
                        mdat.extend(part)
                        logger.debug(f"mdat atom size: {size}")
                        
                    elif atom == b"stsz":
                        flag = 2
                        stsz.extend(part)
                        logger.debug(f"stsz atom size: {size}")

                    elif atom == b"stco":
                        flag = 3
                        stco.extend(part)
                        logger.debug(f"stco atom size: {size}")

                    elif atom == b"trak":
                        flag = 4
                        trak.extend(part)
                        logger.debug(f"trak atom size: {size}")
                            
                    else:
                        if flag == 0:
                            if len(ftyp) < 128:
                                ftyp.extend(part)
                        elif flag == 1:
                            is_frame = False
                            if b'\x00\x00\x00\x01' in part or b'\x00\x00\x01':
                                frames_count[0] += 1
                                is_frame = True
                            if len(mdat) < MDAT_SIZE:
                                mdat.extend(part)
                                if is_frame:
                                    frames_count[1] += 1
                        elif 1 < flag < 5:
                            if len(stsz) + len(stco) + len(trak) < MOOV_SIZE:
                                if flag == 2:
                                    stsz.extend(part)
                                elif flag == 3:
                                    stco.extend(part)
                                elif flag == 4:
                                    trak.extend(part)
                    
                    pos += len(part)
                    gen_pos += len(part)

            data = ftyp + mdat + stsz + stco + trak
            logger.debug(data)
            with open(f"temp/{event.id}.h264", "wb") as file:
                for offset, size in zip(stco, stsz):
                    frame = data[offset : offset + size]
                    file.write(b'\x00\x00\x00\x01')
                    file.write(frame)

            logger.debug(f"Frames count | loaded: {frames_count[1]}; all: {frames_count[0]}")

Ответы (0 шт):