#python #python-3.x #mpeg #mpeg2-ts #transport-stream
Вопрос:
У меня большой двоичный файл MPEG (.ts), обычно кратный 188 байтам, я использую python3,когда я каждый раз читаю 188 байт и анализирую, чтобы получить требуемое значение, я обнаружил, что это очень медленно. Я должен пройти через каждый пакет размером 188 байт, чтобы получить значение PID (двоичные данные).
- В то же время, когда я использую любой профессиональный анализатор MPEG offline, они получают список всех значений PID и их общее количество в течение 45 секунд в течение 5 минут в файле TS, где моей программе требуется > 10 минут, чтобы получить то же самое.
- Я не понимаю, как быстро они могут найти, даже если они могут быть написаны на c или c .
- Я пробовал многопроцессорную обработку python, но это не очень помогает. это означает, что мой метод анализа и обработки 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)`
Ответ №1:
Это твой кодовый человек.
Я тоже некоторое время пробовал Bitstream, он медленный.
Модуль cProfile — ваш друг.
С помощью pypy3 я могу проанализировать 3,7 ГБ mpeg-файлов за 2,9 секунды, один процесс.
С Go-lang я могу разобрать 3,7 ГБ за 1,2 секунды.
Комментарии:
1. да, наконец-то я написал код на c , и это довольно быстро, для 24 ГБ это заняло менее 3 минут. Я постараюсь с помощью модуля cProfile получить анализ. позвольте мне проверить pypy3
2. Ты классный мужик.pypy3 быстро глупеет Вот как это сделать на Python
Ответ №2:
Ты классный парень. Попробуй вот так:
```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]) amp; 0x01FFF
print(f'Packet: {pkt_num} Pid: {pid}', end='r')
if __name__ == "__main__":
do()
имейте в виду, что печать каждого pid будет; замедлять вас, в 3,7 ГБ mpeg-файлов содержится 20 миллионов пакетов
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,7 ГБ требуется всего 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
надеюсь, это поможет тебе, парень.
Комментарии:
1. Большое вам спасибо, одна ошибка, которую я допустил, заключается в том, что я использовал f.seek (), который не был нужен, я понял, когда использовал c . Pypy быстрее, чем python, c занял почти половину времени, которое занимает pypy. Я даже слышал о «нумбе». Вы пробовали?
2. Я не пробовал numba, я не собирался использовать pypy3, но я рад, что сделал это. Мой код работает в среднем в 4 раза быстрее. Сейчас я собираюсь проверить нумбу. 🙂