Jak mogę wsadowo wyodrębnić audio z plików MP4 za pomocą ffmpeg bez dekompresji (automatyczne wykrywanie kodeków audio)?

19

Mam 228 plików mp4 (2,6 GB) i chciałbym z nich wyodrębnić dźwięk (mp3 lub ogg). Chcę je częściowo wyodrębnić - najlepiej z bash. Nie jestem pewien, czy wszystkie pliki używają tego samego kodeka audio, co zostały nagrane w różnych latach, od 2006-2012.

Chcę przejrzeć je wszystkie, wybrać nazwę pliku, wykryć kodek audio i użyć ffmpeg do wyodrębnienia dźwięku.

Czy to możliwe?

wryrych
źródło
To pytanie dotyczące skryptów i jako takie nie ma nic wspólnego z Ubuntu. Nie jest to nie temat, ale SO lub unix.SE mogą być lepszym miejscem do zapytania.
Mahesh
Dzięki. Następnym razem postaram się zadać takie pytanie w bardziej odpowiednim miejscu.
wryrych,

Odpowiedzi:

29

Mówisz, że chcesz „wydobyć z nich dźwięk (mp3 lub ogg)”. Ale co jeśli dźwięk w pliku mp4 nie jest jednym z nich? i tak musisz transkodować. Dlaczego więc nie pozostawić wykrywania formatu audio ffmpeg?

Aby przekonwertować jeden plik:

ffmpeg -i videofile.mp4 -vn -acodec libvorbis audiofile.ogg

Aby przekonwertować wiele plików:

for vid in *.mp4; do ffmpeg -i "$vid" -vn -acodec libvorbis "${vid%.mp4}.ogg"; done

Możesz oczywiście wybrać dowolne parametry ffmpeg do kodowania dźwięku, które chcesz, aby ustawić takie parametry, jak bitrate i tak dalej.

Użyj -acodec libmp3lamei zmień rozszerzenie z .oggna .mp3do kodowania mp3.

Jeśli chcesz naprawdę wyodrębnić audio, możesz po prostu „skopiować” ścieżkę audio do pliku za pomocą -acodec copy. Oczywiście główna różnica polega na tym, że transkodowanie jest powolne i wymaga dużej mocy obliczeniowej, a kopiowanie jest bardzo szybkie, ponieważ przenosisz bajty z jednego pliku do drugiego. Oto jak skopiować tylko ścieżkę audio (zakładając, że jest w formacie mp3):

ffmpeg -i videofile.mp4 -vn -acodec copy audiofile.mp3

Zauważ, że w tym przypadku format pliku audio musi być zgodny z tym, co ma kontener (tj. Jeśli audio ma format AAC, musisz powiedzieć audiofile.aac). Możesz użyć ffprobepolecenia, aby zobaczyć, jaki masz kodek, może to dostarczyć pewnych informacji:

ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "videofile.mp4"

Możliwym sposobem automatycznego parsowania kodeka audio i odpowiedniego nazwania pliku audio byłoby:

mkdir -p output
# current directory has to contain at least one .mp4 file 
for vid in *.mp4; do
   codec="$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "$vid")"
   case "$codec" in
    mp3    ) filetype=mp3 ;;
    vorbis ) filetype=ogg ;;
    *      ) filetype= ;;
   esac

   if [ "$filetype" ]; then 
    ffmpeg -i "$vid" -vn -acodec copy output/"${vid%.*}"."$filetype"
   else
    ffmpeg -i "$vid" -vn -acodec libvorbis output/"${vid%.*}".ogg
done

Uwagi: pliki wyjściowe są tworzone w podkatalogu, outputktóry tworzy na początku (w razie potrzeby). W przypadku innych kodeków niż mp3 i vorbis konwertuje audio na ogg. Ubuntu 14.04 nie ma ffmpeg w standardowych repozytoriach, ale możesz dodać ppa: mc3man / trusty-media repozytorium i zainstalować pakiet ffmpeg, aby uzyskać potrzebne oprogramowanie. Zobacz tutaj, aby uzyskać szczegółowe informacje.

roadmr
źródło
Źle to ułożyłem. Chciałem mieć mp3 lub ogg, ale jak zauważyłeś, kodek audio był inny - w tym przykładzie aac. Tak czy inaczej muszę je transkodować. Bardzo ci dziękuje za pomoc!
wryrych,
Twój przykład automagiczny zrywa z nazwami plików, które mają spacje, ponieważ nie podałeś $ file w podfunkcji ffprobe. Zmiana na: dla pliku w * mp4 * avi; wykonaj ffmpeg -i „$ plik” -vn -acodec skopiuj „$ plik”. ffprobe "$file" 2>&1 |sed -rn 's/.*Audio: (...), .*/\1/p'; gotowe Naprawiono to.
Andrew Beals,
+1, ale wygląda na to, że ta odpowiedź mogłaby skorzystać z aktualizacji:This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Nicolas Raoul,
ffmpeglub ffprobenie są dostępne dla systemu Ubuntu 14.04 lub nowszego.
jarno
1
@jarno Prawdziwy ffmpeg wrócił do Ubuntu w 15.04 i wygląda jak plewy Libav avconvi avprobezostał usunięty w 15.10 .
llogan
1

Jak stwierdził Nicolas Raoul, wymaga to aktualizacji. Oto ta sama linia, którą dał roadmr, ale zamiast tego użył avconv:

for vid in *.mp4; do avconv -i "$vid" "${vid%.mp4}.mp3"; done

Scooby-2
źródło
To jest już nieaktualne. FFmpeg powrócił i Libav zniknął.
llogan 18.03.16
Absolutnie poprawne. Jeśli ktokolwiek myślał, że ffmpeg umrze, przeczytaj to: en.wikipedia.org/wiki/Libav#Confusion
Scooby-2