Может кто-нибудь сказать мне, где я иду не так, делая это.

Идея состоит в том, чтобы найти и преобразовать все файлы в каталоге в m4v. Независимо от расширения. Затем, после того, как он был преобразован, для создания миниатюры из предположительно «соответствующей» части преобразованного файла. Затем, как только это будет сделано, чтобы удалить исходный файл (в идеале, если он меньше, чем оригинальный - однако я еще не понял этот бит). Я очень новичок в сценариях оболочки, поэтому любая помощь будет наиболее ценной.

Затем я хотел бы добавить в будущем имя файла и детали к базе данных MySQL. Если у кого-нибудь есть какие-либо советы по этому поводу, я был бы очень признателен. Также, как добавить в проверку, чтобы пропустить преобразование для файлов, которые уже являются m4v.

#!/bin/bash
#Convert files using ffmpeg
OrDir="/Volumes/Misc/Test/"
NewDir="/Volumes/Misc/Conv2/"

find "$OrDir" -type f -exec /bin/bash -c \
    'f2=$(basename "$1"); \
     ffmpeg -i "$1" -c:v libx264 -crf 23 -preset ultrafast -c:a aac -strict experimental -b:a 192k -ac 2 "${NewDir}${f2%.*}.m4v" ' _ {} \;
     ffmpeg -ss 3 -i "${NewDir}${f2}.m4v" -vf "select=gt(scene\,0.4)" -frames:v 5 -vsync vfr fps=fps=1/600 "${NewDir}pictures/${f2%.*}.jpg"
     rm $1

ОБНОВЛЕНИЕ: я играл с этим много в последние несколько дней, и это то, что я получил в данный момент:

#!/bin/bash
#Convert files using ffmpeg

OrDir="/Volumes/Misc/Test"

find "$OrDir" -type f -exec /bin/bash -c \
    'ND="/Volumes/Misc/Convert/"
     f2=$(basename "$1")
     eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width "$1")
     size=${streams_stream_0_height}
     if [ "$size" -gt 720 ]
     then
         size=720
     fi
     ffmpeg -y -hide_banner -i "$1" -codec:v libx264 -profile:v high -preset ultrafast -b:v 500k -qmin 10 -qmax 42 -maxrate 1000k -bufsize 1000k -threads 0 -vf "scale=-1:$size" -pass 1 -c:a aac -strict -2 -b:a 128k -f m4v /dev$
     ffmpeg -y -hide_banner -i "$1" -codec:v libx264 -profile:v high -preset ultrafast -b:v 500k -qmin 10 -qmax 42 -maxrate 1000k -bufsize 1000k -threads 0 -vf "scale=-1:$size" -pass 2 -c:a aac -strict -2 -b:a 128k "$ND${f2%.*$
     ffmpeg -hide_banner -i "$ND${f2%.*}.m4v" -vf "select=gt(scene\,0.4), scale=-1:135, fps=1/60" -frames:v 5 -vsync vfr "${ND}pictures/${f2%.*}_%03d.png"
     rm $1
     mysql --host=****** --user=***** --password=****** db << EOF
     INSERT INTO tbl (Name, FileType, Time, AddedDate) VALUES ("${f2%.*}", '.m4v', 0, NOW());
     EOF
     ' _ {} \;

Это имеет две проблемы; во-первых, он не всегда генерирует миниатюры, иногда возвращает Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used) однако созданный файл конвертируется отлично, а во-вторых, строка mysql isn ' t выполняется правильно, возвращая ошибку: _: line 12: mysql: command not found Я также еще не выяснил, как определить продолжительность видео, чтобы добавить ее в базу данных.

1 ответ1

0

Если вы планируете расширить этот скрипт - который, исходя из вашего вопроса о базе данных, - я бы порекомендовал параматеризировать как можно больше.

Я также рекомендовал бы использовать ffmpegthumbnailer для генерации миниатюр, что должно быть простой yum install ffmpegthumbnailer / apt-get install ffmpegthumbnailer . Проверьте параметры - в моем скрипте я создаю миниатюру того же размера (-s0), что и оригинал, но вы можете этого не захотеть.

Этот пример сценария должен помочь вам начать:

#!/bin/bash
# Convert files using ffmpeg
# USE AT YOUR OWN RISK!

# Parameters
OrDir="/tmp/video/"             # Original directory
NewDir="/tmp/video/out/"        # New directory
PicsDir=${NewDir}pictures/
ignore="m4v"                    # ignore single filetype being converted
convto="$ignore"                # in case you want to convert to something else
thumbnailseek=5                 # Seek % at which to generate thumbnail

# Change to original directory
# For each file:
#       check appropriate (exists, not directory, not already same type)
#       convert to $convto type media file (ffmpeg)
#       generate thumbnail (ffmpegthumbnailer)
#       (optional) remove original if new version smaller

cd "$OrDir"
for oldfile in *.mkv; do        # indeed every file; globbing will eat up  spaces properly
    ext=${i##*.}
    # ignore 1) non-existant files 2) directories 3) $ignore-extentioned files
    if [[ ! -e "$oldfile" ]] || [[ -d "$oldfile"  ]] || [[ "$ext" = "$ignore" ]]; then
            continue
    fi

    filename=${oldfile%.*}
    newfile="$NewDir$filename.$convto"
    oFS=$(stat --printf="%s" $oldfile) # old file size

    ffmpeg -y -loglevel quiet -i "$oldfile" -c:v libx264 -crf 23 -preset ultrafast -c:a aac -strict experimental -$
    nFS=$(stat --printf="%s" $newfile) # new file size

    ffmpegthumbnailer -s0 -i "$newfile" -t $thumbnailseek -o "$PicsDir$filename.jpg" &>/dev/null
    if [ "$oFS" -gt "$nFS" ]; then
            #rm -- "$OrDir$oldfile" # AT OWN RISK: uncomment to remove older file if smaller
    fi
done

Я не эксперт, как покажет любое тщательное прочтение приведенного выше кода. Я смешал в своих собственных соглашениях по именованию переменных с теми, что были в исходном коде (я намеревался сохранить некоторое знакомство); Я мог бы параметризовать дальше; Я закодировал довольно много предположений в сценарии (например, OrDir содержащий только видеофайлы); некоторые условные проверки могут быть упрощены; Обработка имени файла и каталога может быть сделана единообразной.

Но это не Code Review. Там не должно быть никаких явных ошибок, и это работает локально на некоторых mkvs, которые я прогонял, просто ожидая чего-то подобного.

Если вы намерены сделать гораздо больше с использованием сценариев bash, стоит почитать о некоторых распространенных ошибках bash и, если у вас есть время, руководство по сценариям Advanced Bash.


Для «базы данных SQL» требуется больше информации, чтобы дать любой совет. Что за база данных? SQLite? Почему вообще SQL, а не простой плоский файл (CSV и т.д.)? Какие детали?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .