2011-04-13 8 views
70

Deseo dividir un video avi grande en dos videos consecutivos más pequeños. Estoy usando ffmpeg.FFmpeg: ¿Cómo dividir el video de manera eficiente?

Una forma es ejecutar ffmpeg dos veces:

ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi 
ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi 

Pero de acuerdo con la página de manual de ffmpeg, puedo hacer más de un archivo ouput de un archivo de entrada utilizando sólo uno línea:

ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi \ 
    -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi 

Mi pregunta es, ¿el enfoque posterior ahorra tiempo de cálculo y memoria?

+3

stackoverflow.com es para cuestiones relacionadas con la programación. Pruebe superuser.com (esta pregunta probablemente se moverá allí, solo necesita algunos votos más). –

+0

, ¿ahorra tiempo? – rogerdpack

+2

cuando se usa la copia "-vcodec -acodec copy" es muy rápido :)) –

Respuesta

54

El wiki de ffmpeg enlaza de nuevo a esta página con referencia a "Cómo dividir el video de manera eficiente". No estoy convencido de esta página responde a esa pregunta, así que lo hice como se sugiere @AlcubierreDrive ...

echo "Two commands" 
time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 -sn test1.mkv 
time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test2.mkv 
echo "One command" 
time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 \ 
    -sn test3.mkv -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test4.mkv 

que da salida a ...

Two commands 
real 0m16.201s 
user 0m1.830s 
sys 0m1.301s 

real 0m43.621s 
user 0m4.943s 
sys 0m2.908s 

One command 
real 0m59.410s 
user 0m5.577s 
sys 0m3.939s 

He probado un archivo HD SD &, después de algunas carreras & un poco de matemáticas.

Two commands SD 0m53.94 #2 wins 
One command SD 0m49.63 

Two commands SD 0m55.00 
One command SD 0m52.26 #1 wins 

Two commands SD 0m58.60 #2 wins 
One command SD 0m58.61 

Two commands SD 0m54.60 
One command SD 0m50.51 #1 wins 

Two commands SD 0m53.94 
One command SD 0m49.63 #1 wins 

Two commands SD 0m55.00 
One command SD 0m52.26 #1 wins 

Two commands SD 0m58.71 
One command SD 0m58.61 #1 wins 

Two commands SD 0m54.63 
One command SD 0m50.51 #1 wins 

Two commands SD 1m6.67s #2 wins 
One command SD 1m20.18 

Two commands SD 1m7.67 
One command SD 1m6.72 #1 wins 

Two commands SD 1m4.92 
One command SD 1m2.24 #1 wins 

Two commands SD 1m1.73 
One command SD 0m59.72 #1 wins 

Two commands HD 4m23.20 
One command HD 3m40.02 #1 wins 

Two commands SD 1m1.30 
One command SD 0m59.59 #1 wins 

Two commands HD 3m47.89 
One command HD 3m29.59 #1 wins 

Two commands SD 0m59.82 
One command SD 0m59.41 #1 wins 

Two commands HD 3m51.18 
One command HD 3m30.79 #1 wins 

archivo SD = 1.35GB flujo de transporte DVB
archivo HD = 3.14GB flujo de transporte DVB

Conclusión

El único comando es mejor si usted está manejando HD, se está de acuerdo con los comentarios de los manuales sobre el uso de -ss después del archivo de entrada para hacer una 'búsqueda lenta'. Los archivos SD tienen una diferencia insignificante.

La versión de dos comandos debe ser más rápida al agregar otro -ss antes del archivo de entrada para la 'búsqueda rápida' seguida de una búsqueda lenta más precisa.

+3

¡Funciona perfecto, felicitaciones a su esfuerzo! – Kartos

+0

Si TS contiene múltiples programas (programas de TV capturados por DVB-T), ¿cómo se puede dividir? Por ejemplo, tengo un archivo TS que contiene football + cooking + cartoon. ¿Cómo puedo dividir este archivo TS en 3 mpg? –

+0

