145 votes

Comment obtenir la durée d'une vidéo en secondes ?

Comment puis-je obtenir la durée de la vidéo en secondes ?

Ce que j'ai essayé :

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

Ce qui est proche, mais ce n'est pas si précis, 2383 est 39,71 minutes.

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

2voto

Nauman Points 1484

Pour mon ffmpeg-0.6.5-1.el6.rf.x86_64, pour obtenir juste le second, le format de la commande ffprobe est :

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

1voto

satirio Points 1

J'ai rencontré le problème de l'obtention de métadonnées étranges et incorrectes à partir de certains fichiers vidéo avec lesquels je travaillais et je n'ai pas réussi à trouver un modèle ou un type de manipulation en utilisant du code et des outils comme ffmpeg, mp4box, ffprobe, mediainfo, mplayer, pour obtenir la durée réelle de la vidéo.

Identifier la durée réelle de la vidéo était une exigence pour un projet sur lequel je travaillais et la seule façon que j'ai trouvée pour que ce soit toujours correct était de réencoder le fichier vidéo en utilisant ffmpeg et en forçant les fichiers encodés à ignorer les métadonnées du fichier original, comme :

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

(Cela peut aller plus vite que prévu. J'ai été surpris, pour le type de contenu et sur l'environnement que j'utilisais, le temps moyen était de 2 secondes)

... et ensuite obtenir la durée en utilisant un outil à votre choix. J'aime bien mediainfo, btw : - "mediainfo FILE --Inform="Video;%Duration%" vous donne la durée en millisecondes.

1voto

rusty Points 101

Python

Vous pouvez extraire les flux en utilisant le code suivant

import json

infile = "<path to your file>"
command = "ffprobe -v quiet -print_format json -show_format  -show_streams {}".format(infile)
res = json.loads(subprocess.check_output(command, shell=True))
streams = res.get('streams')

Chaque flux aurait un champ duration .

Cas particulier de Webm

Si votre fichier d'entrée est webm, votre méthode d'extraction de la durée du flux sera différente, puisque la norme la stocke à un endroit différent. Dans chaque flux, vous verrez un champ 'tags'.

"tags": {
                "language": "eng",
                "HANDLER_NAME": "ISO Media file produced by Google Inc. Created on: 12/09/2019.",
                "VENDOR_ID": "[0][0][0][0]",
                "ENCODER": "Lavc59.4.101 libvorbis",
                "DURATION": "00:03:14.703000000"
            }

Vous devrez convertir ce format de temps lisible par l'homme en secondes. Ce que vous pouvez facilement faire avec la fonction utilitaire suivante.

def convert_secs(text):
    if isinstance(text, float):
        num = str(text)
        nums = num.split('.')
    else:
        nums = text.split(':')
    if len(nums) == 2:
        st_sn = int(nums[0]) * 60 + float(nums[1])
        return st_sn
    elif len(nums) == 3:
        st_sn = int(nums[0]) * 3600 + int(nums[1]) * 60 + float(nums[2])
        return st_sn
    else:
        raise ValueError("Not correct time")

1voto

# Returns duration (in seconds) of a video $1 (uses ffmpeg).
get_video_duration() {
  OUTPUT=$(ffmpeg -i "$1" -vframes 1 -f rawvideo -y /dev/null 2>&1) ||
    { debug -e "get_video_duration: error running ffmpeg:\n$OUTPUT"; return 1; }
  DURATION=$(echo "$OUTPUT" | grep -m1 "^[[:space:]]*Duration:" |
    cut -d":" -f2- | cut -d"," -f1 | sed "s/[:\.]/ /g") || 
    { debug -e "get_video_duration: error parsing duration:\n$OUTPUT"; return 1; }
  read HOURS MINUTES SECONDS DECISECONDS <<< "$DURATION"
  echo $((10#$HOURS * 3600 + 10#$MINUTES * 60 + 10#$SECONDS))      
}

Utilisation : DURATION=$(get_video_duration "$VIDEO")

0voto

Luchostein Points 129

Si vous avez seulement besoin d'interroger des métadonnées :

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

[...]

streams.stream.0.duration="5221.146009"

[...]

Donc vous pouvez l'analyser :

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)

Mais si vous voulez obtenir la durée effective du conteneur, vous devez le décoder :

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

Il faudra un certain temps au CPU pour le décoder, jusqu'à ce que :

[...]

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

Ensuite, vous pouvez l'analyser :

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"

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X