我试图在android上开发用于OGG文件格式音频流的媒体提取器。我在google文档的帮助下编写了一些代码。但根本不起作用。可能我写错了代码或语法,因为我是学生。它显示我无法实例化提取器
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource("http://examplelink.com/ogg");// I cant put real link so sorry for that
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; ++i) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
extractor.selectTrack(i);
ByteBuffer inputBuffer = ByteBuffer.allocate(1024);
while (extractor.readSampleData(inputBuffer,0) >= 0) {
int trackIndex = (int) extractor.getSampleTime();
long presentationTimeUs = extractor.getSampleTime();
}
MediaCodec codec = MediaCodec.createDecoderByType(mime);
codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
format = codec.getOutputFormat();
Long timeoutUs=(long) 1;
for (;;) {
int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferIndex >= 0) {
// fill inputBuffers[inputBufferIndex] with valid data
codec.queueInputBuffer(inputBufferIndex, 0, 128, 0,0);
}
MediaCodec.BufferInfo info = new BufferInfo();
int outputBufferIndex = codec.dequeueOutputBuffer(info, timeoutUs);
if (outputBufferIndex >= 0) {
// outputBuffer is ready to be processed or rendered.
codec.releaseOutputBuffer(outputBufferIndex, false);
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = codec.getOutputBuffers();
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
format = codec.getOutputFormat();
AudioTrack mAudioTrack = null;
mAudioTrack.setPlaybackRate(format.getInteger(MediaFormat.KEY_SAMPLE_RATE));
}
codec.stop();
codec.release();
codec = null;
}
}}
发布于 2012-11-13 04:12:53
我想你的问题是“为什么它根本不起作用?”通常,这是一个太大的问题,但在这种情况下,我认为您根本不了解MediaExtractor & MediaCodec是如何工作的。
但并不全是你的错。说得好听些,这份文件很神秘。但是,我成功地用这种方式播放了音频文件。
我的方案假设MediaCodec实现一个异步缓冲区队列。这个队列中似乎有大约4个缓冲区。
因此,我使用两个线程:一个线程将来自MediaExtractor的数据放入队列,另一个线程从队列中取出解码音频并将其写入AudioTrack。
然后,我需要非常小心,以避免死锁在一个寻求,例如。最后我得到的代码比你的多得多。我不知道该怎么避免!
我在考虑试一试视频。任何有帮助的参考资料将不胜感激!
完成
发布于 2013-04-24 11:12:43
下面的代码将为我在JB平台上的本地音频文件完美地工作。
try{
Extractor lExt = new MediaExtractor();
lExt.setDataSource(file path); //I have tried with local file
lExt.setTrack(0); //For local file only one track will be present
MediaFormat format = lExt.getTrackFormat(0); //0 is the track ID
String mime = format.getString(MediaFormat.KEY_MIME);
MediaCodec codec = MediaCodec.createDecoderByType(mime);
codec.configure(
format,//format of input data ::decoder OR desired format of the output data:encoder
null,//Specify a surface on which to render the output of this decoder
null,//Specify a crypto object to facilitate secure decryption
0 //For Decoding, encoding use: CONFIGURE_FLAG_ENCODE
);
codec.start();
codec.flush();
//Get Input and Output buffers from codec
inputBuffers = codec.getInputBuffers();
outputBuffers = codec.getOutputBuffers();
While(condition)
{
//Get Audio data from extractor
int inputBufIndex = codec.dequeueInputBuffer(50);//Timeout set of 50 microsec
if (inputBufIndex >= 0)
{
ByteBuffer dstBuf = inputBuffers[inputBufIndex];
int sampleSize = extractor.readSampleData(dstBuf, 0);
long presentationTimeUs = extractor.getSampleTime();
codec.queueInputBuffer(inputBufIndex,
0, //offset
sampleSize,
presentationTimeUs,
0); //Use appropriate flag value
extractor.advance();
}
//Use codec to decode the data -- handle end of stream properly
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
info.set(0,0,0,0);
final int res = codec.dequeueOutputBuffer(info, 20000);
if (res >= 0)
{
int outputBufIndex = res;
ByteBuffer buf = outputBuffers[outputBufIndex];
byte[] chunk = new byte[info.size];
buf.get(chunk); // Read the buffer all at once
buf.clear(); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN
if (chunk.length > 0)
//Use this chunk as it contains decoded audio dat
codec.releaseOutputBuffer(outputBufIndex, false /* render */);
}
else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
outputBuffers = codec.getOutputBuffers();
}
codec.stop();
codec.release();
lExt.release();
}
catch(Exception ex)...发布于 2015-01-21 01:18:21
将数据源设置为远程URL将需要在android.permission.INTERNET中声明AndroidManifest.xml权限
<uses-permission android:name="android.permission.INTERNET" />https://stackoverflow.com/questions/12671989
复制相似问题