У меня есть файл mp4 с одной звуковой дорожкой в формате AAC.Я хотел бы преобразовать этот файл mp4 в аудиофайл в формате PCM.Я могу извлечь аудио файл в формате AAC из файла mp4 успешно.Но я не могу декодировать формат AAC в формат PCM.
Следующий код работает без ошибок и сохраняет данные PCM в файл.Но этот звук в формате PCM не может быть открыт ни с каким медиаплеером.Это говорит о том, что файл поврежден.Я попытался декодировать формат AAC в формат PCM с помощью ffmpeg, и с ffmpeg проблем нет.Но я не хочу использовать библиотеку ffmpeg из-за размера библиотеки.
Сначала я попытался указать путь к файлу mp4 для inputfilePath, и выходной файл был успешно создан и сохранен.Но этот выходной файл не открывается ни в одном медиаплеере.
extractAudioFromVideo ("... / input.mp4", "... / output.wav");
Во-вторых, я успешно извлек аудиофайл AAC из файла mp4.И я попытался указать путь к файлу ACC для inputfilePath, и ничего не изменилось в выводе.
extractAudioFromVideo ("... / input.aac", "... / output.wav");
статический void extractAudioFromVideo (@NonNull String inputfilePath, @NonNull String outputFilePath) {
try
{
OutputStream outputStream = new FileOutputStream(outputFilePath);
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(inputfilePath);
MediaCodec mediaCodec = null;
for(int index = 0; index < extractor.getTrackCount(); index++)
{
MediaFormat format = extractor.getTrackFormat(index);
String mime = format.getString(MediaFormat.KEY_MIME);
if(mime.startsWith("audio/"))
{
extractor.selectTrack(index);
mediaCodec = MediaCodec.createDecoderByType(mime);
mediaCodec.configure(format, null, null, 0);
break;
}
}
if (mediaCodec == null)
{
Log.e("Converter", "Can't find audio info");
return;
}
mediaCodec.start();
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
boolean isEOS = false;
while (true)
{
if (!isEOS)
{
int inputIndex = mediaCodec.dequeueInputBuffer(10000);
if (inputIndex >= 0)
{
ByteBuffer buffer = inputBuffers[inputIndex];
int sampleSize = extractor.readSampleData(buffer, 0);
if (sampleSize < 0)
{
Log.d("Converter", "InputBuffer BUFFER_FLAG_END_OF_STREAM");
mediaCodec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
isEOS = true;
}
else
{
mediaCodec.queueInputBuffer(inputIndex, 0, sampleSize, extractor.getSampleTime(), 0);
extractor.advance();
}
}
}
int outputIndex = mediaCodec.dequeueOutputBuffer(info, 10000);
switch (outputIndex)
{
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.d("Converter", "INFO_OUTPUT_BUFFERS_CHANGED");
outputBuffers = mediaCodec.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
Log.d("Converter", "New format " + mediaCodec.getOutputFormat());
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.d("Converter", "dequeueOutputBuffer timed out!");
break;
default:
ByteBuffer buffer = outputBuffers[outputIndex];
/*
// I tried this line of code but it gives the same result.
byte[] chunk = new byte[info.size-info.offset];
int position = buffer.position();
buffer.get(chunk);
buffer.position(position);
outputStream.write(chunk,0,info.size-info.offset);
*/
final byte[] chunk = new byte[info.size - info.offset];
buffer.get(chunk);
buffer.clear();
if (chunk.length > 0)
{
outputStream.write(chunk,0,info.size - info.offset);
}
mediaCodec.releaseOutputBuffer(outputIndex, true);
break;
}
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0)
{
Log.d("Converter", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
break;
}
}
outputStream.flush();
outputStream.close();
mediaCodec.stop();
mediaCodec.release();
extractor.release();
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
Должен ли я сделать что-то большее, чем эта строка кода, чтобы сохранить его в формате PCM, или я сделал что-то не так?