我正在使用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
来计算可视化的音频功率级别。