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.
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:
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"
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
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
Cree una variable de matriz a partir del archivo de texto times.
file=chapter.txt
while read line
do
time+=($line)
done <"$file"
Corta el video entre los dos marcos negros.
ffmpeg -i "$video" -ss "${time[0]}" -to "${time[1]}" "$dest"/middle-"$filename"."$extension"
Elimine el archivo de texto que ya no necesita y finalice.
rm chapter.txt
fi
done
Banda sonora personalizada
alab28