问题描述
我是带MediaCodec的TextureView,它显示了从远程服务获得的实时流中H.264格式的视频流。
这是我的实现: 首先,声明变量:
private TextureView m_surface;// View that contains the Surface Texture
private MediaCodec m_codec;// Media decoder
private DecodeFramesTask m_frameTask;// AsyncTask that takes H264 frames and uses the decoder to update the Surface Texture
现在在OnCreate
方法中初始化变量:
@Override
public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.help_fragment,container,false);
// Get a referance to the TextureView in the UI
m_surface = (TextureView) root.findViewById(R.id.textureView);
// Add this class as a call back so we can catch the events from the Surface Texture
m_surface.setSurfaceTextureListener(this);
return root;
}
这是其余的代码:
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface,int width,int height) {
// Create the format settinsg for the MediaCodec
MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC,1280,720);
// Set the buffer size
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE,100000);
format.setInteger(MediaFormat.KEY_FRAME_RATE,30);
try {
// Get an instance of MediaCodec and give it its Mime type
m_codec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
// Configure the Codec
m_codec.configure(format,new Surface(m_surface.getSurfaceTexture()),null,0);
// Start the codec
m_codec.start();
// Create the AsyncTask to get the frames and decode them using the Codec
m_frameTask = new DecodeFramesTask();
m_frameTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface,int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
private class DecodeFramesTask extends AsyncTask<String,String,String> {
@Override
protected String doInBackground(String... data) {
while (!isCancelled()) {
// Get the next frame
byte[] frame = remoteSerice.getVideoPacket(); // getting the video packet in byte[]
// Get the input buffer from the decoder
int inputIndex = m_codec.dequeueInputBuffer(-1);// Pass in -1 here as in this example we don't have a playback time reference
// If the buffer number is valid use the buffer with that index
if (inputIndex >= 0 && frame != null) {
ByteBuffer buffer = m_codec.getInputBuffer(inputIndex);
buffer.put(frame);
// tell the decoder to process the frame
m_codec.queueInputBuffer(inputIndex,frame.length,0);
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
int outputIndex = m_codec.dequeueOutputBuffer(info,0);
if (outputIndex >= 0) {
m_codec.releaseOutputBuffer(outputIndex,true);
}
}
return "";
}
@Override
protected void onPostExecute(String result) {
try {
m_codec.stop();
m_codec.release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onStop() {
super.onStop();
m_frameTask.cancel(true);
}
现在我在textureView
上得到了一张图像,但这只是一个紫色的图像,有时会变为另一个图像。
在实现它的方式上我缺少什么吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)