【问题标题】:How to avoid audio track skipping audio buffer in android?如何避免音轨在android中跳过音频缓冲区?
【发布时间】:2014-06-17 04:48:36
【问题描述】:

我想为我的 Android 应用程序实现实时音频流。所以我使用了OpenCORE aacdec 库并将其包装起来。因为我必须同时播放 MP3 和 AAC。

将流保存为文件(大小为 50 * 1024),使用库的 BufferReaderDecoder 读取和解码每个文件。

为了读取每个文件,修改了BufferReadernext()方法。在next()读取文件内部作为大小与文件大小相同的缓冲区(即50*1024)。将这些解码缓冲区写入线程中的AudioTrack 并播放。

public void run() {
           short[] samplesBuffered = getDecodedSample(filePath);

        if (samplesBuffered != null) {
            // samples written to AudioTrack in this round:
            int writtenNow = 0;
            int ln = samplesBuffered.length;
            do {
                if (writtenNow != 0) {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                    }
                }
                int written = track.write(samplesBuffered, writtenNow, ln);
                if (written < 0) {
                    stopped = true;
                    break;
                }
                writtenTotal += written;
                int buffered = writtenTotal - track.getPlaybackHeadPosition()
                        * configuration.getChannels();
                if (!stopped && !isPlaying) {
                    if (buffered * 2 >= configuration.getBufferSizeInBytes()) {
                        track.play();
                        isPlaying = true;
                    }
                }

                writtenNow += written;
                ln -= written;
            } while (ln > 0 && !stopped);
        }
    }


private  synchronized short[] getDecodedSample(String filePath) {
        InputStream iStream = null;
        BufferReader reader = null;
        try {
            if (decoder != null) {
                decoder.stop();
            }
            iStream = new FileInputStream(filePath.trim());
            reader = new BufferReader(PlayerUtils.computeInputBufferSize(declaredBitRate, decodeBufferCapacityMs), iStream);
            //new Thread(reader).start();

            Decoder.Info info = decoder.start(reader);
            short[] decodeBuffer = new short[PCMFeed.msToSamples( decodeBufferCapacityMs, info.getSampleRate(), info.getChannels())];

            info = decoder.decode(decodeBuffer, decodeBuffer.length);

            int nsamp = info.getRoundSamples();
            if (nsamp == 0 || reader.isStopped()){
                return null;
            }

            return decodeBuffer;
        } catch (FileNotFoundException e) {
        } catch (Exception e) {
        } finally {
            try {
                iStream.close();
            } catch (Exception e) {
            }
        }
        return null;
    }

decodeBufferCapacityMs : 5000 audioBufferCapacityMs:1000 音轨缓冲区大小:88200 采样率:22050

我的问题是 AudioTrack 跳过了每个缓冲区的最后一部分。我该如何解决这个问题?

【问题讨论】:

    标签: android mp3 audio-streaming aac


    【解决方案1】:

    我知道这是一年前的事了,但如果您仍在寻找解决方案,或者其他人需要它 - 您需要播放整个缓冲区,您需要写入“轨道”中的任何内容您的 PCMFeed 缓冲区,而不是在您的 do-while (ln &gt; 0 &amp;&amp; !stopped); 循环之后立即完成。

    请在此处查看更多详细信息:https://github.com/vbartacek/aacdecoder-android/blob/master/decoder/src/com/spoledge/aacdecoder/PCMFeed.java

    并注意waitForLastTone周围的方法和逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-04
      相关资源
      最近更新 更多