VLC如何将RTSP实时流传输到Android设备?

11

我需要从Decklink卡流式传输到Android应用程序(必须是实时流,因此HLS或RTSP似乎是很好的解决方案,因为我的应用程序面向Android 3+)。我使用Decklink SDK重新编译了VLC,并能够通过网络将实时流式传输到另一台PC(但RTSP仅适用于60秒)。

这是我尝试过的:

  • HTTP Stream :

    ./vlc -vvv decklink:// --sout
    '#transcode{vcodec=mp4v,acodec=mpga,vb=56,ab=24,channels=1}
    :standard{access=http{use-key-frames},mux=ts,dst=:3001/stream.mpeg}'
    

在Android VLC 0.0.11中它可以工作,但只能在WiFi下使用,不能在3G下使用。而且我无法在我的应用程序中使用VideoView播放它。以下是我使用的代码和相应的错误消息:

String url = "http://134.246.63.169:5554/stream.mpeg";

VideoView videoView = (VideoView) this.findViewById(R.id.videoView);
videoView.setVideoURI(Uri.parse(url));        
videoView.setMediaController(new MediaController(this));
videoView.requestFocus();  
videoView.start();

错误信息:

04-08 15:26:46.272: D/MediaPlayer(16349): Couldn't open file on client side, trying server side
04-08 15:26:46.272: V/ChromiumHTTPDataSource(7680): connect on behalf of uid 1080867789
04-08 15:26:46.272: I/ChromiumHTTPDataSource(7680): connect to http://134.246.63.169:8554/ @0
04-08 15:26:46.302: I/AwesomePlayer(7680): AwesomePlayer::AwesomePlayer()in
04-08 15:26:46.302: I/AwesomePlayer(7680): AwesomePlayer::AwesomePlayer()aftermClient.connect()
04-08 15:26:46.302: I/AwesomePlayer(7680): setDataSource_l('http://134.246.63.169:5554/')
04-08 15:26:46.302: W/MediaPlayer(16349): info/warning (701, 0)
04-08 15:26:46.302: V/ChromiumHTTPDataSource(7680): connect on behalf of uid 10067
04-08 15:26:46.302: I/ChromiumHTTPDataSource(7680): connect to http://134.246.63.169:5554/ @0
04-08 15:26:46.342: I/ActivityManager(272): Displayed fr.ifremer.testrtsp/.MainActivity: +183ms
04-08 15:26:46.382: I/MediaPlayer(16349): Info (701,0)
04-08 15:27:07.592: E/MediaPlayer(16349): error (1, -2147483648)
04-08 15:27:07.592: E/MediaPlayer(16349): Error (1,-2147483648)
  • RTSP:

