将实时视频从 Raspberry Pi 流式传输到我的 Android 应用程序,但出现安全异常

Posted

技术标签:

【中文标题】将实时视频从 Raspberry Pi 流式传输到我的 Android 应用程序,但出现安全异常【英文标题】:Streaming live video from Raspberry Pi to my Android App but getting security exception 【发布时间】:2017-03-08 17:54:51 【问题描述】:

我想将实时视频流式传输到我的 android 应用程序。 我正在使用运动服务从我的树莓派相机(小型 USB 连接相机)流式传输实时视频。我已经为端口 8082 设置了它,因此我可以从任何浏览器成功输入(示例 IP)“http://74.220.185.125:8082”并查看我的视频流。但是,当我使用 videoView 在我的应用程序代码中使用它时,每次都会抛出异常。

主活动:

@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();
            
        );


    

每次,我都会收到同样的错误:

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)

我在清单文件中启用了 INTERNET:

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

我尝试了 rstp:// 和 http:// ,但最终都抛出了相同的异常。谁能看到我这个异常可能是从哪里引起的?

【问题讨论】:

【参考方案1】:

因此,在搜索和询问大约两周后,我实际上在大约一周前找到了这个简单的解决方案,我注意到有很多其他人提出相同的问题或寻找一个简单的答案,我想分享什么有效为了我。

我的搜索引导我使用 videoView,但据我了解,videoView 正在搜索通常会在您的远程服务器上创建的特定文件和/或特定流文件类型。然而,运动服务并没有提供文件或我正在寻找的详细信息,但 ip 地址肯定在普通浏览器中工作,所以我尝试使用 webView,在 motion.conf 文件中调整我的树莓派上的像素比,并使用我的 webView 的尺寸,它工作得非常好。代码比我一直看到的示例要容易得多,这就是我使用的:

String piAddr = "http://10.0.0.116:8081/"

mWebView = (WebView) findViewById(R.id.activity_main_webview);
mWebView.loadUrl(piAddr);

注意:我正在运行一个 python 脚本,它在我的树莓派上启动运动服务,似乎应用程序请求树莓派运动服务端口和实际启动运动服务之间的时间略有偏差,所以在我的整个过程中代码我只是定期重复以下行来验证我的视频是否成功流式传输。

此外,webView 有一个自动滚动条,因此如果您看不到整个视频(底部有计时器),您可以随时在 motion.conf 文件中的 pi 上调整视频尺寸。

【讨论】:

谢谢,您关于在 Android 应用上使用运动服务进行视频流传输的想法对我的项目帮助很大。感谢您发布代码。

以上是关于将实时视频从 Raspberry Pi 流式传输到我的 Android 应用程序,但出现安全异常的主要内容,如果未能解决你的问题,请参考以下文章

Raspberry Pi无延迟(<10ms)视频流

如何在 html 中嵌入来自 Raspberry Pi 的流媒体视频?

将实时视频广播从 android 相机流式传输到服务器

寻找一个库/框架将实时视频从 OS X 流式传输到 Wowza 服务器(RTMP)[关闭]

将实时视频从我的 c# 应用程序流式传输到 ASP.NET 网页

将 pi 的 opencv 视频传输到 ffmpeg 以进行 Youtube 流式传输