Linux: Como listar todos os arquivos de vídeo com exatamente a resolução de 720p?

0

Eu tenho vários arquivos de vídeo com diferentes resoluções. Agora quero listar apenas os nomes dos arquivos de vídeo com, por exemplo, Resolução de 720p. Eu prefiro um forro na linha de comando do bash e posso receber informações de vídeo úteis, incluindo resolução, quando eu executo:

avconv -i video.mp4

mas essa combinação:

find -exec sh -c 'if [[ "$(avconv -i {}") == *720* ]] ; then echo 720 found; fi;'

produz o erro: exec - missing argument.

Eu sou honesto, eu dificilmente luto com estruturas de comando bash, especialmente comandos combinados. Então, o que está errado na minha string de comando combinada?

Obrigado.

    
por Linuxwhisperer 22.06.2017 / 19:42

3 respostas

1

Talvez este comando complemente o que você está procurando:

for i in *.mp4; do if [[ $(avconv -i $i) =~ .*720.* ]]; then echo $i; fi; done
    
por 22.06.2017 / 20:48
0

No momento, encontrei uma solução utilizável:

 for i in ls *.m??; do sm=$(mediainfo $i | grep Height | sed 's/  //g');if [[ "$sm" == *720* ]]; then printf "Video: %-s $i %-s $sm \n"; fi; done

Aqui eu posso fazer um loop em todos os m ?? arquivos de vídeo e imprimir seu nome, incluindo a condição "720". Sem a parte if eu poderia deixar mostrar todos os vídeos e suas resoluções.

Eu trabalhei nisso com a ajuda de outras respostas aqui.

Quando tento combinar find e exec e a parte do da solução acima, recebo apenas mensagens "E: File read error" como resultado de mediainfo para cada assunto:

 find -exec mediainfo "{}" \; -exec bash -c 'sm=$(mediainfo ${} | grep 720) : ; echo $sm' \;

Como eu disse, a construção 'if' funciona (para o diretório atual), mas tentarei fazer com que ele seja executado também.

    
por 23.06.2017 / 12:31
0

Pode ser surpreendente, mas -exec pode ser usado como um teste em find invocação:

find -type f -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print

O comando acima irá descer para os subdiretórios. Para pesquisar no diretório atual, use apenas -maxdepth 1 , por exemplo:

find -maxdepth 1 -type f -exec …

Observe que ffprobe testará todos os arquivos. Obviamente falhará em arquivos que não sejam de mídia, mas você poderá obter uma mídia que não seja de vídeo (como .jpg ) na saída final. Para evitar isso, alguns testes adicionais em find devem ser usados antes de -exec , por exemplo:

find -maxdepth 1 -type f \( -iname "*.avi" -o -iname "*.mp4" -o -iname "*.mkv" \) -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print

Ou melhor, você pode testar o tipo MIME com file :

find -maxdepth 1 -exec sh -c 'file --mime-type "$1" | grep -q "video/"' sh {} \; -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print

Leia man find para saber mais.

EDITAR:

Este comando (mis) usa avconv , como você pediu:

find -exec sh -c 'file --mime-type "$1" | grep -q "video/"' sh {} \; -exec sh -c 'avconv 2>&1 -i "$1" | grep -q "Stream.*x720"' sh {} \; -print

O problema é que todas as invocações de avconv emitem um erro. Nós simplesmente ignoramos e extraímos as informações de que precisamos. Esta é uma solução um tanto feia. Não tenho certeza se o seu avconv se comporta como meu, talvez seja necessário substituir Stream.*x720 por outro regex.

what is wrong in my combined command string?

  • find -exec requer fechamento com \; ou + ,
  • $( sem ) depois que você editou a pergunta, há "" intercalado (não aninhado) com $() ,
  • *720* pode acionar a globalização do shell, deve ser "*720*" (estou falando de sh , não do shell externo),
  • a saída de avconv que você tenta analisar vai para stderr , acho que você precisa redirecioná-lo antes de poder analisá-lo,
  • e talvez mais alguma coisa.
por 22.06.2017 / 21:29