Detecção automática de cena

2

Eu estou procurando um programa que é capaz de dividir o filme em partes, dependendo de uma mudança de cena. Então, se o filme é composto por paisagem florestal e peixes no aquário, então eu quero fazer dois filmes: o primeiro é sobre a floresta, o segundo é sobre peixes. De preferência, o programa está disponível no Linux e tem interface de linha de comando

krvladislav
fonte

Respostas:

5

Tudo o que consegui encontrar até agora:

  • O programa lav2yuv pode detectar alterações de cena:

    -S list.el
    Output a scene list with scene detection
    

    Para que isso funcione, você precisa converter seus arquivos de vídeo para o MJPEG antes:

    ffmpeg -i source.avi -an -vcodec mjpeg destination.avi 
    

  • Há um pedaço de software abandonado chamado shotdetect . É o único programa de linha de comando e código aberto que já encontrei, mas espero que não funcione na maioria dos vídeos.
slhck
fonte
Você sabe alguma coisa sobre o conteúdo dentro desse arquivo? O que os números representam? Meu palpite é que esses são números de quadros - alguma pista, se é isso mesmo?
Utkarsh Sinha
1
o list.el Arquivo? Eu não tenho ideia desde que eu nunca tentei, mas eu acho que são quadros, sim.
slhck
3

Eu encontrei este post há alguns dias atrás, procurando uma solução para dividir clipes automaticamente. Acabei fazendo um script bash. Espero que isso ajude alguém, Desde que a minha pesquisa no google me trouxe aqui em primeiro lugar e eu já era membro da troca de pilha eu decidi postá-lo aqui esperando que ele vai ajudar alguém.

Eu não sei se eu tenho o direito de colocar um aviso, mas você será aconselhado que é dado como é sem garantia e se você (ou isso) mexer em algo, eu não sou resposible. É um dos meus primeiros scripts e eu tenho muito pouca experiência no bash, então se um guru do bash quiser ajustar isso ainda mais, por favor, seja o meu palpite. Sinta-se livre para modificar, compartilhar e usar o script.

Uso: sh ./scenesplit.sh inputfile.mp4

  • O script criará uma pasta com o nome do arquivo de entrada no caminho atual e saída as cenas cutted nele
  • Vai criar um arquivo com o showinfo do ffmpeg
  • A partir deste arquivo, ele irá gerar outro arquivo com o timestamp de cada detecção.
  • O script irá então fazer o loop do ffmpeg para criar uma série de clipes de acordo com o arquivo de registro de data e hora. O primeiro clipe começa em 0 e termina no primeiro timestamp. O último clipe começa no último registro de data e hora e termina final do clipe original.
  • Vai dormir um segundo entre cada cena.

Você pode ajustar a 'sensibilidade' da detecção alterando o valor de gt(scene,0.1). Precisa ser um valor entre 0 e 1. Eles recomendam (é são como eles dizem) entre 0,4 e 0,6, mas 0,1 funciona bem para mim.

O codec de saída é configurado para mp4 com áudio aac a 30fps 720p.

Trabalhe como pretendido (para mim) com arquivos mp4. Não testei com nenhum outro codec.

#/bin/bash

start=0; 
count=0; 
in="$1"
bn="$(basename "$in")"
echo "=============================================================================="
echo "FILE START: $bn"
mkdir "./$bn"

echo "Finding Scene... this might take a while..."
ffmpeg -nostdin -i "$in" -filter:v "select='gt(scene,0.1)',showinfo" -f null - 2>"./$bn/ffout.tmp.txt"

echo "Filtering timestamp... this might take a while..."
grep showinfo "./$bn/ffout.tmp.txt" | grep pts_time:[0-9.]* -o | grep '[0-9]*\.[0-9]*' -o > "./$bn/timestamps.tmp.txt"

scenes=$(wc -l < "./$bn/timestamps.tmp.txt")
echo "Found $scenes scenes"
sleep 1

while IFS= read -r line; do
    echo "---------------------------------------------------------------------------"
    echo "SCENE START: $count/$scenes ($start,$line)"
    ffmpeg -i "$in" -ss "$start" -to "$line" -nostdin -y -vcodec libx264 -acodec aac -g 120 -s 1280x720 -r 30 "./$bn/$bn.($count of $scenes).mp4"
    echo "SCENE DONE:$count/$scenes ($start,$line)"
    echo "---------------------------------------------------------------------------"
    start=$line
    count=$(($count+1))
    sleep 1

done <"./$bn/timestamps.tmp.txt"
echo "---------------------------------------------------------------------------"
echo "LAST SCENE START:$count/$scenes ($start,end)"
ffmpeg -i "$in" -ss "$start" -nostdin -y -vcodec libx264 -acodec aac -g 120 -s 1280x720 -r 30 "./$bn/$bn.($count of $scenes).mp4"
echo "LAST SCENE DONE:$count/$scenes ($start,end)"
echo "---------------------------------------------------------------------------"

echo "FILE DONE: $bn"
echo "=============================================================================="

Espero que isto ajude, llt

Louis Loudog Trottier
fonte
Ótimo roteiro! Ao invés de bn="$(basename "$in")" Eu removi a extensão com bn=${in%.*}
Marcin Raczyński
2

Eu usei Scenalyzer ao vivo com grande sucesso. Ele faz a detecção de cena, mas é uma ferramenta GUI do Windows, não uma linha de comando do Linux:

O ScLive possui divisão automática de cenas durante a captura - cada cena é gravada em seu próprio arquivo .avi em tempo real.   Ele divide as cenas com base no tempo de gravação incorporado nos fluxos DV ou com base no conteúdo óptico.

haimg
fonte