Getting IP Cam video stream on Android (MJEPG)

2019-01-21 18:11发布

问题:

I am currently doing an AndAR project in group of 3. I'm the person who's in charge of video streaming into the Android phone. I got ourselves a D-Link DCS-920 IP camera and I found out that it uses MJPEG codec for the live video stream and the webserver uses Jview to view the live stream. As far as I know MJPG is not a supported file type for Android OS so I've came out with an idea, instead of using ImageView, I use WebView to stream the video. I've implemented a very simple concept and it works! But the problem is, refresh rate is terrible. I get the video image (eg: http://192.168.1.10/image.jpg) to view on the WebView and implement a Timer to control the refresh rate (supposed to set it to 30fps, which is refresh every 33ms) but it can only go up to 500ms interval, any lower interval I notice it will not be any smoother,sometimes the image wont load and connection is unstable (eg: dropped). Could this be I'm refreshing at a rate faster than it can receive? But over on the webserver Jview it has no problem! was trying to find the source code for the jview but I have no hope. Anyway here's the code I've written

package org.example.test;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;

public class Webview extends Activity {

public WebView webView;
public Timer autoUpdate;
public String url;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);    

        webView = (WebView) findViewById(R.id.webview);
        webView.getSettings();
        final EditText urlText = (EditText) findViewById(R.id.urlText);

        //Buttons//////////////////------------
        final Button connectB = (Button)findViewById(R.id.connectButton);
        connectB.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
            //Actions goes here
          url = urlText.getText().toString();
          webView.loadUrl(url);
          timerSetup();
         }
        });
        final Button exitB = (Button)findViewById(R.id.exitButton);
     exitB.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
       //Actions goes here
       finish();
      }
     });
   }

    //refresh timer//////////////-----------------
    public void timerSetup(){
     autoUpdate = new Timer();
     autoUpdate.schedule(new TimerTask() {
      @Override
      public void run() {
       runOnUiThread(new Runnable() {
        @Override
     public void run() {
         //Actions goes here
         webView.loadUrl(url);
        }
       });
      }
     }, 0, 500);//refresh rate time interval (ms)
    }
}

Is there anyway I can get the video stream in by at least 15fps/have a faster refresh rate? Are there any such thing as MJPEG viewer/source code that I can use to display these images?

here's the screenshot of the app http://s945.photobucket.com/albums/ad295/kevinybh/?action=view&current=video.jpg (not enough points to post pictures) :(

I just need to make the video stream around 15-30fps. any suggestions/help would be very deeply appreciated :) Thanks!

回答1:

Instead of an Arduino you could use a Raspberry PI, it should have enough CPU power to control the vehicle and to convert the video stream at the same time. Sure, you'll need to port all of your Arduino software to Raspberry...



回答2:

MJPEG is a terribly inefficient way to deliver motion video to a mobile device, because each frame is compressed as it's own independent picture. For an application which doesn't need video (someone was asking about a camera watching waiting lines last week) your solution of pushing a static frame every second or so sounds good.

If you need motion video, I would recommend you do transcoding on your webserver from MJPEG to a supported video format which utilizes frame-to-frame compression. This will result in far less data to push, both over the user's 3g connection and from your server to all of its clients. You should only need to run one transcoding engine to support all clients - and you'll be able to use the same one for android & iphone devices, though you may want to also have a higher resolution output for tablets and pc's if your camera output is good enough to justify it.



回答3:

On android, if we decode a jpeg by CPU, it will cost 40-100ms. If we want to play mjpeg to 15-30fps, we need hardware jpeg decoder.



回答4:

There was a useful previous SO discussion and this great one with code. Would you try and let us know if that works for you.



回答5:

You can use MjpegView class to display mjpeg stream directly. https://code.google.com/p/android-camera-axis/source/browse/trunk/serealisation/src/de/mjpegsample/MjpegView/MjpegView.java?r=33

You'll have to implement some AsyncTasks on this class to works fine.

Good luck