¿Cómo puedo eliminar por lotes de los videos todo el material que viene antes del primer cuadro completamente negro?

Tengo muchos cientos de videos, cada uno de unos minutos de duración y a los que se les agregó una secuencia de introducción y final que me gustaría eliminar automáticamente. Siempre hay un marco completamente negro inmediatamente después de la secuencia de introducción e inmediatamente antes de la secuencia de cierre.

¿Hay alguna manera de detectar por lotes (para todos los videos en una carpeta, macOS High Sierra) y eliminar todo el material que precede al primer cuadro negro en un video? (Tengo la misma pregunta para eliminar la secuencia final, si existe una solución viable).

Gracias.

Respuestas (1)

Puede intentar usar la herramienta de detección de escenas ffprobe para encontrar el tiempo del cuadro negro, luego use ffmpeg para buscar y recortar.

No soy muy bueno con las secuencias de comandos, pero aquí hay algo que puedes probar. ¡Es muy importante que el marco negro sea solo un marco para que esto funcione! Además, la herramienta de escena de ffprobe es muy exigente con las rutas de los archivos, así que asegúrese de que no haya espacios ni caracteres especiales en el nombre del archivo o en la ruta del archivo de cualquiera de los videos que necesite editar.

Copie y pegue el siguiente código en un bash o archivo de script de comando. Voy a caminar a través de cada paso para explicar lo que sucede después.

#!/bin/bash

echo "Enter Source Folder"

read input

cd "$input"

mkdir -p "$input"/output

dir="$input"/output

for video in *; do

if [[ -f "$video" ]]; then

filename="${video%.*}"
extension="${video##*.}"

mkdir "$dir"/"$filename"

dest="$dir"/"$filename"

ffprobe -show_frames -of compact=p=0 -f lavfi "movie="$video",select=gt(scene\,0.9)" -show_entries frame=best_effort_timestamp_time > tmp.txt

sed -e 's/.*best_effort_timestamp_time=\(.*\)|tag:lavfi.scene_score.*/\1/' tmp.txt > chapter.txt
rm tmp.txt

file=chapter.txt
while read line
do
    time+=($line)   
done <"$file"

ffmpeg -i "$video" -ss "${time[0]}" -to "${time[1]}" "$dest"/middle-"$filename"."$extension"

rm chapter.txt

fi

done

Desglose

Determine la carpeta que contiene los videos que desea recortar y configúrela como directorio de trabajo.

#!/bin/bash
echo "Enter Source Folder"
read input
cd "$input"

Crear directorio de salida

mkdir -p "$input"/output
dir="$input"/output

Para cada archivo en la carpeta, haga esto:

  1. asegúrese de que sea un archivo y no una carpeta
  2. guarde el nombre del archivo y la extensión como una variable
  3. crear un nuevo directorio de salida para cada video

    for video in *; do
    if [[ -f "$video" ]]; then
    filename="${video%.*}"
    extension="${video##*.}"
    mkdir "$dir"/"$filename"
    dest="$dir"/"$filename"
    
  4. Encuentre cualquier cuadro que sea 9/10 diferente al cuadro anterior y guarde el tiempo en un archivo txt.

    ffprobe -show_frames -of compact=p=0 -f lavfi "movie="$video",select=gt(scene\,0.9)" -show_entries frame=best_effort_timestamp_time > tmp.txt
    
  5. Limpiar y reemplazar el archivo de texto.

    sed -e 's/.*best_effort_timestamp_time=\(.*\)|tag:lavfi.scene_score.*/\1/' tmp.txt > chapter.txt
    rm tmp.txt
    
  6. Cree una variable de matriz a partir del archivo de texto times.

    file=chapter.txt
    while read line
    do
        time+=($line)   
    done <"$file"
    
  7. Corta el video entre los dos marcos negros.

    ffmpeg -i "$video" -ss "${time[0]}" -to "${time[1]}" "$dest"/middle-"$filename"."$extension"
    
  8. Elimine el archivo de texto que ya no necesita y finalice.

    rm chapter.txt
    fi
    done
    
Hmm... Recibo un error "mkdir: /salida: Permiso denegado mkdir: /salida: No existe tal archivo o directorio". (Intentaré usar a mi hermano, que conoce bien la línea de comandos, para superar esta parte).
Dado que parece ser un problema de permisos, intente ejecutarlo en Sudo