我使用了Google在这个页面上推荐的编码选项,例如:

  • video codec : h264
  • audio codec : AAC
  • video bitrate : 56
  • audio bitrate : 24
  • audio channels : 1
  • size : 176x144

    ./vlc -vvv decklink:// --sout-ffmpeg-strict=-2 --sout
    '#transcode{width=176,height=144,vcodec=h264,acodec=mp4a,vb=56,ab=24,channels=1}
    :rtp{dst=134.246.63.169,port-video=5554,port-audio=5556,sdp=rtsp://134.246.63.169:5554/stream.sdp}'
    
我能在VLC桌面版本中播放流,但在Android设备上无法播放(包括Android版VLC或默认的Google视频播放器)。 如果我不指定复用器,我也可以在QuickTime中播放它(如果我指定复用器,无论是ts还是ps,都没有视频。如果我尝试使用其他复用器,VLC会告诉我只允许在RTP中使用ts或ps)。
如果我尝试使用Google视频播放器,则会在本地收到以下消息:
04-08 15:32:45.792: D/MediaPlayer(13688): Couldn't open file on client side, trying server side
04-08 15:32:45.802: W/MediaPlayer(13688): info/warning (701, 0)
04-08 15:32:45.812: I/MediaPlayer(13688): Info (701,0)
04-08 15:32:45.812: D/MediaPlayer(13688): getMetadata
04-08 15:32:45.812: E/MediaPlayerService(7680): getMetadata failed -38
04-08 15:32:45.852: I/MyHandler(7680): connection request completed with result 0 (Success)
04-08 15:32:45.882: I/ARTSPConnection(7680): status: RTSP/1.0 200 OK
04-08 15:32:45.882: I/MyHandler(7680): DESCRIBE completed with result 0 (Success)
04-08 15:32:45.882: I/ASessionDescription(7680): v=0
04-08 15:32:45.882: I/ASessionDescription(7680): o=- 15352003113363922923 15352003113363922923 IN IP4 to63-169.ifremer.fr
04-08 15:32:45.882: I/ASessionDescription(7680): s=Unnamed
04-08 15:32:45.882: I/ASessionDescription(7680): i=N/A
04-08 15:32:45.882: I/ASessionDescription(7680): c=IN IP4 134.246.63.169
04-08 15:32:45.882: I/ASessionDescription(7680): t=0 0
04-08 15:32:45.882: I/ASessionDescription(7680): a=tool:vlc 2.0.5
04-08 15:32:45.882: I/ASessionDescription(7680): a=recvonly
04-08 15:32:45.882: I/ASessionDescription(7680): a=type:broadcast
04-08 15:32:45.882: I/ASessionDescription(7680): a=charset:UTF-8
04-08 15:32:45.882: I/ASessionDescription(7680): a=control:rtsp://134.246.63.169:5554/stream.sdp
04-08 15:32:45.882: I/ASessionDescription(7680): m=audio 5556 RTP/AVP 96
04-08 15:32:45.882: I/ASessionDescription(7680): b=AS:24
04-08 15:32:45.882: I/ASessionDescription(7680): b=RR:0
04-08 15:32:45.882: I/ASessionDescription(7680): a=rtpmap:96 mpeg4-generic/48000
04-08 15:32:45.882: I/ASessionDescription(7680): a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=118856e500; SizeLength=13; IndexLength=3; IndexDeltaLength=3; Profile=1;
04-08 15:32:45.882: I/ASessionDescription(7680): a=control:rtsp://134.246.63.169:5554/stream.sdp/trackID=0
04-08 15:32:45.882: I/ASessionDescription(7680): m=video 5554 RTP/AVP 96
04-08 15:32:45.882: I/ASessionDescription(7680): b=AS:56
04-08 15:32:45.882: I/ASessionDescription(7680): b=RR:0
04-08 15:32:45.882: I/ASessionDescription(7680): a=rtpmap:96 H264/90000
04-08 15:32:45.882: I/ASessionDescription(7680): a=fmtp:96 packetization-mode=1;profile-level-id=64000b;sprop-parameter-sets=Z2QAC6zZQsTv/AC0ALBAAAADAEAAAAyjxQplgA==,aOvssiw=;
04-08 15:32:45.882: I/ASessionDescription(7680): a=control:rtsp://134.246.63.169:5554/stream.sdp/trackID=1
04-08 15:32:45.982: I/ARTSPConnection(7680): status: RTSP/1.0 200 OK
04-08 15:32:45.982: I/MyHandler(7680): SETUP(1) completed with result 0 (Success)
04-08 15:32:45.982: I/MyHandler(7680): server specified timeout of 60 secs.
04-08 15:32:45.992: W/MyHandler(7680): Missing 'source' field in Transport response. Using RTSP endpoint address.
04-08 15:32:45.992: I/APacketSource(7680): dimensions 176x144
04-08 15:32:46.012: I/ARTSPConnection(7680): status: RTSP/1.0 200 OK
04-08 15:32:46.022: I/MyHandler(7680): SETUP(2) completed with result 0 (Success)
04-08 15:32:46.022: I/MyHandler(7680): server specified timeout of 60 secs.
04-08 15:32:46.022: W/MyHandler(7680): Missing 'source' field in Transport response. Using RTSP endpoint address.
04-08 15:32:46.022: W/MyHandler(7680): Server picked an odd RTP port, it should've picked an even one, we'll let it pass for now, but this may break in the future.
04-08 15:32:46.082: I/ARTSPConnection(7680): status: RTSP/1.0 200 OK
04-08 15:32:46.082: D/dalvikvm(13688): GC_FOR_ALLOC freed 303K, 7% free 9289K/9927K, paused 35ms, total 36ms
04-08 15:32:46.092: I/MyHandler(7680): PLAY completed with result 0 (Success)
04-08 15:32:46.092: I/MyHandler(7680): This is a live stream
04-08 15:32:48.262: D/AudioHardware(7680): AudioHardware pcm playback is going to standby.
04-08 15:32:48.262: D/AudioHardware(7680): closePcmOut_l() mPcmOpenCnt: 1
04-08 15:32:56.092: W/MyHandler(7680): Never received any data, switching transports.
04-08 15:32:56.112: I/ARTSPConnection(7680): status: RTSP/1.0 200 OK
04-08 15:32:56.122: I/MyHandler(7680): TEARDOWN completed with result 0 (Success)
04-08 15:32:56.122: I/MyHandler(7680): connection request completed with result 0 (Success)
04-08 15:32:56.152: I/ARTSPConnection(7680): status: RTSP/1.0 200 OK
04-08 15:32:56.152: I/MyHandler(7680): DESCRIBE completed with result 0 (Success)
04-08 15:32:56.152: I/ASessionDescription(7680): v=0
04-08 15:32:56.152: I/ASessionDescription(7680): o=- 15352003157473632156 15352003157473632156 IN IP4 to63-169.ifremer.fr
04-08 15:32:56.152: I/ASessionDescription(7680): s=Unnamed
04-08 15:32:56.152: I/ASessionDescription(7680): i=N/A
04-08 15:32:56.152: I/ASessionDescription(7680): c=IN IP4 134.246.63.169
04-08 15:32:56.152: I/ASessionDescription(7680): t=0 0
04-08 15:32:56.152: I/ASessionDescription(7680): a=tool:vlc 2.0.5
04-08 15:32:56.152: I/ASessionDescription(7680): a=recvonly
04-08 15:32:56.152: I/ASessionDescription(7680): a=type:broadcast
04-08 15:32:56.152: I/ASessionDescription(7680): a=charset:UTF-8
04-08 15:32:56.152: I/ASessionDescription(7680): a=control:rtsp://134.246.63.169:5554/stream.sdp
04-08 15:32:56.152: I/ASessionDescription(7680): m=audio 5556 RTP/AVP 96
04-08 15:32:56.152: I/ASessionDescription(7680): b=AS:24
04-08 15:32:56.152: I/ASessionDescription(7680): b=RR:0
04-08 15:32:56.152: I/ASessionDescription(7680): a=rtpmap:96 mpeg4-generic/48000
04-08 15:32:56.152: I/ASessionDescription(7680): a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=118856e500; SizeLength=13; IndexLength=3; IndexDeltaLength=3; Profile=1;
04-08 15:32:56.152: I/ASessionDescription(7680): a=control:rtsp://134.246.63.169:5554/stream.sdp/trackID=0
04-08 15:32:56.152: I/ASessionDescription(7680): m=video 5554 RTP/AVP 96
04-08 15:32:56.152: I/ASessionDescription(7680): b=AS:56
04-08 15:32:56.152: I/ASessionDescription(7680): b=RR:0
04-08 15:32:56.152: I/ASessionDescription(7680): a=rtpmap:96 H264/90000
04-08 15:32:56.152: I/ASessionDescription(7680): a=fmtp:96 packetization-mode=1;profile-level-id=64000b;sprop-parameter-sets=Z2QAC6zZQsTv/AC0ALBAAAADAEAAAAyjxQplgA==,aOvssiw=;
04-08 15:32:56.152: I/ASessionDescription(7680): a=control:rtsp://134.246.63.169:5554/stream.sdp/trackID=1
04-08 15:32:56.222: I/ARTSPConnection(7680): status: RTSP/1.0 461 Unsupported transport
04-08 15:32:56.222: I/MyHandler(7680): SETUP(1) completed with result 0 (Success)
04-08 15:32:56.222: I/APacketSource(7680): dimensions 176x144
04-08 15:32:56.242: I/ARTSPConnection(7680): status: RTSP/1.0 461 Unsupported transport
04-08 15:32:56.252: I/MyHandler(7680): SETUP(2) completed with result 0 (Success)
04-08 15:32:56.272: E/MediaPlayer(13688): error (1, -2147483648)
04-08 15:32:56.272: E/MediaPlayer(13688): Error (1,-2147483648)
04-08 15:32:56.272: D/VideoView(13688): Error: 1,-2147483648

我猜问题出在"status: RTSP/1.0 461 Unsupported transport"上,但是我不知道我能改变什么:我已经打开使用的端口,并且在另一台电脑上接收到了视频。
在Android手机上,我可以播放我在网上找到的一些rtsp流,例如这个:rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov。所以应该是可能的。
如果有人能帮忙...!

你的问题解决了吗? - Nirav Bhandari
我还想开发一个应用程序,可以显示IP摄像机的实时流。我有经过身份验证的RSTP URL,但Android的VideoView不支持它。我还想记录RSTP...你能指导我如何实现这样的功能吗? - Nirav Bhandari
4个回答

8

最终问题是网络问题,我通过MacBook WiFi共享连接设备,似乎阻止了RTSP流。现在我使用路由器,RTSP可以正常工作(但我仍然无法在Android VideoView中接收HTTP流)。尽管如此,我仍然有超时问题:RTSP流在60秒后停止,因为VideoView没有发送保持活动消息。我将尝试自己解决这个问题...


那么错误信息:状态:RTSP/1.0 461 不支持的传输,真的意味着这是网络问题? - Robert

1

我已经使用openRTSP命令测试了我的rtsp服务器。

UDP端口被阻止了。

如果不使用-t访问rtsp:

-> $ openRTSP <rtsp_url>

我收到了一条日志,内容是:

// omit lots of lines..
Created receiver for "video/H264" subsession (client ports 63346-63347)
Sending request: SETUP rtsp://61.218.52.250:554/live/ch00_0/trackID=0 RTSP/1.0
CSeq: 4
User-Agent: openRTSP (LIVE555 Streaming Media v2013.12.16)
Transport: RTP/AVP;unicast;client_port=63346-63347

Received 47 new bytes of response data.
Received a complete SETUP response:
RTSP/1.0 461 Unsupported Transport
CSeq: 4

Failed to setup "video/H264" subsession: 461 Unsupported Transport

所以改用TCP:

-> $ openRTSP -t <rtsp_url>

它成功开始接收数据。

// omit lots of lines..
Opened URL "rtsp://61.218.52.250:554/live/ch00_0", returning a SDP description:
v=0
o=- 1 1 IN IP4 127.0.0.1
s=Ubiquiti Live
i=UBNT Streaming Media
c=IN IP4 0.0.0.0
t=0 0
m=video 0 RTP/AVP 99
b=AS:50000
a=framerate:25
a=x-dimensions:1280,720
a=x-vendor-id:ubnt,a521
a=x-rtp-ts:4617405454576779984
a=rtpmap:99 H264/90000
a=fmtp:99 profile-level-id=42A01E;packetization-mode=1;sprop-parameter-sets=Z0IAKOkAoAt1xIAG3dAAzf5gDYgQlA==,aM4xUg==
a=control:trackID=0

Sending request: SETUP rtsp://61.218.52.250:554/live/ch00_0/trackID=0 RTSP/1.0
CSeq: 4
User-Agent: openRTSP (LIVE555 Streaming Media v2013.12.16)
Transport: RTP/AVP/TCP;unicast;interleaved=0-1


Received 107 new bytes of response data.
Received a complete SETUP response:
RTSP/1.0 200 OK
CSeq: 4
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
Session: E090B5503236A1BFB7CE


Setup "video/H264" subsession (client ports 54884-54885)
Sending request: PLAY rtsp://61.218.52.250:554/live/ch00_0/ RTSP/1.0
CSeq: 5
User-Agent: openRTSP (LIVE555 Streaming Media v2013.12.16)
Session: E090B5503236A1BFB7CE
Range: npt=0.000-


Received 159 new bytes of response data.
Received a complete PLAY response:
RTSP/1.0 200 OK
CSeq: 5
Session: E090B5503236A1BFB7CE
Range: npt=now-
RTP-Info: url=rtsp://61.218.52.250:554/live/ch00_0//trackID=0;seq=41402;rtptime=0


Started playing session
Data is being streamed (signal with "kill -HUP 96432" or "kill -USR1 96432" to terminate)...
Received 47 new bytes of response data.
Received 1424 new bytes of response data.
Received 1424 new bytes of response data.
Received 1424 new bytes of response data.
Received 1424 new bytes of response data.
Received 1448 new bytes of response data.
Received 1448 new bytes of response data.

参考openRTSP基础知识。

现在我得弄清楚如何在Android上自动切换到TCP。


你解决了吗? - Curious Mind
1
抱歉,我已经多年没有接触那个项目了。上次我记得,就像@tim-autin提到的那样,呼叫会在短时间内停止。祝你好运。 - Robert


0

请尝试使用VLC:

vlc some_file.mp4 -I http --sout "#transcode{soverlay,ab=128,samplerate=44100,channels=2,acodec=mp4a,vcodec=h264,width=480,height=270,vfilter="canvas{width=480,height=270,aspect=16:9}",fps=25,vb=800,venc=x264{level=12,no-cabac,subme=20,threads=4,bframes=0,min-keyint=1,keyint=50}}:gather:rtp{mp4a-latm,sdp=rtsp://0.0.0.0:5554/stream.sdp}"

还有安卓代码:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final VideoView vidView = (VideoView)findViewById(R.id.myVideo);

        MediaController vidControl = new MediaController(this);
        vidControl.setAnchorView(vidView);
        vidView.setMediaController(vidControl);

        vidView.setVideoPath("rtsp://137.110.92.231:5554/stream.sdp");

        vidView.start();
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接