3 votos

Automator - Shell script - ffmpeg: secuencia de imágenes a vídeo

El terminal puede generar vídeo a partir de una secuencia PNG (0001.png, 0002.png, ...) mediante ffmpeg:

ffmpeg -i %04d.png -r 24 -codec prores output.mov

Pero, ¿cómo puedo indicar el uso de ffmpeg para la secuencia de imágenes de entrada en Automator? Con esta variable no funciona:

for f in "$@"
do
    /opt/local/bin/ffmpeg -i "$f" -r 24 -codec prores ~/Desktop/output.mov
done

Parece que la variable es para el archivo que para la secuencia ... La lista de registro parece como script se ejecuta 10 veces para la secuencia de 10 imágenes. El error probablemente viene del segundo y todos los demás bucles donde se pide sobrescribir lo existente. Pude crear el video sólo con la ruta completa de la secuencia de imágenes como ~/Desktop/PNG_Folder/%04d.png , pero eso no es la solución. script pedía 9 veces la sobreescritura de todas formas (saltando el error con -y oculta el error pero mantiene el proceso en bucle) y necesito, por supuesto, utilizar archivos seleccionados desde el Finder, no especificados en la ruta completa escrita en un script :) Aquí está una pantalla de Automator sólo para asegurarse de que otras cosas se establecen correctamente. Gracias por la ayuda.

enter image description here

Además: el comando original de Terminal permite generar el vídeo en el directorio de secuencias de imágenes. ¿Es esto posible también con el Shell de Automator? También la variable sería mejor si se puede establecer para cualquier nombre de archivo y más formatos que PNG (JPEG, EXR, ...?) para ser más versátil. Gracias.

3voto

user3439894 Puntos 5883

Después de investigar un poco, resulta que el -i opción para ffmpeg toma un solo nombre de archivo y al convertir un número de archivos de imagen a un archivo .mov tiene que ser en forma de, por ejemplo %05d.png . Obviamente, el relleno del numeración secuencial puede ser un número diferente de dígitos y el extensión del tipo de imagen también puede variar.

Entonces, para ello, lo siguiente ejemplo bash código funciona para mí:

Método 1:

A continuación, se supone que el archivos numerados secuencialmente son cuatro dígitos a partir de 0001 , añada todo archivos tienen el mismo extensión .

Procesará todos los archivos con numeración secuencial de cuatro dígitos en el mismo directorio mientras se sobrescribe el output.mov archivo si ya existe.

Cambiar Servicio que recibe seleccionado files or folders en Finder a:

Servicio que recibe seleccionado folders en Finder

Retire el Obtenga los artículos seleccionados del buscador acción ,

Set Pase de entrada: a as arguments en el Ejecutar Shell script acción .

Sustituir el valor por defecto código con lo siguiente ejemplo bash código :

