Kod dönüştürmeden avconv ile toplu ses çıkarma


14

Yaklaşık 70 mp4 dosyam var ve daha fazla kod dönüştürmeden ses dosyalarını doğrudan ayıklamak istiyorum. Tüm mp4 dosyalarında aac ses dosyaları bulunur.

Ben mp4 dosyalarından birinden ses dosyasını ayıklamak için aşağıdaki komutu kullanabilirsiniz anlıyorum:

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

Tüm 70 mp4 dosyalarındaki tüm ses dosyalarını nasıl ayıklayabilirim, bu yüzden 70 aac dosyasıyla sonuçlanırım?

Yanıtlar:


21

Basit bir döngü kullanabilirsiniz:

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

veya bir satırda:

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

avconvDosya adının değişkende *.mp4saklandığı gibi adlandırılan her dosya için bir kez çalıştırılır ${i}.

${i%.mp4}anlamına gelir ${i}(örn. dosya adı) .mp4.


2
IIRC, ham aac dosyaları meta veri içeremez; meta verileri orijinal dosyalardan korumak istiyorsanız, aac yerine bir dosya uzantısı olarak m4a (mp4 için başka bir addır, ancak ses çalarlar tarafından oldukça yaygın bir şekilde tanınır) kullanın.
13'te

-Map seçeneği ne işe yarar? Neden 0: 0, 0: 2 gibi diğer akışlardan ziyade 0: 1 akışını seçiyorsunuz?
qed

-Map

Thunar özel eylemleri ve benzerlerinde bu komutu kullanmak için, bir komut dosyasına ve Thunar eylemlerine eklenirse çalışır: bash /path/to/the/script %F- burada olduğu

2
@qed: düşürmek -map, başka bir çıkış biçimine geçtiğinizde videonun dikkate alınmasına neden olabilir (bu biçim hem ses hem de video içeriyorsa). Olduğu gibi tutmak daha güvenlidir.
dr. Sybren

5

Xiao'nun cevabı genellikle tüm dosyalar tek bir dizinde varsa en kullanışlıdır; ancak farklı dizinlere dağılmış MP4 dosyaları varsa, findhepsini dönüştürmek için bu komutu kullanabilirsiniz .

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

Bu, sonunda biraz farklı bir bash dizesi değiştirme biçimi kullanır: "$ {0 /% mp4 / m4a}", bash'ye mp4'ü m4a ile değiştirmesini söyler, ancak yalnızca mp4 dizenin sonundaysa.


Bash'in bu tür bir ikamesi olduğunu hiç bilmiyordum. Harika :)
Andrew Gunnerson

1
@xiao Dışarıda bırakırsanız %, bulduğu dizenin ilk örneği yerine geçer; #dizeyi yalnızca bir değişkenin başlangıcındaysa dizeyi değiştirmek için de kullanabilirsiniz ; bu yüzden $ {0 / mp4 / m4a}, mp4'ün ilk örneğini m4a ile değiştirir (gerçekten garip dosya adlarınız varsa bir sorun olabilir); ve $ {0 / # mp4 / m4a}, m44 yerine mp4'ün yerini alacaktır, ancak yalnızca değişkenin dize değeri mp4 ile başlıyorsa (burada hiçbir faydası yoktur, ancak başka bir yerde kullanışlı olabilir).
evilsoup

3

Aynı anda birden fazla dosyanın işlenmesini önlemek için (çok fazla kaynak kullanabilir) kullanın parallel. Varsayılan olarak, her seferinde yalnızca bir iş yapar. Birden fazla CPU çekirdeğini paralel olarak kullanmak istiyorsanız, paralel parallel -j 4 ...olarak 4 iş deneyin . Ayrıca göz atın man parallel.

sudo apt-get install parallel

Bu satır, aacseçilen videolardan ses dosyalarını ayıklar ve m4akaplara koyar .

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

Doğrudan CLI'de çalışırken %F, girdi dosyalarınızın listesiyle değiştirin . Örn *.mp4.

Esinlenerek bu tarafından, cevap bir önceki cevabı bu soruya ve tarafından evilsoup 'ikincisi (söyleyerek yorumunu: ' çiğ aac dosyaları meta içeremez; sonra (m4a kullanmak orijinal dosyalarından meta tutmak istiyorsanız hangi mp4 için başka bir addır, ancak ses çalarlar tarafından oldukça yaygın bir şekilde tanınmaktadır) aac yerine bir dosya uzantısıdır ' ).

Thunar özel eylemlerinde bu tür komutları kullanıyorum,

resim açıklamasını buraya girin

uygulamayı aacses içeren videolarla sınırlama .

resim açıklamasını buraya girin

İşlem sırasında bir terminal penceresinin açık olması ve sonunda kapanması için komut aşağıdaki gibi değiştirilebilir:

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

2

Çıkış dosyası daha yeni olduğunda dosyaları atlayan bir komut dosyasına dönüştürerek @ Xiao-Long Chen'in cevabını uzattım:

#!/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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.