Ekstrak batch audio dengan avconv tanpa transcoding

14

Saya memiliki sekitar 70 file mp4, dan saya ingin mengekstrak file audio secara langsung tanpa transcoding lebih lanjut. Semua file mp4 memiliki file audio aac.

Saya mengerti saya dapat menggunakan perintah berikut untuk mengekstrak file audio dari salah satu file mp4:

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

Bagaimana cara mengekstrak semua file audio dari semua file 70 mp4, jadi saya berakhir dengan 70 file aac?

oshirowanen
sumber

Jawaban:

21

Anda dapat menggunakan simpel untuk loop:

for i in *.mp4; do
    avconv -i "${i}" -map 0:1 -c:a copy "${i%.mp4}.aac"
done

atau pada satu baris:

for i in *.mp4; do avconv -i "${i}" -map 0:1 -c:a copy "${i%.mp4}.aac"; done

Apa yang dilakukan dijalankan avconvsekali untuk setiap file bernama seperti di *.mp4mana nama file disimpan dalam ${i}variabel.

${i%.mp4}berarti ${i}(mis. nama file) dengan .mp4dilucuti dari ujung.

Andrew Gunnerson
sumber
2
IIRC, file aac mentah tidak dapat mengandung metadata; jika Anda ingin menyimpan metadata dari file asli maka gunakan m4a (yang hanya nama lain untuk mp4, tetapi cukup dikenal luas oleh pemutar audio) alih-alih aac sebagai ekstensi file.
Evilsoup
Untuk apa opsi -map? Mengapa Anda memilih aliran 0: 1 daripada aliran lainnya, seperti 0: 0, 0: 2?
qed
Saya menjatuhkan opsi -map dan berfungsi dengan baik
qed
untuk menggunakan perintah ini dalam tindakan khusus Thunar dan sejenisnya, berfungsi jika ditambahkan ke skrip dan dalam tindakan Thunar: bash /path/to/the/script %F- seperti di sini
2
@qed: menjatuhkan -mapmungkin masih menyebabkan video dianggap saat Anda beralih ke format output lain (jika format itu dapat berisi audio dan video). Lebih aman untuk mempertahankannya apa adanya.
dr. Sybren
5

Jawaban Xiao umumnya paling berguna jika Anda memiliki semua file dalam satu direktori; tetapi jika ada file MP4 yang tersebar di direktori yang berbeda, Anda dapat menggunakan findperintah ini untuk mengonversi semuanya.

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

Ini menggunakan bentuk substitusi string bash yang sedikit berbeda di akhir: "$ {0 /% mp4 / m4a}" memberitahu bash untuk mengganti mp4 dengan m4a, tetapi hanya jika mp4 berada di akhir string.

Evilsoup
sumber
Saya tidak pernah tahu bahwa bash memiliki jenis pengganti seperti itu. Luar biasa :)
Andrew Gunners pada
1
@ xiao Jika Anda meninggalkan %, itu akan melakukan substitusi untuk contoh pertama dari string yang ditemukannya; Anda juga bisa menggunakannya #untuk membuatnya hanya mengganti string jika itu pada awal variabel; jadi $ {0 / mp4 / m4a} akan menggantikan instance pertama dari mp4 dengan m4a (yang bisa menjadi masalah jika Anda memiliki nama file yang sangat aneh); dan $ {0 / # mp4 / m4a} akan menggantikan mp4 untuk m4a, tetapi hanya jika nilai string variabel dimulai dengan mp4 (jelas tidak digunakan di sini, tetapi mungkin berguna di tempat lain).
evilsoup
3

Untuk menghindari beberapa file diproses secara bersamaan (yang mungkin menggunakan terlalu banyak sumber daya), gunakan parallel. Secara default, itu hanya melakukan satu pekerjaan pada satu waktu. Jika Anda ingin menggunakan beberapa inti CPU secara paralel, coba parallel -j 4 ...untuk 4 pekerjaan secara paralel. Lihat juga man parallel.

sudo apt-get install parallel

Baris ini akan mengekstrak aacfile audio dari video yang dipilih dan memasukkannya ke dalam m4awadah.

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

Saat bekerja langsung di CLI, gantikan %Fdengan daftar file input Anda. Misalnya *.mp4.

Terinspirasi oleh jawaban ini , oleh jawaban sebelumnya untuk pertanyaan ini, dan oleh komentar evilsoup untuk yang terakhir (mengatakan: 'file aac mentah tidak dapat berisi metadata; jika Anda ingin menyimpan metadata dari file asli kemudian gunakan m4a (yang hanyalah nama lain untuk mp4, tetapi cukup dikenal luas oleh pemutar audio) bukan aac sebagai ekstensi file ' ).

Saya menggunakan perintah seperti itu dalam tindakan kustom Thunar,

masukkan deskripsi gambar di sini

membatasi aplikasi ke video yang berisi aacaudio.

masukkan deskripsi gambar di sini

Agar jendela terminal terbuka selama pemrosesan, yang ditutup pada akhirnya, perintah dapat diubah seperti:

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

Saya memperluas jawaban @ Xiao-Long Chen, mengubahnya menjadi skrip yang melompati file ketika file output lebih baru:

#!/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
dr. Sybren
sumber