#for-loop #batch-file #ffmpeg
#for-loop #пакетный файл #ffmpeg
Вопрос:
Я сжимаю видео с помощью FFMPEG с помощью однострочного пакетного скриптинга с ЦИКЛОМ FOR. После сжатия я хочу удалить исходный файл.
Этот код отлично выполняет задание сжатия, но исходный файл не удаляется:
for %%i in (*.mp4) do ffmpeg -i "%%i" -vcodec libx265 -crf 28 "%%~ni"-small.mp4amp;amp;del "%%i"
pause
Что я пропустил?
Кстати, это почти идеальная степень сжатия для любых видов обучающих видеороликов, руководств и т. Д. которые заняли ваш жесткий диск.
Комментарии:
1. Попробуйте выполнить предложение, подобное этому:
DO (ffmpeg -i "%%i" -vcodec libx265 -crf 28 "%%~ni-small.mp4" amp;amp; del "%%i")
2. Есть много способов сделать это в дополнение к тому, на который указывает @Squashman. Вы можете использовать «enabledelayedexpansion», чтобы вы могли писать строки, не беспокоясь о том, будут ли они выполнены успешно. Я сам предпочитаю » пакетные функции «. Моя точка зрения? Есть много способов сделать что-то, и вы можете использовать другой метод, если вам нужно больше одной строки.
3. Вам следует улучшить свой способ цитирования, изменить
"%%~ni"-small.mp4
на"%%~ni-small.mp4"
…4. @Squashman, круглые скобки не должны иметь никакого значения; возможно
ffmpeg
, устанавливает его код выхода в ненулевое значение, следовательноamp;amp;
, не выполняет следующуюdel
команду; для тестирования я бы временно использовалamp;
вместоamp;amp;
…
Ответ №1:
Я бы предположил, что эта методология послужит вам лучше:
@For /F "EOL=? Delims=" %%G In ('Dir /B /A:-D "*.mp4" ^| ^
"%__AppDir__%findstr.exe" /IR ".mp4$" ^| ^
"%__AppDir__%findstr.exe" /IRV "-small.mp4$"'
) Do @If Not Exist "%%~nG-small%%~xG" (
ffmpeg.exe -i "%%G" -vcodec libx265 -crf 28 "%%~nG-small%%~xG"
If Not ErrorLevel 1 If Exist "%%~nG-small%%~xG" Del /A /F "%%G")
Идея состоит в том, чтобы получить список каталогов всех файлов с .mp4
расширением. Использование первого findstr
для исключения любых файлов, которые соответствуют коротким (8.3) именам. Затем он передает их через другой findstr
поиск, чтобы исключить любой из тех файлов, которые уже -small
добавлены к их базовому имени. Затем он проверяет, чтобы убедиться, что в этом каталоге нет существующих файлов с тем же базовым именем плюс суффикс -small
базового имени (предотвращение возможной перезаписи). Если все они проходят, ffmpeg.exe
должен быть вызван (при условии ffmpeg.exe
, что он находится в текущем каталоге, внутри %PATH%
или зарегистрирован как исполняемый файл с указанием его местоположения в реестре). После завершения преобразования скрипт проверяет, что возвращенное ErrorLevel
значение было меньше 1
, (чтобы убедиться, что оно прошло успешно), и если да, то существует ли новый файл (с суффиксом -small
базового имени). Если это так, он продолжит удаление, используя Del
команду.
Если вы хотите повторить попытку, используя условные операторы вместо ErrorLevel , тогда это будет выглядеть так:
@For /F "EOL=? Delims=" %%G In ('Dir /B /A:-D "*.mp4" ^| ^
"%__AppDir__%findstr.exe" /IR ".mp4$" ^| ^
"%__AppDir__%findstr.exe" /IRV "-small.mp4$"'
) Do @If Not Exist "%%~nG-small%%~xG" (
ffmpeg.exe -i "%%G" -vcodec libx265 -crf 28 "%%~nG-small%%~xG" amp;amp; (
If Exist "%%~nG-small%%~xG" Del /A /F "%%G"))
Ответ №2:
Я просто ставлю ‘/ f’ после DEL, и он отлично выполняет свою работу. Я не знаю, есть ли какие-либо недостатки принудительного удаления, но это работает.
Последняя строка:
for %%i in (*.mp4) do ffmpeg -i "%%i" -vcodec libx265 -crf 28 "%%~ni"-small.mp4amp;amp;del /f "%%i"
pause
Комментарии:
1. Хотя приятно видеть, что вы решили эту проблему, я использовал
/F
опцию с моейDel
командой в предоставленном мной ответе шестнадцать часов назад! В дополнение к этому я улучшил ваш скрипт и объяснил вам методологию, которую он использовал. Есть ли особая причина, по которой вы не приняли его в качестве предпочтительного решения?2. @Compo Я благодарен за вашу дань уважения, и это определенно лучше, чем мое решение. Но я хотел просто однострочный, который выполняет работу с пониманием того, почему я не могу обойтись без «/ F». Я действительно не обратил особого внимания на то, что вы используете «/ F», потому что весь код слишком сложен для моего понимания. Я пометил ваш ответ как решение.
3. Однострочный код не выполняется быстрее, его труднее читать, и в вашем случае он недостаточно надежен для реального сценария. Я не добавил в свой код ничего, чего там не должно быть, и второй пример тоже однострочный. Я просто разделил длинные строки для удобства чтения.