Tenho muitos arquivos de vídeo (flv / mp4) que alteram a resolução no meio do fluxo (720p / 1080p / 640).
Eu gostaria de usar algo como ffmpeg para detectar automaticamente a alteração na resolução e dividir os vídeos em suas cenas individuais, mantendo a qualidade de codificação existente: segmento sem recodificação (Video1-scene1.flv, Video1-scene2.flv , etc).
Eu encontrei vários métodos para dividir o silêncio, a mudança de cena, em cenas negras, mas nada tão simples quanto uma mudança na largura da resolução.
Esses arquivos geralmente fazem com que editores / aparadores de vídeo falhem, e a identificação e remoção manual de cenas de baixa resolução consome muito tempo se eu simplesmente converter o vídeo inteiro em 1080p.
O algoritmo é provavelmente tão simples quanto comparar o quadro atual ao quadro anterior e, se tiverem resoluções diferentes, dividir o vídeo e iniciar um novo segmento.
Alguém pode ajudar por favor?
EXEMPLO DO FICHEIRO (temporarily available)
: Example.flv
Abaixo estão algumas respostas relacionadas:
Cortar peça de arquivo de vídeo da posição inicial para a posição final com o FFmpeg
link
Divida automaticamente grandes arquivos de vídeo .mov em arquivos menores em quadros pretos (mudanças de cena)?
Dividir um vídeo usando o FFMPEG através da detecção de cena
Recursos adicionais:
Usando a solução de Lord Neckbeard, estou anexando o processo (infelizmente muito manual) que eventualmente trabalhei no Windows10. Talvez possa gerar outras ideias em torno do ffmpeg.
(Eu postei uma pergunta separada para quem é GURU o suficiente para: Automatize esse processo ... )
arraste o vídeo para um arquivo de lote que contenha:
ffprobe -v error -show_entries frame=pkt_pts_time,width,height -select_streams v -of csv=p=0 %1 > allkeyframes.txt
(amostra allkeyframes.txt ...)
13.652000,640,480
13.755000,640,480
13.597000,480,360
13.652000,480,360
cole este texto em POWERSHELL:
$o=""
$n=0
foreach($line in (Get-Content allkeyframes.txt)){
$nline = $line.Split(",")
$nline2=($nline[1]+$nline[2])
if ($nline2 -ne $preventry) {
$n0=$nline[0]
$o="$o,$n0"
$n=$n0
}
$preventry = $nline2
}
if ($o.length -gt 1){
echo $o.Remove(0,1) > resolutionchanges.txt
} else {
Write-Host "No resolution changes found" -ForegroundColor Red
}
(resolutionchanges.txt:)
13.597000,25.618000,33.628000,45.598000
digite o seguinte na janela de comando, depois de colar o conteúdo de resolutionchanges.txt e alterar "input.flv" para o nome do vídeo (o Win10 recusou minhas tentativas de agrupar isso):
ffmpeg -i input.flv -map 0 -c copy -segment_times 13.597000,25.618000,33.628000,45.598000 -reset_timestamps 1 -f segment output_%03d.flv