Tengo una lista de .ts
archivos:
out1.ts ... out749.ts out8159.ts out8818.ts
¿Cómo puedo obtener la duración total (tiempo de ejecución) de todos estos archivos?
shell-script
video
k961
fuente
fuente
Respuestas:
No tengo
.ts
aquí pero esto funciona.mp4
. Useffprobe
(parte deffmpeg
) para obtener el tiempo en segundos, por ejemplo:así que para todos los
.mp4
archivos en el directorio actual:a continuación, utilizar
paste
para pasar la salida abc
y obtener el tiempo total en segundos:Entonces, para los
.ts
archivos que podrías probar:Otra herramienta que funciona para los archivos de video que tengo aquí es
exiftool
, por ejemplo:Longitud total de todos los
.mp4
archivos en el directorio actual:También puede canalizar la salida a otro comando para convertir el total
DD:HH:MM:SS
, consulte las respuestas aquí .O use
exiftool
el internoConvertDuration
para eso (aunque necesita una versión relativamente reciente):fuente
ffprobe
antes.paste
ybc
! mucho más limpio que conawk
digamos.bc
hará una precisión arbitraria, un inconveniente es que...| paste -sd+ - | bc
alcanzará el límite de tamaño de línea en algunasbc
implementaciones (por ejemplo,seq 429 | paste -sd+ - | bc
falla con OpenSolarisbc
) o tendrá el potencial de usar toda la memoria en otras.avprobe
en los repositorios de Arch (prolly porque entra en conflicto conffmpeg
), así que no puedo probarlo en ATM, pero ¿te da la duración del archivo si lo ejecutas así:avprobe -show_format_entry duration myfile.mp4
oavprobe -loglevel quiet -show_format_entry duration myfile.mp4
? Creo que uno de estos comandos debería darle una sola línea de salida con la duración del archivo. Aunque no estoy seguro.Esto usa
ffmpeg
e imprime el tiempo de espera en segundos totales:Explicación:
for f in *.ts; do
itera cada uno de los archivos que termina en ".ts"ffmpeg -i "$f" 2>&1
redirige la salida a stderrgrep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' '
aísla el tiempoawk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
Convierte el tiempo en segundos.times+=("$_t")
agrega los segundos a una matrizecho "${times[@]}" | sed 's/ /+/g' | bc
expande cada uno de los argumentos y reemplaza los espacios y los canaliza abc
una calculadora Linux comúnfuente
Simplificando la respuesta de @ jmunsch , y usando la respuesta
paste
que acabo de aprender de @ slm , podría terminar con algo como esto:Al igual que jmunsch, estoy usando
ffmpeg
para imprimir la duración, ignorando el error sobre un archivo de salida faltante y en su lugar buscando la salida de error para la línea de duración. Yo invocoffmpeg
con todos los aspectos de la configuración regional forzados a la configuración regional C estándar, para que no tenga que preocuparme por los mensajes de salida localizados.Luego estoy usando un single en
awk
lugar del suyogrep | grep | head | tr | awk
. Esaawk
invocación busca la línea (con suerte única) que contieneDuration:
. Usando dos puntos como separador, esa etiqueta es el campo 1, las horas son el campo 2, los minutos archivados 3 y los segundos campo 4. La coma final después de los segundos no parece molestarmeawk
, pero si alguien tiene problemas allí, él podría incluir untr -d ,
en la tubería entreffmpeg
yawk
.Ahora viene la parte de slm: estoy usando
paste
para reemplazar las nuevas líneas con signos más, pero sin afectar la nueva línea final (al contrario de lotr \\n +
que tenía en una versión anterior de esta respuesta). Eso da la expresión de suma que se puede alimentarbc
.Inspirado por la idea de slm de usar
date
para manejar formatos similares al tiempo, aquí hay una versión que lo usa para formatear los segundos resultantes como días, horas, minutos y segundos con parte fraccional:La parte interior
$(…)
es exactamente como antes. Utilizando la@
carácter como una indicación, usamos esto como el número de segundos desde el 1 de enero de 1970. La "fecha" resultante se formatea como día del año, hora y nanosegundos. A partir de ese día del año, restamos uno, ya que una entrada de cero segundos ya conduce al día 1 de ese año 1970. No creo que haya una manera de obtener los recuentos del día del año comenzando en cero.La final
sed
elimina los ceros finales adicionales. ConTZ
suerte, la configuración debería forzar el uso de UTC, para que el horario de verano no interfiera con colecciones de videos realmente grandes. Sin embargo, si tiene más de un año de video, este enfoque aún no funcionará.fuente
No estoy familiarizado con la
.ts
extensión, pero suponiendo que sean algún tipo de archivo de video que pueda usarffmpeg
para identificar la duración de un archivo de esta manera:Luego podemos dividir esta salida, seleccionando solo el tiempo de duración.
Así que ahora solo necesitamos una forma de recorrer nuestros archivos y recopilar estos valores de duración.
NOTA: Aquí para mi ejemplo simplemente copiar mi archivo de muestra
some.mp4
y la llamó1.mp4
,2.mp4
y3.mp4
.Convertir tiempos a segundos
El siguiente fragmento tomará las duraciones de arriba y las convertirá a segundos.
Esto toma nuestras duraciones y las pone en una variable
$dur
, a medida que recorremos los archivos. Eldate
comando se usa para calcular el número de segundos sinusoidal de la época de Unix (01/01/1970). Aquí está eldate
comando anterior desglosado para que sea más fácil de ver:NOTA: El uso
Ejemplodate
de esta manera solo funcionará si todos sus archivos tienen una duración <24 horas (es decir, 86400 segundos). Si necesita algo que pueda manejar duraciones más largas, puede usar esto como una alternativa:Sumando los tiempos
Luego podemos tomar la salida de nuestro
for
bucle y ejecutarlo en unpaste
comando que incorporará+
signos entre cada número, así:Finalmente ejecutamos esto en la calculadora de línea de comando,
bc
para resumirlos:Resultando en la duración total de todos los archivos, en segundos. Por supuesto, esto se puede convertir a otro formato si es necesario.
fuente
date
podría ahogarse siffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
devuelve algo como26:33:21.68
(es decir, duración ≥ 24 horas / 86400 segundos)paste
me llamó la atención. Supongojava -classpath $(find -name \*.jar | paste -sd:)
que va a ser muy útil para mí, teniendo en cuenta los trucos que usé para esto en el pasado.paste
es mi comando favorito 8-)Saliendo de la respuesta aceptada y utilizando la herramienta clásica de pulido inverso UNIX:
Es decir: apelando
+
yp
luego canalizando esodc
y obtendrás tu suma.fuente
bc
se pone demasiado amor Todos están poniendo+
señales entre cada línea (uniéndose+
), mientras que con el pulido inverso puede simplemente tirar un+
extremo yp
eliminarlo;)Asegúrese de tener instalado MPlayer .
fuente
Como ubuntu envía libav en lugar de ffmpeg:
Muy basado en ideas de MvG
fuente
Bueno, todas estas soluciones necesitan un poco de trabajo, lo que hice fue muy simple, 1)
fue a la carpeta deseada y haga clic derecho -> abrir con otra aplicación
Luego seleccione el reproductor multimedia VLC,
aquí hay un ejemplo
1)
2)
3)
Puede ver justo debajo de la barra de herramientas, hay una lista de reproducción [10:35:51] escrita, por lo que la carpeta contiene 10 horas 35 minutos y 51 segundos de duración del total de videos
fuente
Tenía subdirectorios en la carpeta actual, así que tuve que calcular recursivamente la duración:
find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1
fuente