#android #audio #android-mediacodec
#Android #Аудио #android-mediacodec
Вопрос:
До сих пор в моих поисках объединения видео с MediaCodec мне, наконец, удалось выполнить повторную дискретизацию звука с частотой 48 Кбит / с до 44,1 Кбит / с.
Я тестировал объединение видео вместе с двумя видео, первое из которых содержит звуковую дорожку с 2-канальным форматом 22050 Гц, а второе — звуковую дорожку с 1-канальным форматом 24000 Гц. Поскольку мой декодер выдает только 44100 Гц 2 канала необработанного звука для первого видео и 48000 Гц 2 канала необработанного звука для второго, я пересчитал ByteBuffers
то, что декодер второго видео выводит с 48000 Гц до 44100 Гц, используя этот метод:
private byte[] minorDownsamplingFrom48kTo44k(byte[] origByteArray)
{
int origLength = origByteArray.length;
int moddedLength = origLength * 147/160;
//int moddedLength = 187*36;
int delta = origLength - moddedLength;
byte[] resultByteArray = new byte[moddedLength];
int arrayIndex = 0;
for(int i = 0; i < origLength; i =44)
{
for(int j = i; j < (i 40 > origLength ? origLength : i 40); j )
{
resultByteArray[arrayIndex] = origByteArray[j];
arrayIndex ;
}
//Log.i("array_iter", i " " arrayIndex);
}
//smoothArray(resultByteArray, 3);
return resultByteArray;
}
Однако в выходном видеофайле видео воспроизводится с меньшей скоростью при достижении второго видео с пониженной дискретизацией звуковой дорожки. Высота звука осталась прежней, а шум исчез, но звуковые сэмплы просто воспроизводятся медленнее.
Мой выходной формат на самом деле 22050 Гц 2 канала, после первого видео.
РЕДАКТИРОВАТЬ: как будто проигрыватель продолжает воспроизводить звук так, как будто у него частота дискретизации 48000 Гц, даже после того, как он уменьшен до 44100 Гц.
Мои вопросы:
- Как мне решить эту проблему? Потому что я не думаю, что изменение временных меток работает в этом случае. Я просто использую временные метки, предоставляемые декодером, с некоторым смещением, основанным на последней временной метке первого видео.
- Проблема связана с CSD-0
ByteBuffer
s? - Если
MediaCodec
есть возможность изменять битрейт видео «на лету», будет ли возможна новая функция изменения частоты дискретизации звука или количества каналов «на лету»?
Ответ №1:
Оказывается, это было так просто, как ограничение размера моих байт-буферов.
Декодер выдает 8192 байта (2048 сэмплов).
После понижающей дискретизации данные становятся 7524 байтами (1881 сэмпл) — первоначально 7526 байт, но это составляет 1881,5 сэмпла, поэтому я округлил его в меньшую сторону.
Основная ошибка заключалась в этом коде, где я должен приблизить частоту дискретизации к исходной:
byte[] finalByteBufferContent = new byte[size / 2]; //here
for (int i = 0; i < bufferSize; i = 2) {
if ((i 1) * ((int) samplingFactor) > testBufferContents.length) {
finalByteBufferContent[i] = 0;
finalByteBufferContent[i 1] = 0;
} else {
finalByteBufferContent[i] = testBufferContents[i * ((int) samplingFactor)];
finalByteBufferContent[i 1] = testBufferContents[i * ((int) samplingFactor) 1];
}
}
bufferSize = finalByteBufferContent.length;
Где size
ByteBuffer
— длина выходного сигнала декодера и testBufferContents
массив байтов, который я использую для изменения его содержимого (и тот, который был уменьшен до 7524 байт).
Длина результирующего массива байтов по-прежнему составляла 4096 байт вместо 3762 байт.
Переход new byte[size / 2]
на new byte[testBufferContents.length / 2]
эту проблему решен.