如何从完整的H264码流中提取一小段H264码流?

问题描述 投票:0回答:1

我将一张大图像切割成许多图块(150,000),然后用FFmpeg以每秒一帧的速度将其编码成.h264文件,并将其放在服务器上。现在我想从.h264文件中随机解码一张图片进行分析。 我本地解码的思路是在剪切图片时记录它们的索引(i,j),然后让解码器根据索引找到.h264中对应的帧,效果还不错。 现在我把.h264放在服务器(minio)上,我只想截取一段码流并解码。这可能吗?

(比如我的.h264总共有10帧,我想解码第5帧并保存。我可以缓存第4到第6帧然后解码吗?)

----------------------这是我用来从服务器捕获一小部分流的代码。--------- --------------------------------------------------

 @lru_cache(1024)
    def read_small_cached(self, start, length, retry=5):
        ''' read cached and thread safe, but do not read too large'''
        if length == 0:
            return b''
        resp = None
        for _ in range(retry):
            try:
                _client = minio_get_client()
                resp = _client.get_object(
                    self.bucket, self.filename, offset=start, length=length)
                oup = resp.read()
                return oup
            except:
                time.sleep(3)
            finally:
                if resp is not None:
                    resp.close()
                    resp.release_conn()
        raise Exception(f'can not read {self.name}')

我尝试了start = 0,length = 10241024100等参数,可以读取部分图片

但是当我使用该函数查找 IDR 帧并获取其位置时,FFmpeg 的解码器认为这是无效资源。

---------------------------------这是我的 find key_frame 的代码-------- ---------------------------------

def get_all_content(file_path, search_bytes):
    """
    查找指定文件中所有与 search_bytes 相同的内容,并将其位置记录在 positions 列表中。

    :param file_path: 要查找的文件路径
    :param search_bytes: 要查找的字节序列
    :return: 包含字节序列位置的列表
    """
    if not file_path or not search_bytes:
        raise ValueError("file_path 和 search_bytes 不能为空")

    search_len = len(search_bytes)
    positions = []

    with open(file_path, 'rb') as fp:
        fp.seek(0, 2)  # 移动到文件末尾 0表示文件移动的字节数,2表示到末尾,这样是为了获取文件的总大小
        file_size = fp.tell()  # 文件大小
        fp.seek(0)  # 回到文件开始

        pos = 0
        while pos <= (file_size - search_len):
            fp.seek(pos)
            buf = fp.read(search_len)
            if len(buf) < search_len:
                break
            if buf == search_bytes:
                positions.append(pos)
            pos += 1

    return positions

我最近才开始了解H264。也许我对bitstream和H264有误解。我希望得到一些指导。预先感谢!

python ffmpeg h.264
1个回答
0
投票

抱歉,这是代码。

def get_all_content(file_path, search_bytes):
"""
查找指定文件中所有与 search_bytes 相同的内容,并将其位置记录在 positions 列表中。

:param file_path: 要查找的文件路径
:param search_bytes: 要查找的字节序列
:return: 包含字节序列位置的列表
"""
if not file_path or not search_bytes:
    raise ValueError("file_path 和 search_bytes 不能为空")

search_len = len(search_bytes)
positions = []

with open(file_path, 'rb') as fp:
    fp.seek(0, 2)  # 移动到文件末尾 0表示文件移动的字节数,2表示到末尾,这样是为了获取文件的总大小
    file_size = fp.tell()  # 文件大小
    fp.seek(0)  # 回到文件开始

    pos = 0
    while pos <= (file_size - search_len):
        fp.seek(pos)
        buf = fp.read(search_len)
        if len(buf) < search_len:
            break
        if buf == search_bytes:
            positions.append(pos)
        pos += 1

return positions

@lru_cache(1024)
def read_small_cached(self, start, length, retry=5):
    ''' read cached and thread safe, but do not read too large'''
    if length == 0:
        return b''
    resp = None
    for _ in range(retry):
        try:
            _client = minio_get_client()
            resp = _client.get_object(
                self.bucket, self.filename, offset=start, length=length)
            oup = resp.read()
            return oup
        except:
            time.sleep(3)
        finally:
            if resp is not None:
                resp.close()
                resp.release_conn()
    raise Exception(f'can not read {self.name}')
© www.soinside.com 2019 - 2024. All rights reserved.