¿Dividir vídeo MPEG desde la línea de comando?

¿Dividir vídeo MPEG desde la línea de comando?

Tengo un DVD casero en el que estoy intentando insertar capítulos y reorganizarlos; el autor original lo grabó como un capítulo largo y me gustaría dividirlo en partes más pequeñas y volver a codificarlo en un nuevo DVD. Ripeé el DVD con el siguiente comando:

mplayer dvd:// -dispositivo-dvd /dev/sr2 -dumpstream -dumpfile raw.vob

Estoy ejecutando Gentoo Linux con mplayer versión 1.0-rc2_p20090731 (la última disponible en Portage).

Tengo una lista de horarios en los que se supone que deben abarcar los capítulos (por ejemplo, 30:11-33:25), así que mi primer pensamiento fue copiar todo el DVD y usarlo.mpgtxpara recortar ciertas partes del archivo. Mi problema es que la ejecución mpgtx -idel archivo informa bastantes saltos de marca de tiempo:

Las marcas de tiempo saltaron de 59,753789 a 0,001622 en la posición 1d29800
Las marcas de tiempo saltaron de 204963823030450.343750 a 31.165900 en la posición 2d4f800
Las marcas de tiempo saltaron de 60.077878 a 0.001622 en la posición 43cc000
Las marcas de tiempo saltaron de 60.024233 a 0.001622 en la posición 65c5000
Las marcas de tiempo saltaron de 204963823068631.718750 a 52.549244 en la posición 7fd1000

Intenté arreglar los índices usando:

mencoder raw.vob -copia oac -copia ovc -forceidx -o fix.vob -of mpeg

Pero mpgtx seguirá informando problemas con la marca de tiempo. Mi pregunta inmediata: ¿hay alguna manera de tomar la película copiada que tengo y corregir sus marcas de tiempo para poder cortarla con mpgtx? Si puedo solucionar ese problema, crear el resto del DVD será un proceso sencillo.

Si no es posible corregir las marcas de tiempo de este archivo: ¿existe una mejor manera de extraer pequeños fragmentos del DVD en archivos separados para volver a compilarlos más adelante? Me gustaría mucho que esto se hiciera en Linux, y sería incluso mejor si pudiera crear un script de alguna manera (introducir una lista de posiciones de inicio y fin, o horas de inicio y duraciones, y obtener una serie de archivos copiados). archivos). Si es necesario, también tengo disponible una máquina Mac OS X, pero no Windows.

Editar:Terminé encontrando otra solución que involucrabaFreno de manoyffmpeg(con ayuda deesta pregunta), pero la pregunta sigue en pie.

Editar de nuevo:Resulta que mi otra solución no funcionó del todo: el audio se desincronizó en unos cinco segundos, en aproximadamente la mitad de mis mpg recortados, así que volví al punto de partida. ¿Alguien?

Respuesta1

FFmpeg hará esto por usted.

Su comando podría verse así:

Código: ffmpeg -i input.mpg -ss 00:00:10 -t 00:00:30 out1.mpg -ss es el punto de inicio en hh:mm:ss desde el principio de su archivo de video

-t es el período de tiempo en hh:mm:ss de su nuevo segmento.

Entonces, en el ejemplo anterior, comienza 10 segundos desde el principio del archivo original y finaliza 30 segundos después.

Si desea crear varias piezas en una sola pasada, lo siguiente debería funcionar:

Código: ffmpeg -i input.mpg -ss 00:00:10 -t 00:00:30 out1.mpg -ss 00:00:35 -t 00:00:30 out2.mpg En este ejemplo, el primer segmento es Lo mismo que el primer ejemplo, pero también está creando un segundo archivo que comienza en 35 segundos y dura 30 segundos.

.

Respuesta2

Una vez pirateé esto para obtener un video de un DVD-RAM:

#! /usr/bin/ruby -w

a = [0, 0x37f9800, 0xf3e1800]

filename = "input.vob"

a.each_with_index{|seq_start, i|
  if seq_start % 1024 != 0 then
    puts "Error: Blocksize doesn't match 1024"
  end

  seq_end = a[i+1]

  if seq_end then
    puts "dd if=#{filename} of=chapter#{i+1}.mpeg bs=1024 skip=#{seq_start/1024} count=#{(seq_end - seq_start)/1024}"
  else
    puts "dd if=#{filename} of=chapter#{i+1}.mpeg bs=1024 skip=#{seq_start/1024}"
  end
}

La avariable toma los valores de posición donde ocurre el salto y luego simplemente los usa ddpara cortar el archivo en pedazos en esas posiciones. El resultado son archivos MPEG separados para cada capítulo, ya que el salto se producía cada vez que se detenía y reiniciaba la grabación. Los archivos MPEG resultantes se liberaron y luego se pudieron procesar como de costumbre.

El script en sí en realidad no llama dd, simplemente genera los ddcomandos necesarios para dividir el archivo en pedazos.

Respuesta3

num=1
offset=0
divide="Title:"
divide="Chapter:"
input="VTS_01_1.VOB|VTS_01_2.VOB|VTS_01_3.VOB|VTS_01_4.VOB|VTS_01_5.VOB|VTS_01_6.VOB" 
#|VTS_01_7.VOB|VTS_01_8.VOB|VTS_01_9.VOB"

for len in $(lsdvd -c VIDEO_TS | grep "$divide" | awk -F' +|,' '/Length:/ { print $5 }')
do
 ss=$(date -u -d "@$offset" +%T.%3N)

 echo $num $ss $len
 cd VIDEO_TS
 #ffmpeg -ss $ss -i "concat:$input" -t $len -c copy ../$(printf "%02d" $num).VOB 2>/dev/null
 ffmpeg -ss $ss -i "concat:$input" -map 0:1 -map 0:3 -t $len -acodec copy -vcodec libx264 ../$(printf "%02d" $num).mp4 2>/dev/null
 cd ..

 len=$(date -u -d "1970-01-01 $len" +%s.%3N)
 offset=$( echo "$offset + $len" | bc )
 num=$((num+1))
done

información relacionada