安卓wifi直接直播摄像头视频流 [英] android wifi direct live camera video stream
问题描述
我已在两个android设备之间建立了wifi直接p2p连接,以720x480的分辨率将实时摄像头Feed从设备A传输到设备B.它可以正常工作,但是即使在近距离(<1m)时也非常不稳定.有时约为15fps,然后在几秒钟内降至约3fps(只是一个估计值).基本功能是PreviewCallback的OnPreviewFrame内的Runnable线程,该线程使用YuvImage()将预览帧压缩为JPEG并将其写入OutputStream.
I have established a wifi direct p2p connection between two android devices, streaming the live camera feed from device A to device B, at 720x480 resolution. It works ok, but is pretty choppy, even at close range (<1m). Sometimes it's ~15fps, then for a couple seconds it will drop to ~3fps (just a guesstimate). The basic functionality is a Runnable thread inside the OnPreviewFrame of the PreviewCallback that uses YuvImage() to compress the preview frame into a JPEG and writes it to an OutputStream.
我的问题是:有没有更有效的方法来做到这一点?我不需要惊人的帧频(20再见...?).只需保持一致即可.
My question is: Is there a more efficient way to do this? I don't need an amazing frame rate (mabye 20...?). It just has to be a little more consistent.
private PreviewCallback previewCb_ = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera c) {
frame = data;
imageFormat = c.getParameters().getPreviewFormat();
if (!socket.isClosed()) {
mHandler.post(new Runnable() {
public void run() {
if (stream != null){
try
{
//Log.d(ChooseFunction.TAG, "writing to stream");
buffer.reset();
synchronized(frame){
new YuvImage(frame, imageFormat, CameraView.IMG_WIDTH, CameraView.IMG_HEIGHT, null).compressToJpeg(area, 100, buffer);
}
buffer.flush();
// write the content header
stream.write(("--" + boundary + "\r\n" +
"Content-type: image/jpg\r\n" +
"Content-Length: " + buffer.size() +
"\r\n\r\n").getBytes());
buffer.writeTo(stream);
stream.write("\r\n\r\n".getBytes());
stream.flush();
}
catch (IOException e)
{
Log.d(ChooseFunction.TAG, e.getMessage());
}
}
}
});
}
}
};
推荐答案
我已使用 OpenCV 进行此转换,以使将摄像机预览数据转换为位图的性能更加有效.
I've used OpenCV for this conversion to make the performance for conversion of camera preview data to bitmap more efficient.
//Use openCV manager or openCV native libs directly in your project
Log.i(TAG, "Trying to load OpenCV library");
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_2_0, this, mOpenCVCallBack)) {
Log.e(TAG, "Cannot connect to OpenCV Manager");
}
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
//Init mat object
mYuv = new Mat(480 + 480 / 2, 640, CvType.CV_8UC1);
mRgb = new Mat();
Log.i(TAG, "OpenCV loaded successfully");
OpenCVLoaded = true;
}
break;
default: {
super.onManagerConnected(status);
}
break;
}
}
};
if (OpenCVLoaded) {
//put camera preview data in mat
mYuv.put(0, 0, instantPhotoData);
Imgproc.cvtColor(mYuv, mRgb, Imgproc.COLOR_YUV420sp2RGB, 4);
// convert to bitmap:
final Bitmap rawBitmap = Bitmap.createBitmap(mRgb.cols(), mRgb.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mRgb, rawBitmap);
previewImageView.setImageBitmap(rawBitmap);
}
});
}
这篇关于安卓wifi直接直播摄像头视频流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!