无法从 IP cam 接收 RTSP 实时流

Posted

技术标签:

【中文标题】无法从 IP cam 接收 RTSP 实时流【英文标题】:Can't receive RTSP live stream from an IP cam 【发布时间】:2015-07-16 12:08:47 【问题描述】:

我想使用 RTSP 接收来自 IP 摄像机的实时流,我收到 “无法播放此视频”,以及以下异常:

07-16 14:06:26.945: D/MediaPlayer(19411): setDataSource IOException happend : 
07-16 14:06:26.945: D/MediaPlayer(19411): java.io.FileNotFoundException: No content provider: rtsp://192.168.30.108:554
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1052)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:907)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:834)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.media.MediaPlayer.setDataSource(MediaPlayer.java:973)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.widget.VideoView.openVideo(VideoView.java:337)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.widget.VideoView.setVideoURI(VideoView.java:247)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.widget.VideoView.setVideoURI(VideoView.java:237)
07-16 14:06:26.945: D/MediaPlayer(19411):   at com.example.video_rtsp.MainActivity$2.run(MainActivity.java:59)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.os.Handler.handleCallback(Handler.java:733)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.os.Handler.dispatchMessage(Handler.java:95)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.os.Looper.loop(Looper.java:157)
07-16 14:06:26.945: D/MediaPlayer(19411):   at android.app.ActivityThread.main(ActivityThread.java:5293)
07-16 14:06:26.945: D/MediaPlayer(19411):   at java.lang.reflect.Method.invokeNative(Native Method)
07-16 14:06:26.945: D/MediaPlayer(19411):   at java.lang.reflect.Method.invoke(Method.java:515)
07-16 14:06:26.945: D/MediaPlayer(19411):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-16 14:06:26.945: D/MediaPlayer(19411):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-16 14:06:26.945: D/MediaPlayer(19411):   at dalvik.system.NativeStart.main(Native Method)
07-16 14:06:26.945: D/MediaPlayer(19411): Couldn't open file on client side, trying server side
07-16 14:06:26.955: V/MediaPlayer(19411): setVideoSurfaceTexture
07-16 14:06:26.955: V/MediaPlayer-JNI(19411): setAudiostreamType: 3
07-16 14:06:26.955: V/MediaPlayer(19411): MediaPlayer::setAudioStreamType
07-16 14:06:26.955: V/MediaPlayer(19411): setVideoSurfaceTexture
07-16 14:06:26.955: V/MediaPlayer(19411): prepareAsync
07-16 14:06:26.965: D/ProgressBar(19411): setProgressDrawable drawableHeight = 48
07-16 14:06:26.985: D/AbsSeekBar(19411): AbsSeekBar Constructor: misSeebarAnimationAvailable = true

我正在使用以下方式:

VideoView videoView = (VideoView) ((Activity) ctx).findViewById(R.id.videoView);

//add controls to a MediaPlayer like play, pause.
MediaController mc = new MediaController(ctx);
videoView.setMediaController(mc);

//Set the path of Video or URI
videoView.setVideoURI(Uri.parse("rtsp://192.168.30.108:554"));

//Set the focus
videoView.requestFocus();

不能说我确定是这个问题,但我认为这是因为这个相机软件需要身份验证,但如果是这样,我不知道如何为其提供身份验证。


将 MediaPlayer 与 setDataSource 一起使用后,我收到以下异常:

07-21 12:04:11.677: W/System.err(17714): java.io.IOException: Prepare failed.: status=0x1
07-21 12:04:11.677: W/System.err(17714):    at android.media.MediaPlayer.prepare(Native Method)

我不确定这是否与设置标题的错误方式有关:

Uri uri = Uri.parse("rtsp://192.168.30.108:554");
Map<String , String> headres = new HashMap<String, String>();
headres.put("Authorization", "Basic ce0ca0f0864513c28c7be98f0f929be7b1f5db79"); //Also tried it without "Basic"
headres.put("encryption", "Default");
headres.put("mac", "9002A9D89200");
headres.put("random", "1715377261");
headres.put("realm", "Login to 90:02:a9:d8:92:00");

mediaPlayer.setDataSource(getApplicationContext(), uri, headres);

这是使用firebug的登录过程标头和json数据的屏幕截图:

【问题讨论】:

您是否尝试过基本身份验证rtsp://username:password@192.168.30.108:554?你可能也需要一个流名称rtsp://username:password@192.168.30.108:554/stream_name @aergistal 是的,我试过了,没有什么新东西 尝试使用 VLC 等其他播放器在同一台机器上播放流 @aergistal 我在 VLC 上试过了,一旦我按下播放它就会弹出一个用户和密码对话框,一旦我输入它们,流就可以毫无问题地播放 您是否尝试像@aergistal 在他的第一条评论中提到的那样将身份验证放入 URI(也在 VLC 中)?在您的示例中,使用 rtsp://username:password@192.168.30.108:554 而不是 rtsp://192.168.30.108:554 【参考方案1】:

如果身份验证机制是 HTTP 基本身份验证,那么可能有办法设置所需的 HTTP 标头:MediaPlayer 类有一个方法 setDataSource 为标头采用 Map 参数:

public void setDataSource (Context context, Uri uri, Map&lt;String, String&gt; headers)

您必须设置Authorization 标头:

Authorization: Basic _credentials_

_credentials_username:password 字符串的 RFC2045-MIME Base64 编码。

【讨论】:

感谢您的回答,请查看我的更新 当我执行解码时,它给了我一个二进制数据文件,而不是一个特定的单词组合,当手动编码 username:password 时,它没有给我上面的代码

以上是关于无法从 IP cam 接收 RTSP 实时流的主要内容,如果未能解决你的问题,请参考以下文章

网络摄像头如何按需推流?

cvlc 不能播放 rtsp(omxplayer 可以)

调用Live555接收RTSP直播流,转换为Http Live Streaming(iOS直播)协议

rtsp和sdp协议简介

来自 C# 的 IP Cam 实时提要

WEB页面实时播放海康大华等摄像头RTSP视频流完全方案