He utilizado su respuesta en mi pregunta aquí (http://stackoverflow.com/questions/41983940/ffmpeg-disassemble-video-into-parts) pero no funcionó, ¿qué crees que estoy haciendo mal? – utdev

-5

Resulta que el tamaño del archivo en el caso posterior sería proporcionalmente equivalente al intervalo de tiempo.

+2

No estoy seguro de que esto responda a la pregunta que planteó el asker: le preocupa el tiempo de cálculo y la memoria, no el tamaño del archivo. –

15

Aquí hay un script útil, ayuda a dividir de forma automática: A script for splitting videos using ffmpeg

#!/bin/bash 
  
# Written by Alexis Bezverkhyy <[email protected]> in 2011 
# This is free and unencumbered software released into the public domain. 
# For more information, please refer to <http://unlicense.org/> 
  
function usage { 
        echo "Usage : ffsplit.sh input.file chunk-duration [output-filename-format]" 
        echo -e "\t - input file may be any kind of file reconginzed by ffmpeg" 
        echo -e "\t - chunk duration must be in seconds" 
        echo -e "\t - output filename format must be printf-like, for example myvideo-part-%04d.avi" 
        echo -e "\t - if no output filename format is given, it will be computed\ 
 automatically from input filename" 
} 
  
IN_FILE="$1" 
OUT_FILE_FORMAT="$3" 
typeset -i CHUNK_LEN 
CHUNK_LEN="$2" 
  
DURATION_HMS=$(ffmpeg -i "$IN_FILE" 2>&1 | grep Duration | cut -f 4 -d ' ') 
DURATION_H=$(echo "$DURATION_HMS" | cut -d ':' -f 1) 
DURATION_M=$(echo "$DURATION_HMS" | cut -d ':' -f 2) 
DURATION_S=$(echo "$DURATION_HMS" | cut -d ':' -f 3 | cut -d '.' -f 1) 
let "DURATION = (DURATION_H * 60 + DURATION_M) * 60 + DURATION_S" 
  
if [ "$DURATION" = '0' ] ; then 
        echo "Invalid input video" 
        usage 
        exit 1 
fi 
  
if [ "$CHUNK_LEN" = "0" ] ; then 
        echo "Invalid chunk size" 
        usage 
        exit 2 
fi 
  
if [ -z "$OUT_FILE_FORMAT" ] ; then 
        FILE_EXT=$(echo "$IN_FILE" | sed 's/^.*\.\([a-zA-Z0-9]\+\)$/\1/') 
        FILE_NAME=$(echo "$IN_FILE" | sed 's/^\(.*\)\.[a-zA-Z0-9]\+$/\1/') 
        OUT_FILE_FORMAT="${FILE_NAME}-%03d.${FILE_EXT}" 
        echo "Using default output file format : $OUT_FILE_FORMAT" 
fi 
  
N='1' 
OFFSET='0' 
let 'N_FILES = DURATION/CHUNK_LEN + 1' 
  
while [ "$OFFSET" -lt "$DURATION" ] ; do 
        OUT_FILE=$(printf "$OUT_FILE_FORMAT" "$N") 
        echo "writing $OUT_FILE ($N/$N_FILES)..." 
        ffmpeg -i "$IN_FILE" -vcodec copy -acodec copy -ss "$OFFSET" -t "$CHUNK_LEN" "$OUT_FILE" 
        let "N = N + 1" 
        let "OFFSET = OFFSET + CHUNK_LEN" 
done 
+1

Mismo comentario va para ti que para SEARAS.Escribir archivos por lotes es útil cuando es absolutamente necesario y cuando no tiene otra opción disponible, porque no es portátil. Por ejemplo, no podrá ejecutar el mismo script en Windows. Cuando hay formas más genéricas/portátiles, se deben evitar los scripts por lotes, para ahorrar el tiempo necesario para portarlos. Como ffmpeg tiene varias formas de resolver este problema, la forma correcta sería usar ffmpeg solo, sin la ayuda de scripts. –

+2

tnx para el script) – gaRex

+0

Buen script. ¿Lo escribiste? ¿Está en GitHub? Me gustaría hacer algunas sugerencias :) – user3155368

1

qué el enfoque más tarde Guardar tiempo de cálculo y la memoria?

No hay una gran diferencia entre esos dos ejemplos que proporcionó. El primer ejemplo corta el video secuencialmente, en 2 pasos, mientras que el segundo ejemplo lo hace al mismo tiempo (usando hilos). No se notará una aceleración particular. Puede leer más sobre creating multiple outputs with FFmpeg

Adicionalmente, en lo que se puede utilizar (en los últimos FFmpeg) es el que puede stream segmenter muxer:

flujos de salida a una serie de archivos separados de duración casi fijo. El patrón del nombre del archivo de salida se puede configurar de manera similar al image2.

0

¿No hizo ist prueba, pero esto parece prometedor:

Basic stream segmenter

Obviamente está dividiendo en segmentos de AVI mismo tamaño, lo que implica hacer estos trozos calidad no suelta o aumentar la memoria o debe ser recalculado

También usa la copia de códec, ¿eso significa que puede manejar flujos muy grandes? Debido a que este es mi problema, quiero descomponer mi avi para poder usar un filtro para eliminar la distorsión. Pero un avi completo funciona durante horas.

3

En mi experiencia, no use ffmpeg para dividir/unir. MP4Box, es más rápido y ligero que ffmpeg. Por favor pruebalo. Por ejemplo, si desea dividir un archivo 1400MB MP4 en dos partes una 700mb puede utilizar el siguiente CMDL: MP4Box -splits 716800 input.mp4 por ejemplo, para la concatenación de dos archivos que se pueden utilizar:

MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4 
+0

¡Esto era exactamente lo que necesitaba! Cuando estaba cortando con ffmpeg, los clips no arrancaban en fotogramas clave y tenían heladas raras en los extremos. Usando MP4Box -splitz hizo el truco! – matt

2

Aquí es un simple archivo del palo de Windows para divide el archivo entrante en 50 partes. Cada parte tiene una duración de 1 minuto. Perdón por ese guion tonto. Espero que sea mejor tener un script de Windows tonto en lugar de no tenerlo en absoluto. Tal vez ayude a alguien. (Basado en "archivo del palo para el bucle" de este sitio.)

set var=0 
@echo off 
:start 
set lz= 
if %var% EQU 50 goto end 
if %var% LEQ 9 set lz=0 
echo part %lz%%var% 
ffmpeg -ss 00:%lz%%var%:00 -t 00:01:00 -i %1 -acodec copy -vcodec copy %2_%lz%%var%.mp4 
set /a var+=1 
goto start 

:end 
echo var has reached %var%. 
exit 
Cuestiones relacionadas