ExoPlayer:自定义音频处理器 - 均衡器

ExoPlayer: Custom AudioProcessor - Equalizer

我正在为 Android 开发基于 ExoPlayer 的媒体播放器,我正在尝试编写自己的均衡器。

我对 ExoPlayer 进行了相当深入的研究,我认为操作样本以应用 Equalier 更改的最佳位置是自定义 AudioProcessor

我使用 ChannelMappingAudioProcessor 作为起点,并克隆了我认为相关的方面:

class EqualizerAudioProcessor : BaseAudioProcessor() {

        private lateinit var outputChannels: IntArray

        override fun configure(sampleRateHz: Int, channelCount: Int, encoding: Int): Boolean {
            outputChannels = IntArray(channelCount)
            for (i in 0 until channelCount) {
                outputChannels[i] = i
            }
            return true
        }

        override fun isActive(): Boolean {
            return true
        }

        override fun getOutputChannelCount(): Int {
            return outputChannels.size
        }

        override fun queueInput(inputBuffer: ByteBuffer) {
            var position = inputBuffer.position()
            val limit = inputBuffer.limit()
            val frameCount = (limit - position) / (2 * channelCount)
            val outputSize = frameCount * outputChannels.size * 2
            val buffer = replaceOutputBuffer(outputSize)
            while (position < limit) {
                for (element in outputChannels) {
                    var sample = inputBuffer.getShort(position + 2 * element)
                    // Todo: Manipulate sample
                    buffer.putShort(sample)
                }
                position += channelCount * 2
            }
            inputBuffer.position(limit)
            buffer.flip()
        }

        override fun onReset() {

        }
    }

似乎如果我 enable 这个 AudioProcessor,播放不会发生(它似乎卡在 'paused state',就好像样本没有被传递一样,有趣的是,queueInput() 没有被调用。如果我禁用 AudioProcessor,播放正常。

我希望有人能帮助我理解我是否在此处犯了错误,以及如何使它正常工作。

作为参考,ExoPlayer 实例初始化如下:

    private fun initPlayer(context: Context): ExoPlayer {

        val audioProcessor = EqualizerAudioProcessor()

        val renderersFactory = object : DefaultRenderersFactory(context) {
            override fun buildAudioProcessors(): Array<AudioProcessor> {
                return arrayOf(audioProcessor)
            }
        }

        val player: SimpleExoPlayer = ExoPlayerFactory.newSimpleInstance(
            context,
            renderersFactory,
            DefaultTrackSelector(),
            DefaultLoadControl()
        )

        player.addListener(object : Player.EventListener {
            override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
                callback?.onPlayStateChanged(playWhenReady)
            }
        })

        return player
    }

提前致谢

问题是你必须在AudioProcessorconfigure()中调用setInputFormat(),否则queueInput()将不会被调用。