Search code examples
androidvideocompressionbandwidthbitmapfactory

Android: I want to record an extra low quality video feed possible and send it in discrete packets. Is it possible? How would you approach it?


Basically I want to be able to send a few second delayed "live" feed over less than 3g. It's ok if it very low quality. I could even go with like 4 bit grayscale if necessary (though 128-256 colors would be preferable). I'd be willing to go as low as 160x120 at >1fps if necessary. Fully uncompressed at this crummiest of settings means an over-saturated low bandwidth connection.

Should I look into simply snapshotting as images? Is anyone familiar with the capabilities of Bitmapfactory with regard to the lowest quality JPEGs possible?

Should I look into PNGs or GIFs? My understanding is that solid fields work best with these. I'm not sure I can depend a lot on solid fields other than a good portion of sky, as I'm looking to have control over a drone that sends back "video." Faux video with a several second delay is fine and even preferable as I expect losing and regaining server connection often.

I get like 128k up on "3g" with a decent signal, but i can't exactly depend on that. I can do any necessary decoding server side - that shouldn't be a problem.

So I ask you, Stack, you want to see from your smartphone over the internet and cannot depend on a good connection. How do you approach it?


Solution

  • I think the most simple approach will be grabbing the preview images and sending those.

    Here's a nice piece of code I found for grabbing the preview image as a JPEG. It's nice and fast and should suit your needs. I was also using it for uploading, so I was after very small file size.

    When outputting 1920x1080 images the file size was anywhere between 150-300KB.

        camera.setOneShotPreviewCallback(new PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    try {
                        Camera.Parameters parameters = camera.getParameters();
                        Size size = parameters.getPreviewSize();
                        YuvImage image = new YuvImage(data, parameters.getPreviewFormat(),
                                size.width, size.height, null);
                        File file = new File(getCacheDir().getPath() + "/out.jpg");
                        FileOutputStream filecon = new FileOutputStream(file);
                        image.compressToJpeg(
                                new Rect(0, 0, image.getWidth(), image.getHeight()), 90,
                                filecon);
                    } catch (FileNotFoundException e) {
                    }
                }
            });
    

    Here's how I just set the preview size to the maximum setting, but you can set it to a lower one to speed things up.

    Camera.Parameters parameters = camera.getParameters();
    List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
    imageWidth = previewSizes.get(0).width;
    imageHeight = previewSizes.get(0).height;
    parameters.setPreviewSize(imageWidth, imageHeight);
    camera.setParameters(parameters);