Пакетний витяг аудіо з avconv без перекодування


14

У мене близько 70 mp4 файлів, і я хочу витягнути аудіофайли безпосередньо, не перекодуючи далі. Усі файли mp4 мають аудіофайли AAC.

Я розумію, що я можу використовувати наступну команду для отримання аудіофайлу з одного з mp4-файлів:

avconv -i "INPUT FILE" -map 0:1 -c:a copy "OUTPUT FILE"

Як витягнути всі аудіофайли з усіх файлів 70 mp4, щоб я закінчив 70 файлів aac?

Відповіді:


21

Ви можете використовувати простий цикл:

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викресленим від кінця.


2
IIRC, неочищені файли AAC не можуть містити метадані; якщо ви хочете зберегти метадані від оригінальних файлів, тоді використовуйте m4a (це просто інша назва mp4, але аудіоплеєри досить широко визнані) замість aac як розширення файлу.
зол

Для чого варіант -map? Чому ви обираєте потік 0: 1, а не інші потоки, такі як 0: 0, 0: 2?
qed

Я скинув варіант -map, і він працює просто чудово
qed

щоб використовувати цю команду в налаштуваннях Thunar користувальницьких дій і подібних, вона працює, якщо її додати до сценарію та в Thunar дії: bash /path/to/the/script %F- як тут

2
@qed: падіння -mapвсе ще може спричинити розгляд відео при переключенні на інший вихідний формат (якщо цей формат може містити як аудіо, так і відео). Безпечніше тримати його таким, яким він є.
д-р. Sybren

5

Відповідь Сяо, як правило, найбільш корисна, якщо у вас є всі файли в одному каталозі; але якщо є файли MP4, розкидані в різних каталогах, ви можете скористатися цією findкомандою для їх перетворення.

find . -type f -name '*.mp4' -exec bash -c 'avconv -i "$0" -c:a copy "${0/%mp4/m4a}"' {} \;

Для цього використовується дещо інша форма підстановки рядків bash в кінці: "$ {0 /% mp4 / m4a}" вказує bash замінити mp4 m4a, але тільки якщо mp4 знаходиться в кінці рядка.


Я ніколи не знав, що у Баша був такий тип заміни. Дивовижно :)
Ендрю Гуннерсон

1
@xiao Якщо ви не залишите %, він зробить підміну для першого екземпляра рядка, який він знайде; ви також можете використовувати #його для підстановки рядка, лише якщо він знаходиться на початку змінної; тому $ {0 / mp4 / m4a} замінить перший екземпляр mp4 на m4a (що може бути проблемою, якщо у вас справді дивні назви файлів); і $ {0 / # mp4 / m4a} замінить mp4 m4a, але лише якщо значення рядкової змінної починається з mp4 (тут немає ніякого використання, очевидно, але це може стати в нагоді в іншому місці).
зол

3

Щоб уникнути обробки декількох файлів одночасно (які можуть використовувати занадто багато ресурсів), використовуйте parallel. За замовчуванням вона виконує лише одну роботу за один раз. Якщо ви хочете паралельно використовувати кілька ядер CPU, спробуйте паралельно 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 до останнього (кажучи: "raw файли AAC не можуть містити метадані; якщо ви хочете зберегти метадані від вихідних файлів, тоді використовуйте m4a (який це лише інша назва для mp4, але досить широко визнана аудіоплеєрами) замість aac як розширення файлу ' ).

Я використовую такі команди в налаштуваннях Thunar,

введіть тут опис зображення

обмеження програми на відео, які містять aacзвук.

введіть тут опис зображення

Щоб під час обробки було відкрито вікно терміналу, яке закривається в кінці, команду можна змінити так:

 gnome-terminal -e "parallel avconv -i '{}' -map 0:1 -c:a copy '{.}.m4a' ::: %F"

2

Я продовжив відповідь @ 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.