0

私は大きな MPEG (.ts) バイナリ ファイルを持っています。通常は 188 バイトの倍数です。python3 を使用します。毎回 188 バイトを読み取り、解析して必要な値を取得すると、非常に遅いことがわかりました。PID (バイナリ データ) の値を取得するには、188 バイトのパケットごとにトラバースする必要があります。

  • 同時に、MPEG オフライン プロフェッショナル アナライザーを使用すると、すべての PID 値とその合計カウントのリストが、5 分間の TS ファイルで 45 秒以内に取得されます。
  • c や c++ で書かれているかもしれませんが、どれだけ早く見つけられるかわかりません。
  • python multiprocessing を試しましたが、あまり役に立ちません。これは、188 バイトのデータを解析して処理する私の方法が適切でなく、大きな遅延を引き起こしていることを意味します。

`with open(file2,'rb') as f:
data=f.read(188)
if len(data)==0: break
b=BitStream(data)
...   #parse b to get the required value 
...   # and increase count when needed
...
cnt=cnt+188 
f.seek(cnt)`
4

2 に答える 2

1

あなたはクールな男です。次のようにしてみてください。

```import sys
from functools import partial


PACKET_SIZE= 188

def do():
    args = sys.argv[1:]
    for arg in args:
        print(f'next file: {arg}')
        pkt_num=0
        with open(arg,'rb') as vid:
             for pkt in iter(partial(vid.read, PACKET_SIZE), b""):
                 pkt_num +=1
                 pid =(pkt[1] << 8 | pkt[2]) & 0x01FFF
                 print(f'Packet: {pkt_num} Pid: {pid}', end='\r')
         
if __name__ == "__main__":
    do()

各 pid を印刷すると覚えておいてください。遅くなりましたが、3.7 GB の mpegt には 2000 万個のパケットがあります

a@fumatica:~/threefive$ time pypy3 cli2.py plp0.ts 
next file: plp0.ts
Packet: 20859290 Pid: 1081
real    1m22.976s
user    0m48.331s
sys     0m34.323s

各 pid を出力すると、1m22.976s かかります

コメントアウトしたら

   #print(f'Packet: {pkt_num} Pid: {pid}', end='\r')

それははるかに速くなります

a@fumatica:~/threefive$ time pypy3 no_print.py plp0.ts 
next file: plp0.ts

real    0m3.080s
user    0m2.237s
sys     0m0.816s

印刷呼び出しをに変更すると

                 print(f'Packet: {pkt_num} Pid: {pid}')

出力をファイルにリダイレクトし、

3.7GB を解析するのに 9 秒しかかかりません

a@fumatica:~/threefive$ time pypy3 cli2.py plp0.ts > out.pids

real    0m9.228s
user    0m7.820s
sys     0m1.229s

a@fumatica:~/threefive$ wc -l out.pids 
20859291 out.pids

それがあなたを助けることを願っています。

于 2021-09-17T14:38:06.597 に答える