首页 > 解决方案 > 如何从 mp3 文件中获取 pcm 数据?

问题描述

我想导入 mp3 文件的 PCM 数据。我尝试了 mediaCodec 但失败了。有没有办法做到这一点?使用 mediaFormat 更改为原始文件,然后使用 mediaCodec 对其进行解码以创建与 mp3 文件大小相同的原始文件。但是,不知道该文件是否正确创建。

File aac = new File(Environment.getExternalStorageDirectory()+"/audio.raw"); 
if(!aac.exists())
                aac.createNewFile();

            FileInputStream fis = new FileInputStream(audioPath);
            BufferedInputStream bis = new BufferedInputStream(fis);

            extractor.setDataSource(audioPath);

            int numTracks = extractor.getTrackCount();

            for (int i = 0; i < numTracks; ++i) {
                format = extractor.getTrackFormat(i);
                mime = format.getString(MediaFormat.KEY_MIME);
                if (mime.startsWith("audio/")) {
                    extractor.selectTrack(i);
                    break;
                }
            }

            MediaMuxer muxerd = new MediaMuxer(aac.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

            format = MediaFormat.createAudioFormat("audio/raw", sample_rate, 1);
            format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
            format.setInteger(MediaFormat.KEY_BIT_RATE, COMPRESSED_AUDIO_FILE_BIT_RATE);

            codec = MediaCodec.createDecoderByType("audio/raw");
            codec.configure(format, null, null, 0);
            codec.start();


            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

            int audioTrackIdx = 0;
            int totalBytesRead = 0;

            boolean inputEos = false;
            boolean outputEos = false;
            int inputBufIndex, outputBufIndex;
            int sampleSize;
            ByteBuffer readBuffer, writeBuffer;
            double presentationTimeUs = 0;
  while (!outputEos) {
                if (!inputEos) {
                    inputBufIndex = codec.dequeueInputBuffer(timeoutUs);
                    if (inputBufIndex >= 0)
                    {
                        readBuffer = codec.getInputBuffer(inputBufIndex);
                        readBuffer.clear();

                        int i = readBuffer.remaining();
                        byte[] tempBuffer = new byte[i];

                        sampleSize = bis.read(tempBuffer);

                        if (sampleSize < 0) {
                            inputEos = true;
                            codec.queueInputBuffer(inputBufIndex, 0, 0, (long) presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                        } else {
                            totalBytesRead += sampleSize;
                            if (little_endian)
                                readBuffer.put(tempBuffer, 0, sampleSize);
                            else {
                                ByteBuffer bb = ByteBuffer.wrap(tempBuffer);
                                ShortBuffer sb = bb.order(ByteOrder.BIG_ENDIAN).asShortBuffer();
                                short[] shorts = new short[i / 2];
                                sb.get(shorts);
                                for (short s : shorts) {
                                    readBuffer.putShort(s);
                                }
                            }

                            codec.queueInputBuffer(inputBufIndex, 0, sampleSize, (long) presentationTimeUs, 0);
                            presentationTimeUs = 1000000L * (totalBytesRead / 2) / sample_rate;
                        }
                    }
                }

                Log.e("line 3", "pass");

                outputBufIndex = codec.dequeueOutputBuffer(info, timeoutUs);
                if (outputBufIndex >= 0) {
                    writeBuffer = codec.getOutputBuffer(outputBufIndex);
                    writeBuffer.position(info.offset);
                    writeBuffer.limit(info.offset + info.size);

                    if (info.flags == 0 && info.size > 0)
                        muxerd.writeSampleData(audioTrackIdx, writeBuffer, info);

                    codec.releaseOutputBuffer(outputBufIndex, false);
                    writeBuffer.clear();
                    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                        Log.d(TAG, "saw output EOS.");
                        outputEos = true;
                    }
                } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    MediaFormat oformat = codec.getOutputFormat();
                    audioTrackIdx = muxerd.addTrack(oformat);
                    muxerd.start();

                    format = oformat;

                    Log.e(TAG, "output format has changed to " + oformat);
                    Log.e("oformat key mime= ", String.valueOf(oformat.KEY_MIME));

                } else {
                    Log.d(TAG, "dequeueOutputBuffer returned " + outputBufIndex);
                }
            }

            fis.close();
            codec.stop();
            codec.release();

            muxerd.stop();
            muxerd.release();

标签: androidmp3android-mediacodecpcm

解决方案


推荐阅读