Вопрос или проблема
согласно мануалу ffmpeg, я должен иметь возможность использовать -map_channel для разделения/заглушения каналов
однако, если поток фактически не содержит 2 канала, карта не работает.
01.mp3:
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s
ffmpeg -threads 1 -i 01.mp3 -map_channel 0.0.1 -map_channel -1 01R.mp3
не сработает:
Stream #0:0 -> #0:0 [ch: 1 M] (mp3 -> libmp3lame)
однако, 01R.mp3 все еще будет стерео потоком, который содержит оба канала L и R.
Если я конвертирую mp3 в wav, тогда это становится двухканальным потоком:
ffmpeg -threads 1 -i 01L.mp3 01LR.wav
Stream mapping:
Stream #0:0 -> #0:0 (mp3 -> pcm_s16le)
ffprobe 01LR.wav
Input #0, wav, from '01LR.wav':
Duration: 00:40:20.42, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s
Я могу заглушить/разделить wav файл.
Как я могу заглушить/разделить стерео поток, не конвертируя его сначала в 2-канальный wav файл?
Спасибо
[Исправлено] согласно @LordNeckbeard:
$ ffmpeg -threads 1 -i 01.mp3 -map_channel 0.0.1 -map_channel -1 01R.mp3
ffmpeg version 0.10.12-7:0.10.12-1~precise1 Copyright (c) 2000-2014 the FFmpeg developers
built on Apr 26 2014 09:49:36 with gcc 4.6.3
configuration: --arch=amd64 --disable-stripping --enable-pthreads --enable-runtime-cpudetect --extra-version='7:0.10.12-1~precise1' --libdir=/usr/lib/x86_64-linux-gnu --prefix=/usr --enable-bzlib --enable-libdc1394 --enable-libfreetype --enable-frei0r --enable-gnutls --enable-libgsm --enable-libmp3lame --enable-librtmp --enable-libopencv --enable-libopenjpeg --enable-libpulse --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-vaapi --enable-vdpau --enable-libvorbis --enable-libvpx --enable-zlib --enable-gpl --enable-postproc --enable-libcdio --enable-x11grab --enable-libx264 --shlibdir=/usr/lib/x86_64-linux-gnu --enable-shared --disable-static
libavutil 51. 35.100 / 51. 35.100
libavcodec 53. 61.100 / 53. 61.100
libavformat 53. 32.100 / 53. 32.100
libavdevice 53. 4.100 / 53. 4.100
libavfilter 2. 61.100 / 2. 61.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 6.100 / 0. 6.100
libpostproc 52. 0.100 / 52. 0.100
[mp3 @ 0x115f6e0] max_analyze_duration 5000000 reached at 5015510
Input #0, mp3, from '01.mp3':
Metadata:
title : VTS_01_1
author : BT
copyright : Happy@2006
comment :
encoder : Lavf53.32.100
Duration: 00:40:20.42, start: 0.000000, bitrate: 128 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s
Output #0, mp3, to '01R.mp3':
Metadata:
TIT2 : VTS_01_1
author : BT
TCOP : Happy@2006
comment :
TSSE : Lavf53.32.100
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s
Stream mapping:
Stream #0:0 -> #0:0 [ch: 1 M] (mp3 -> libmp3lame)
Press [q] to stop, [?] for help
Truncating packet of size 1024 to 189ate= 128.0kbits/s
Truncating packet of size 1024 to 1
size= 37820kB time=00:40:20.45 bitrate= 128.0kbits/s
video:0kB audio:37820kB global headers:0kB muxing overhead 0.001381%
[Исправлено2]:
как я описал выше ffmpeg -i 01.mp3 -map_channel 0.0.1 01R.wav
или ffmpeg -i 01.wav -map_channel 0.0.1 01R.mp3
сработает. Но ffmpeg -i 01.mp3 -map_channel 0.0.1 01R.mp3
не сработает.
Я нашел способ сделать моно канал mp3, добавив -ac 1:
ffmpeg -i 01.mp3 -ac 1 -map_channel 0.0.1 01R.mp3
Однако, использование -map_channel -1
для заглушения одного канала в стерео выходном потоке все еще не работает.
Заглушение канала
Этот пример берет стерео вход и глушит левый канал. Выход остается стерео:
ffmpeg -i stereo.wav -map_channel -1 -map_channel 0.0.1 output.wav
- Этот пример из FFmpeg Wiki: Audio Channel Manipulation.
- Смотрите опцию
-map_channel
в документации FFmpeg.
Стерео канал в моно
Этот пример создает моно выход из левого канала стерео входа:
ffmpeg -i stereo.mp3 -map_channel 0.0.0 left.wav
- Используйте
-map_channel 0.0.1
, если вам нужен правый канал вместо этого.
Или вы можете использовать аудиофильтр pan:
ffmpeg -i stereo.m4a -af "pan=1:c0=c0" left.flac
- Используйте
pan=1:c0=c1
, если вам нужен правый канал вместо этого.
Ответ или решение
Теория
Работа с аудиопотоками в FFmpeg предоставляет широкие возможности для манипуляции каналами, что может быть актуально для задачи разделения или заглушения стерео каналов. При этом важно учитывать специфику кодека MP3 и команд FFmpeg, которые вы собираетесь использовать.
FFmpeg предоставляет достаточно мощный набор инструментов для манипуляции аудиоканалами через опцию -map_channel
. Данная команда позволяет, среди прочего, маршрутизировать каналы аудиопотока, вырезать один из них или создавать из стерео потока моно.
Одной из сложностей работы с аудио в MP3 формате заключается в том, что MP3 не всегда позволяет легко работать с аудиоканалами на уровне битстрима, что в конечном итоге приводит к необходимости конвертации в другой формат, такой как WAV, где доступ к каналам осуществляется более прозрачно.
Пример
Рассмотрим конкретный пример. Вы сталкиваетесь с проблемой необходимости мьютирования одного из каналов звукового файла в формате MP3, но при этом желаете избежать промежуточной конвертации в другой формат.
При попытке выполнения команды для мьютирования правого канала в MP3, может наблюдаться неудача:
ffmpeg -i 01.mp3 -map_channel 0.0.1 -map_channel -1 01R.mp3
Здесь -map_channel 0.0.1
определяет назначение правого канала на выходе, в то время как -map_channel -1
должен был бы мьютировать один из каналов. Однако именно кодек MP3 усложняет задачу — результатом может стать отсутствие преобразований аудиосигнала.
Для решения данной задачи без конвертации в формат WAV можно воспользоваться фильтром панорамирования (-af "pan"
). Этот фильтр позволяет более гибко управлять аудиоканалами и может обойти ограничения MP3.
Применение
Вот как можно реализовать нужный функционал при помощи фильтра панорамирования:
Мьютирование одного из каналов
Если ваша задача — заглушить один из каналов в стерео аудиопотоке, вы можете использовать следующий подход:
ffmpeg -i 01.mp3 -af "pan=stereo|c0=0|c1=c1" 01_muted_left.mp3
В указанной команде используется фильтр pan
, где c0=0
заглушает левый канал, а c1=c1
оставляет правый канал без изменений.
Перевод стерео в моно
Если необходимо извлечь конкретный канал и сохранить его в моно аудиопотоке, используйте такую команду:
ffmpeg -i 01.mp3 -af "pan=mono|c0=c0" mono_left.wav
Эта команда извлекает левый канал из стерео, и выходной файл записывается в моно. Альтернативно для извлечения правого канала используйте c0=c1
.
Советы по оптимизации
- Учитывайте, что повторные вызовы FFmpeg с различными фильтрами могут загружать систему, особенно на больших аудиофайлах. По возможности, объединяйте преобразования в одну команду.
- Проверяйте корректность выходных файлов с помощью
ffprobe
, чтобы убедиться, что необходимые аудиоканалы корректно обрабатываются. - Всегда тестируйте команды на небольших фрагментах или копиях ваших данных, чтобы избежать потери информации из-за ошибок в конфигурации.
Таким образом, подход к манипуляции каналами стерео потока можно реализовать несколькими способами в зависимости от специфики формата и требуемого результата. Естественно, использование pan
часто становится наиболее простым и эффективным средством, особенно для работы с файлами MP3, где прямое маппирование каналов может встретить ограничения.