cd "$1" || exit
ext="$(file="$(ls 0001.*)"; echo "${file##*.}")"
/opt/local/bin/ffmpeg -y -i %04d.${ext} -r 24 -codec prores output.mov

El ejemplo bash código arriba se supone que usted está seleccionando sólo una carpeta en Buscador . Para múltiples carpeta selecciones, utilice lo siguiente ejemplo bash código :

for f in "$@"; do
    cd "$f" || exit
    ext="$(file="$(ls 0001.*)"; echo "${file##*.}")"
    /opt/local/bin/ffmpeg -y -i %04d.${ext} -r 24 -codec prores output.mov
done

<strong>Nota: </strong>El <em>ejemplo </em><code>bash</code> <em>código </em>contiene un número limitado de <em>tratamiento de errores </em>. Es responsabilidad del usuario añadir cualquier <em>tratamiento de errores </em>como sea apropiado, necesario o deseado.


Método 2:

Servicio que recibe seleccionado files or folders en Finder

Retire el Obtenga los artículos seleccionados del buscador acción ,

Set Pase de entrada: a as arguments en el Ejecutar Shell script acción .

Suponiendo que el archivos de imagen en Buscador son todos del mismo tipo, en el mismo carpeta y el e.g. output.mov archivo se creará en el mismo carpeta de los seleccionados archivos de imagen ...

Entonces, para ello, lo siguiente ejemplo bash código funciona para mí:

o="output"
e="mov"

d="$(dirname "$1")"
cd "$d" || exit

if [[ ! -e "${o}.${e}" ]]; then
    o="${o}.${e}"
else
    n=2
    for f in ${o} *.${e}; do
        if [[ "${o} ${n}.${e}" == "$f" ]]; then
            n="$(( n + 1 ))"
        fi
    done
    o="${o} ${n}.${e}"
fi

foo="$(date +%s)"
mkdir "/tmp/${foo}" || exit
cd "/tmp/${foo}" || exit

i=1
for f in "$@"; do
    ln -s "$f" "$(printf "%05d" $i).${f##*.}"
    (( i++ ))
done

/opt/local/bin/ffmpeg -i %05d."${f##*.}" -r 24 -codec prores "${d}/${o}"

rm -r "/tmp/${foo}"

<strong>Nota: </strong>El <em>ejemplo </em><code>bash</code> <em>código </em>contiene un número limitado de <em>tratamiento de errores </em>. Es responsabilidad del usuario añadir cualquier <em>tratamiento de errores </em>como sea apropiado, necesario o deseado.

Método 2 Notas:

  • Si el p. ej. output.mov archivo ya existe, un incremento de nombre de archivo a partir, por ejemplo, de output 2.mov y seguir incrementando según sea necesario para que el Automatizador Servicio no falla porque el archivo de salida ya existe. Esto se gestiona principalmente en el if...else...then bloque Sin embargo, las líneas de código anteriores también forman parte de ella.
  • Para lograr el objetivo, se ha creado una directorio se crea en /tmp , llamado así por el número de segundos transcurridos desde el Época Unix Por ejemplo /tmp/1574058046 y es manejado por foo="$(date +%s)" y mkdir "/tmp/${foo}" .
  • Dentro de este temporal directorio a enlace simbólico numerado secuencialmente se crea para cada uno de los archivos de imagen y es manejado principalmente por el for f in "$@"; do ... done bucle .
  • ffmpeg entonces crea el output.mov archivo .
  • El temporal directorio Por ejemplo /tmp/1574058046 es eliminado.
  • Tenga en cuenta que el archivos de imagen deben ser todos del mismo tipo por ejecución, sin embargo, cada ejecución puede utilizar un soporte diferente tipo de archivo de imagen mientras todos sean iguales tipo por carrera. Tal y como está codificado actualmente, no se pueden mezclar diferentes tipos de archivos de imagen por cada ejecución del servicio .

Nota: El Obtener los elementos del buscador especificados acción es sólo para fines de prueba y se borraría antes de guardar el Automatizador Servicio .

enter image description here

0 votos

Me sorprende que no se pueda hacer esto: cd "$(dirname "$1")"; for f in "$@"; do input="$input -i \"$f\""; done; eval "ffmpeg$input -r 24 -codec prores output.mov" . Pensé que ffmpeg puede aceptar varios archivos de entrada utilizando la función -i bandera en múltiples.

0 votos

@vklidu, No importa la convención de nombres de los archivos de imagen de origen. El script está codificado para tomar los elementos seleccionados en Finder y crear un archivo .mov a partir de ellos. Así, por ejemplo Screen Shot 2019-11-18 at 2.01.33 AM.png se convierte en 00001.png sysmlink y Screen Shot 2019-11-18 at 2.02.00 AM.png se convierte en 00002.png sysmlink o 0001.png se convierte en 00001.png sysmlink y 0002.png se convierte en 00002.png sysmlink etc. Este código es de esta manera para manejar ambos escenarios, así como para permitir pasar todos los archivos seleccionados a ffmpeg utilizando -i %05d."${f##*.}" Como ves el código de @CJK no funciona.

1 votos

Me gustaría señalar que no he hecho ninguna afirmación sobre la eficacia de lo que, al fin y al cabo, era una consulta. I pensamiento (de algún vago recuerdo del pasado) que puede y quería consultarlo con @user3439894, que es, con mucho, el más experimentado en scripts de shell. Si hubiera sentido con alguna confianza que el mío sería el camino a seguir, lo habría ofrecido como segunda respuesta. De todos modos, +1 a esta solución, que debe haber sido una yegua para concebir, escribir y probar.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X