У меня есть около 70 файлов mp4, и я хочу извлечь аудиофайлы напрямую без дальнейшего перекодирования. Все файлы mp4 имеют аудио файлы aac.
Я понимаю, что могу использовать следующую команду для извлечения аудиофайла из одного из файлов mp4:
avconv -i "INPUT FILE" -map 0:1 -c:a copy "OUTPUT FILE"
Как извлечь все аудиофайлы из всех файлов 70 mp4, поэтому я заканчиваю с 70 файлами AAC?
Для предотвращения нескольких файлов, обрабатываемых одновременно (который мог бы использовать слишком много ресурсов), использовать parallel
. По умолчанию это только делает одно задание за один раз. Если Вы хотите использовать несколько ядер процессора параллельно, попробовать parallel -j 4 ...
для 4 заданий параллельно. Также выезд man parallel
.
sudo apt-get install parallel
Эта строка извлечет aac
звуковые файлы от выбранных видео и помещенный их в m4a
контейнеры.
parallel avconv -i '{}' -map 0:1 -c:a copy '{.}.m4a' ::: %F
При работе прямо в CLI, замене%F
со списком Ваших входных файлов. Например. *.mp4
.
Вдохновленный этим ответом, предыдущим ответом на этот вопрос, и комментарием evilsoup последнему (высказывание: 'сырые данные aac файлы не могут содержать метаданные; если Вы хотите сохранить метаданные из исходных файлов, затем используют m4a (который является просто другим названием mp4, но справедливо широко распознан аудиоплеерами) вместо aac как расширение файла').
Я использую такие команды в пользовательских действиях Thunar,
ограничение приложения к видео, которые содержат aac
аудио.
Чтобы иметь окно терминала открываются во время обработки, которая закрывается в конце, команда может быть изменена как:
gnome-terminal -e "parallel avconv -i '{}' -map 0:1 -c:a copy '{.}.m4a' ::: %F"
Вы можете использовать простой цикл for:
for i in *.mp4; do
avconv -i "${i}" -map 0:1 -c:a copy "${i%.mp4}.aac"
done
или в одну строку:
for i in *.mp4; do avconv -i "${i}" -map 0:1 -c:a copy "${i%.mp4}.aac"; done
Что означает запуск avconv
один раз для каждого файла с именем, подобным *.mp4
] где имя файла хранится в переменной ${i}
.
${i%.mp4}
означает ${i}
(то есть имя файла) с .mp4
, удаленным с конца.
Ответ Xiao является обычно самым полезным, если у Вас есть все файлы в одном каталоге; но если существуют файлы MP4, рассеянные в различных каталогах, можно использовать это find
команда для преобразования их всех.
find . -type f -name '*.mp4' -exec bash -c 'avconv -i "$0" -c:a copy "${0/%mp4/m4a}"' {} \;
Это использует немного отличающуюся форму строковой замены удара в конце: "$ {0 / % mp4/m4a}" говорит удару заменять mp4 m4a, но только если mp4 в конце строки.
Я расширил ответ @ Xiao-Long Chen, превратив его в скрипт, который пропускает файлы, когда выходной файл новее:
#!/bin/bash
for file in *.mp4; do
OUT="${file/.mp4/.m4a}"
if [ "$file" == "$OUT" ]; then
echo "Unable to handle $file" >&2
exit 1
fi
if [ "$OUT" -nt "$file" ]; then
echo "Skipping $file; output file is newer."
continue
fi
echo "Converting \"$file\" -> \"$OUT\""
avconv -loglevel warning -i "$file" -map 0:1 -c:a copy "$OUT"
done