Como obter a duração do vídeo em segundos?


69

Como posso obter a duração do vídeo em segundos?

O que eu tentei:

ffmpeg -i file.flv 2>&1 | grep "Duration"
  Duration: 00:39:43.08, start: 0.040000, bitrate: 386 kb/s


mediainfo file.flv | grep Duration
Duration : 39mn 43s

É isso que fecha, mas não é tão preciso, 2383 é 39,71 minutos

ffmpeg -i file.flv 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }'
2383

Respostas:


36

Para obter minutos, é necessário dividir 2383 segundos por 60.

39.7167

e multiplique a parte fracionária 0,7167 por 60 para obter os segundos restantes.

43.002

Então são 39 minutos, 43 segundos. O aplicativo parece estar fornecendo um valor exato.


96

Basta usar ffprobediretamente. Não há necessidade de sed, grepetc. Existem várias "durações" que você pode adquirir (dependendo da sua entrada).

Duração do formato (contêiner)

$ ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4

30.024000

A adição da -sexagesimalopção utilizará o formato da unidade de tempo HOURS: MM: SS.MICROSECONDS:

0:00:30.024000

Duração do fluxo de vídeo

$ ffprobe -v error -select_streams v:0 -show_entries stream=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4
30.000000

Os comandos acima são do FFmpeg Wiki: Dicas do FFprobe .

Com ffmpeg

Pode ser necessário decodificar completamente a entrada se você achar que a duração do contêiner ou do fluxo está ausente ou imprecisa (possivelmente devido a um arquivo danificado ou truncado).

$ ffmpeg -i input.mp4 -f null -
  …
  frame= 1587 fps=0.0 q=0.0 Lsize=N/A time=00:01:03.48 bitrate=N/A

Neste exemplo time=00:01:03.48é a duração:

Quanto tempo isso levará, é claro, dependerá da complexidade e duração da decodificação de sua entrada e dos recursos do seu computador.


Estes não funcionam para arquivos
.m2v

@utdev Consulte a ffmpegseção " Com ".
Llogan

Sua terceira solução me dá um tempo errado, meu vídeo tem um comprimento de 1:19:00 mas o comando retorna Me Time = 01: 09: 15.32, você tem um palpite porque isso está acontecendo
utdev

Muito útil a duração do fluxo de mídia. Obrigado.
Estamos Borg

Para quem usa o avprobe, os parâmetros são um pouco diferentes: avprobe -v error -show_format_entry duration. \ Sample.mp4
Brad

33

Se você tiver ffmpeg, você também deve ter ffprobe:

ffprobe -i input.file -show_format | grep duration
ffprobe -i input.file -show_format -v quiet | sed -n 's/duration=//p'

Isso também fornecerá frações de segundos, se for um problema, você poderá processar isso com o sed.


como posso remover a parte da fração de segundos?
Tina J

@TinaJ Basta canalizá-lo com printf, como | xargs printf %.0f- isso retornará um valor inteiro.
Ilia Rostovtsev

3

Para o meu ffmpeg-0.6.5-1.el6.rf.x86_64, para obter apenas o segundo, o formato do comando ffprobe é:

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p' 

como posso remover a parte da fração de segundos?
Tina J

3

Solução com mplayer que fornece segundos diretamente:

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'

2
mediainfo --Output='General;%Duration%' file.flv

Isso gera a duração em milissegundos como um único valor inteiro. Não há necessidade de grep / cut / sed / ...


Obrigado - era exatamente o que eu estava procurando. Pode ser instalado no MacOS combrew install mediainfo
Alex K

0

Me deparei com a questão de obter alguns metadados estranhos e incorretos de alguns arquivos de vídeo com os quais estava trabalhando e não consegui encontrar um padrão ou qualquer tipo de manipulação usando código e ferramentas como ffmpeg, mp4box, ffprobe, mediainfo, mplayer, para obter a duração real do vídeo.

Identificar a duração real do vídeo era um requisito para um projeto em que eu estava trabalhando, e a única maneira de encontrar o caminho certo era recodificar o arquivo de vídeo usando o ffmpeg e forçando os arquivos codificados a ignorar os metadados do arquivo original, como:

ffmpeg -i INPUT_FILENAME -acodec copy -vcodec copy -map_metadata -1 OUTPUT_FILENAME"

(Isso pode correr mais rápido do que o esperado. Fiquei surpreso, pelo tipo de conteúdo e pelo ambiente que estava usando, o tempo médio foi de 2 segundos)

... e obtenha duração usando uma ferramenta de sua escolha. Eu gosto do mediainfo, btw: - "mediainfo FILE --Inform =" Video;% Duration% "fornece a duração em milissegundos.


Você não forneceu mais informações ou solução melhor do que outras respostas
Sam

0

Se você precisar apenas consultar metadados:

ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4

[...]

streams.stream.0.duration="5221.146009"

[...]

Então você pode analisá-lo:

while read -r; do
  if [[ "$REPLY" =~ ^streams\.stream\.([0-9])+\.duration=\"([^"]+)\"$ ]]; then
    echo -E Duration of stream "${BASH_REMATCH[1]}": "${BASH_REMATCH[2]}"
  fi
done < <(ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4)

Mas se você deseja obter a duração efetiva do contêiner, é necessário decodificá-lo:

AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2

Levará algum tempo de CPU para decodificá-lo, até:

[...]

frame=130527 fps=53271 q=-1.0 Lsize=N/A time=01:27:01.12 bitrate=N/A speed=2.13e+03x
video:152014kB audio:40790kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

Em seguida, você pode analisá-lo:

if [[ "$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2 | head -n 1)" =~ \ time=([0-9]+):([0-9]{2}):([0-9]{2})\.([0-9]+) ]]; then
  declare duration=0 us="${BASH_REMATCH[4]}" t
  for t in "${BASH_REMATCH[@]:1:3}"; do
    ((duration *= 60))
    ((duration += ${t#0} ))
  done
  while [ ${#us} -lt 6 ]; do us+=0; done
  ((us >= 500000)) && ((duration++))
  ((duration)) || ((duration++))
fi
echo -E Duration: "$duration"

-6

Se você quer uma duração PRECISA, esqueça o FFmpeg. Ele fornece apenas uma estimativa com base no tamanho do arquivo e na taxa de bits média. Descobri, em alguns casos, o tempo estimado de duração em 2x!

No Linux, se o arquivo for criado e modificado apenas durante a gravação de vídeo, uma solução alternativa seria usar o tempo de criação e última modificação para calcular a duração, como em:

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'

5
Onde você achou que o ffmpeg é impreciso?
aleb

4
% X é a hora do último acesso. % Y é o tempo desde a última modificação. Isso não diz nada sobre a duração do vídeo.
quer

11
Este parece ser um troll
George Chalhoub
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.