Android Exoplayer现场音频流vu米音频可视化和录制

时间:2016-11-13 22:23:37

标签: android audio android-mediaplayer exoplayer

我正在使用Exoplayer来传输实时音频。我不能使用MediaPlayer,因为我的音频是16和32 KBPS,这在使用MediaPlayer时会造成60秒的延迟,但在使用Exoplayer时会立即流动,因为我可以调整exoplayer的缓冲区大小。

我想在我的应用中使用vu meter音频可视化。有谁知道我怎么能实现它?如何从exoplayer获取音频级别?

还有一种方法可以录制音频流,以便将其保存到磁盘上吗?

这是我的流媒体方式:

Uri builtUri = Uri.parse("http://xxxx.xxxx.xxx/xxx.mp3");
ExoPlayer exoPlayer = ExoPlayer.Factory.newInstance(1);

Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
String userAgent = Util.getUserAgent(getContext(), "SPLENDID");
DefaultUriDataSource dataSource = new DefaultUriDataSource(getContext(), new TransferListener() {
    @Override
    public void onTransferStart() {
        //System.out.println("onTransferStart");
    }

    @Override
    public void onBytesTransferred(int bytesTransferred) {
        //System.out.println("onBytesTransferred: "+bytesTransferred);
    }

    @Override
    public void onTransferEnd() {
        //System.out.println("onTransferEnd");
    }
}, userAgent);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(streamurl, dataSource, allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT);

CustomMediaCodecAudioTrackRenderer audioRenderer = new CustomMediaCodecAudioTrackRenderer(sampleSource);

exoPlayer.prepare(audioRenderer);
exoPlayer.setPlayWhenReady(true);
exoPlayer.addListener(new ExoPlayer.Listener() {
    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        System.out.println("onPlayerStateChanged, playWhenReady: "+playWhenReady+" ,playbackState: ");



    }

    @Override
    public void onPlayWhenReadyCommitted() {
        System.out.println("onPlayWhenReadyCommitted");
    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
        System.out.println("onPlayerError: "+error.getLocalizedMessage());
    }
});

CustomMediaCodecAudioTrackRenderer.java:

import android.media.MediaCodec;
import android.os.Handler;

import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import com.google.android.exoplayer.SampleSource;

import java.nio.ByteBuffer;

/**
 * Created by pranoychowdhury on 11/14/16.
 */
public class CustomMediaCodecAudioTrackRenderer extends MediaCodecAudioTrackRenderer {
    public CustomMediaCodecAudioTrackRenderer(SampleSource source) {
        super(source);
    }

    public CustomMediaCodecAudioTrackRenderer(SampleSource source, Handler eventHandler, EventListener eventListener) {
        super(source, eventHandler, eventListener);
    }

    @Override
    protected boolean processOutputBuffer(long positionUs, long elapsedRealtimeUs, MediaCodec codec, ByteBuffer buffer, MediaCodec.BufferInfo bufferInfo, int bufferIndex, boolean shouldSkip) throws ExoPlaybackException {
        //return super.processOutputBuffer(positionUs, elapsedRealtimeUs, codec, buffer, bufferInfo, bufferIndex, shouldSkip);

        boolean processed = false;

        //  Clone buffer

        ByteBuffer clone = ByteBuffer.allocate(buffer.capacity());
        buffer.rewind();//copy from the beginning
        clone.put(buffer);
        buffer.rewind();
        clone.flip();



        processed = super.processOutputBuffer(positionUs,elapsedRealtimeUs,codec,buffer,bufferInfo, bufferIndex, shouldSkip);
        if (processed & !shouldSkip)
        {
            // send data to be converted to shorts and then propogate a callback to render float data
            //transform(clone);
            //System.out.println("Buffer: "+clone.toString());
            return true;
        }
        else
        {
            return false;
        }
    }


}

编辑:我将Exoplayer降级为1.5.3,因为我无法弄清楚如何访问v2中的MediaCodecAudioTrackRenderer

我扩展了MediaCodecAudioTrackRenderer类,因为它有一个我可以覆盖的processBuffer函数。

但是现在我不知道如何转换ByteBuffer来计算可视化的音频功率级别。

0 个答案:

没有答案