Eu tenho um sistema que grava vídeo em disco e, às vezes, o sistema tem um erro. Estou tentando recriar o sistema de gravação no laboratório, sem a câmera real (é cara e não há peças de reposição), para tentar replicar o padrão de uso que causa o erro.
Estou tendo problemas para domar o ffmpeg.
Fundo:
O vídeo é capturado em um thread continuamente a partir de um URL rtsp: // fornecido pela câmera anexada com este comando:
ffmpeg -i rtsp://192.168.0.10/h264 -c copy -map 0 -f segment -segment_time 900 -segment_format mp4 -segment_atclocktime 1 -strftime 1 /tmp/capture-%s.mp4
Isso funciona e produz arquivos de vídeo com 15 minutos de duração, conforme o esperado.
Problema:
No laboratório, não tenho a câmera nem o rtsp: // stream. Em vez disso, copiei um dos MP4s de captura do sistema real e estou usando isso como uma entrada para o ffmpeg. Algo como:
ffmpeg -stream_loop -1 -i capture-1469547000.mp4 -c copy -map 0 -f segment **-{NEED PARAM}** -segment_format mp4 -strftime 1 /tmp/captest-%s.mp4
O -stream_loop -1
parâmetro faz o que é esperado: ele lê o arquivo de entrada (com 15 minutos de duração) e produz um fluxo de saída infinito. Essa é uma aproximação razoável da leitura do rtsp: // stream.
O que não consigo descobrir é quais parâmetros usar para fazer com que este sistema de laboratório segmente o vídeo em pedaços de 15 minutos de duração, exatamente como o sistema real. O que espero é uma sequência de arquivos de saída, aproximadamente o mesmo tamanho do arquivo de entrada.
Tentativa nº 1
O uso de -segment_time 900
aparece para a) deseja usar o valor do relógio de parede de 15 minutos ou b) será ignorado. Como copiar de um MP4 existente é muito mais rápido do que copiar do rtsp: // stream, o arquivo de captura resultante é composto por muitas cópias do original.
Tentativa # 2
Eu usei esse comando
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 capture-1469547000.mp4
para determinar se o arquivo de entrada possui 13494 quadros.
O uso -segment_frames 13494
parece ser ignorado e a saída não é segmentada.
Tentativa nº 3
Eu li um monte de documentação do ffmpeg e estou perdendo o que preciso ou ele não existe.
O uso -ss *position* -t *duration*
não faz gravação contínua e segmentação de saída.
Peça ajuda
Quais parâmetros devo usar para obter a segmentação para a) trabalho eb) 15 minutos de duração do vídeo?
Possível complicação
Os registros de data e hora (DTS?) No exemplo MP4 não são 'bons', pois esse erro é produzido continuamente:
[segmento @ 0x2abc7c0] DTS não monótono no fluxo de saída 0: 0; anterior: 80990160, atual: -74730276972; mudando para 80990161. Isso pode resultar em carimbos de data / hora incorretos no arquivo de saída. DTS 191648787, próximo: -830336344130 st: 0 descartável inválido PTS 191648787, próximo: -830336344130 st descartável inválido: 0
No entanto, não preciso que os arquivos de vídeo resultantes sejam reproduzidos ou estejam intactos, então estou ignorando isso, a menos que esteja afetando a segmentação que preciso recriar.
Mais informações
versão ffmpeg:
\ # / usr / share / local / bin / ffmpeg -version versão ffmpeg N-79587-g9f9c833 Copyright (c) 2000-2016 the FFmpeg developers construído com o gcc 4.8 (Ubuntu / Linaro 4.8.2-16ubuntu4) configuração: --prefix = / home / t / dev / j / de terceiros / ffmpeg /../ build --cross-prefix = / usr / bin / arm-linux-gnueabihf- --cpu = armv7-a - -disable-shared --enable-static --enable-gpl --enable-pthreads --enable-nonfree --enable-libx264 --enable-filters --extra-libs = -estatic --extra-cflags = - static --enable-cross-compile --target-os = linux --disable-inline-asm --arch = armv7 --disable-debug --disable-altivec --disable-sse --disable-armv6 --disable -armv6t2 --disable-mmx --disable-neon --disable-amd3dnow --disable-thumb --extra-ldflags = -L / home / t / dev / j / terceiros / ffmpeg /../ build / lib --extra-cflags = -I / home / t / dev / j / de terceiros / ffmpeg / ../ build / include --extra-ldflags = -L / home / t / dev / j / de terceiros / ffmpeg / libavcodec --extra-ldflags = -L / home / t / dev / j / de terceiros / ffmpeg / libavdevice --extra-ldflags = -L / home / t / dev / j / terceiros / ffmpeg / libavfilter --extra-ldflags = -L / home / t / dev / j / terceiros / ffmpeg / libavformat --extra-ldflags = -L / home / t / dev / j / de terceiros / ffmpeg / libavresample --extra-ldflags = -L / home / t / dev / j / de terceiros / ffmpeg / libavutil - extra-ldflags = -L / home / t / dev / j / de terceiros / ffmpeg / libswscale --extra-ldflags = -lx264 --extra-ldflags = -lm --extra-ldflags = -ldl --extra- cflags = '- fpic -mthumb'-fpic -mthumb '-fpic -mthumb ' libavutil 55. 22.101 / 55. 22.101 libavcodec 57. 38.100 / 57. 38.100 libavformat 57. 34.103 / 57. 34.103 dispositivo de biblioteca 57. 0.101 / 57. 0.101 libavfilter 6. 44.100 / 6. 44.100 libswscale 4. 1.100 / 4. 1.100 libswresample 2. 0.101 / 2. 0.101 libpostproc 54. 0.100 / 54. 0.100
-break_non_keyframes 1
não muda o comportamento. :-( Todas as combinações de {stream_loop, concat} x {<null>, break_non_keyframes} o comportamento é o mesmo: existe um primeiro segmento criado com aproximadamente o dobro do tamanho do arquivo de entrada (eu não estava esperando o suficiente ontem) , e o segundo segmento parece crescer sem limite, para pelo menos mais de 3x o tamanho do primeiro segmento. O tempo de vídeo da entrada não está sendo respeitado. Vou examinar os DTS não monótonos 'erros mais de perto.'Eu tenho uma solução funcional.
A causa raiz
O arquivo de captura de amostra que eu salvei acabou por não ser 'bom' para os propósitos que eu quero (um fluxo de entrada infinito), embora seja um bom arquivo de vídeo de outra forma (ele funciona bem, embora não seja possível procurar). O problema parece estar relacionado aos carimbos de data e hora e, possivelmente, a um ou mais erros do muxer de segmento.
A solução
Eu corri
Usando, em
captemp.mp4
vez disso, recebo um bom fluxo com stream_loop ou o concat muxer.Não sei qual é a diferença entre capture-1469547000.mp4 e captemp.mp4; AtomicParsley mostra captemp.mp4 é 12 bytes mais curto no átomo 'elst'.
Olhar novamente para minha configuração original e adicionar
segment_list
foi revelador: os segmentos estavam sendo gerados corretamente, mas muito rapidamente. Eles estavam apenas sendo anexados ao arquivo de segmento existente em vez de criar um novo. Isso é parcialmente culpa de ...bug em potencial do strftime
Eu estava usando
strftime
com um%s
formato. O strftime acabou usando a hora do relógio da máquina host, em vez da hora do segmento de vídeo. Isso é verdade mesmo no caso de 'trabalho'; Em vez disso, mudei para a%d
formatação do muxer de segmento .Provavelmente, isso é um bug, e por que, no caso não útil, os segmentos foram anexados um ao outro.
Estou bastante certo de que o uso do
-re
sinalizador contornaria esse problema, retardando o processamento, mas na verdade eu quero um processamento acelerado. Então, eu não tentei isso.fonte