Search code examples
javaandroid-studioraspberry-pivideo-streamingandroid-videoview

Streaming live video from Raspberry Pi to my Android App but getting security exception


I would like to stream live video to my android app. I am using the motion service to stream live video from my raspberry pi's camera (small usb connected camera). I have it setup for port 8082 so I can successfully type in (exampled IP) "http://74.220.185.125:8082" from any browser and see my video streaming. However, when I use this in my code for my app using the videoView I get an Exception thrown each time.

MainActivity:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Starting video
        piVideo = (VideoView) findViewById(R.id.piVidView);

        try{
            piVideo.setVideoURI(Uri.parse("http://74.220.185.125:8082/"));
        } catch (Exception e){
            Log.e("Error found here->", e.getMessage());
            e.printStackTrace();
        }
        piVideo.requestFocus();
        piVideo.start();

        piVideo.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override

            public void onPrepared(MediaPlayer mp) {
                piVideo.start();
            }
        });


    }

Each time, I get this same error:

03-08 12:46:49.258 1412-1412/com.me.blah.app D/MediaPlayer: setDataSource IOException | SecurityException happend : 
                                                                         java.io.FileNotFoundException: No content provider: http://74.220.185.125:8082/
                                                                             at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1141)
                                                                             at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:991)
                                                                             at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:914)
                                                                             at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1121)
                                                                             at android.widget.VideoView.openVideo(VideoView.java:371)
                                                                             at android.widget.VideoView.access$2100(VideoView.java:71)
                                                                             at android.widget.VideoView$7.surfaceCreated(VideoView.java:652)
                                                                             at android.view.SurfaceView.updateWindow(SurfaceView.java:712)
                                                                             at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:209)
                                                                             at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1014)
                                                                             at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2510)
                                                                             at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1437)
                                                                             at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7397)
                                                                             at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
                                                                             at android.view.Choreographer.doCallbacks(Choreographer.java:695)
                                                                             at android.view.Choreographer.doFrame(Choreographer.java:631)
                                                                             at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
                                                                             at android.os.Handler.handleCallback(Handler.java:739)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                             at android.os.Looper.loop(Looper.java:158)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:7229)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

I have INTERNET enabled in my manifest file:

"uses-permission android:name="android.permission.INTERNET"

I have tried rstp:// and http:// and both still end up with the same exception being thrown. Can anyone see where I this exception could being caused from?


Solution

  • So I actually found this simple solution about a week or so ago after searching & asking for roughly two weeks, and I noticed there were many other people asking the same questions or looking for a simple answer and I wanted to share what worked for me.

    My search lead me to using a videoView, but from my understanding the videoView is searching for a specific file and/or a specific streaming file type that would normally be created on your remote server. However the motion service did not readily provide the file nor the details I was looking for, but the ip address definitely worked in a normal browser so I tried a webView instead, adjusted my pixel ratio on my raspberry pi in the motion.conf file, and played with the dimensions of my webView and it worked perfectly fine. The code was a lot easier than the examples I kept seeing and this is what I used:

    String piAddr = "http://10.0.0.116:8081/"
    
    mWebView = (WebView) findViewById(R.id.activity_main_webview);
    mWebView.loadUrl(piAddr);
    

    NOTE: I am running a python script that starts the motion service on my raspberry pi and it seems that the timing between the app requesting the raspberry pi motion service port and the motion service actually starting up is slightly off, so throughout my code I just repeat the following line periodically to verify my video is streaming successfully.

    Additionally, the webView has a scroll bar automatically so if you cannot see the entire video (with the timer at the bottom) you can always tweak your video dimensions on the pi in the motion.conf file.