google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.75k stars 6.03k forks source link

RTSP: Support absolute timing #10804

Open ricardomorarey opened 2 years ago

ricardomorarey commented 2 years ago

ExoPlayer Version

2.18.1

Devices that reproduce the issue

Motorola Moto g30 Android 12

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

When I reproduce this uri of a hikvision ip camera, the reproduction does not give me any problem: rtsp://xxx:xxx@host:port/ISAPI/Streaming/Channels/301

but if i try to play with this uri (which worked ok in vlc and other libraries): rtsp://xxx:xxx@host:port/ISAPI/Streaming/tracks/301?starttime=20221121T073315Z

it gives me the following error:

2022-11-22 11:40:21.832 4783-4850/com.example.tssexoprueba E/ExoPlayerImplInternal: Playback error com.google.android.exoplayer2.ExoPlaybackException: Source error at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:632) at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:608) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:329) at android.os.HandlerThread.run(HandlerThread.java:67) Caused by: java.io.IOException: SDP format error. at com.google.android.exoplayer2.source.rtsp.RtspMediaPeriod$InternalListener.onSessionTimelineRequestFailed(RtspMediaPeriod.java:652) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.onDescribeResponseReceived(RtspClient.java:685) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:598) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:507) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$com-google-android-exoplayer2-source-rtsp-RtspClient$MessageListener(RtspClient.java:500) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener$$ExternalSyntheticLambda0.run(Unknown Source:4) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226)  at android.os.Looper.loop(Looper.java:329)  at android.os.HandlerThread.run(HandlerThread.java:67)  Caused by: com.google.android.exoplayer2.ParserException: clock=20221121T073315Z-20221122T113914Z at com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.checkManifestExpression(RtspMessageUtil.java:471) at com.google.android.exoplayer2.source.rtsp.RtspSessionTiming.parseTiming(RtspSessionTiming.java:51) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.onDescribeResponseReceived(RtspClient.java:683) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:598)  at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:507)  at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$com-google-android-exoplayer2-source-rtsp-RtspClient$MessageListener(RtspClient.java:500)  at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener$$ExternalSyntheticLambda0.run(Unknown Source:4)  at android.os.Handler.handleCallback(Handler.java:938)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loopOnce(Looper.java:226)  at android.os.Looper.loop(Looper.java:329)  at android.os.HandlerThread.run(HandlerThread.java:67) 

Expected result

The media plays ok

Actual result

it gives me an error

Media

Not applicable

Bug Report

christosts commented 2 years ago

@claincly can you take a look?

claincly commented 2 years ago

Please provide a log of RTSP messages.

The easiest way is to use the RtspMediaSource.Factory method setDebugLoggingEnabled()

That is, set the media source factory when building the ExoPlayer instance, like this:

     SimpleExoPlayer player =
          new ExoPlayer.Builder(/* context= */ this)
              .set... // all other customization
              .setMediaSourceFactory(new RtspMediaSource.Factory().setDebugLoggingEnabled(true))
              .build()
ricardomorarey commented 2 years ago

Yes, of course. Here you have:

D/RtspClient: OPTIONS rtsp://xxxxxxxxxxxxxxxxxxxxxxx:554/ISAPI/Streaming/tracks/301?starttime=20221121T000000Z RTSP/1.0 User-Agent: ExoPlayerLib/2.18.1 CSeq: 0 D/RtspClient: RTSP/1.0 401 Unauthorized CSeq: 0 WWW-Authenticate: Digest realm="89ecc56c2badadaa4d82682d", nonce="024f9cfe5", algorithm="MD5" D/RtspClient: OPTIONS rtsp://xxxxxxxxxxxxxxxxxxxxxxx:554/ISAPI/Streaming/tracks/301?starttime=20221121T000000Z RTSP/1.0 User-Agent: ExoPlayerLib/2.18.1 CSeq: 1 Authorization: Digest username="xxxx", realm="89ecc56c2badadaa4d82682d", nonce="024f9cfe5", uri="rtsp://xxxxxxxxxxxxxxxxxxxxxxx/ISAPI/Streaming/tracks/301?starttime=20221121T000000Z", response="28f6906d9310fd501ffb3438ad0db774"

D/RtspClient: RTSP/1.0 200 OK CSeq: 1 Public: OPTIONS, DESCRIBE, SETUP, PLAY, TEARDOWN, PAUSE, SET_PARAMETER, GET_PARAMETER Date: Tue, 22 Nov 2022 15:53:59 GMT D/RtspClient: DESCRIBE rtsp://xxxxxxxxxxxxxxxxxxxxxxx:554/ISAPI/Streaming/tracks/301?starttime=20221121T000000Z RTSP/1.0 User-Agent: ExoPlayerLib/2.18.1 CSeq: 2 Authorization: Digest username="xxxx", realm="89ecc56c2badadaa4d82682d", nonce="024f9cfe5", uri="rtsp://xxxxxxxxxxxxxxxxxxxxxxx:554/ISAPI/Streaming/tracks/301?starttime=20221121T000000Z", response="172abad0dd72ade00a375187abfa23ab" D/hw-ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument D/RtspClient: RTSP/1.0 200 OK CSeq: 2 Content-Type: application/sdp Content-Length: 602 Date: Tue, 22 Nov 2022 15:53:59 GMT

v=0
o=- 1109162014219182 0 IN IP4 0.0.0.0
s=HIK Media Server V4.32.110
i=HIK Media Server Session Description : standard
e=NONE
c=IN IP4 0.0.0.0
t=0 0
a=control:*
b=AS:4106
a=range:clock=20221121T000000Z-20221122T165233Z
m=video 0 RTP/AVP 96
i=Video Media
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=4D0014;packetization-mode=0
a=control:trackID=video
b=AS:4096
m=audio 0 RTP/AVP 0
i=Audio Media
a=rtpmap:0 PCMU/8000
a=control:trackID=audio
b=AS:10
a=Media_header:MEDIAINFO=494D4B48020100000400000110710110401F000000FA000000000000000000000000000000000000;
a=appversion:1.0

and followed the mistake:

E/ExoPlayerImplInternal: Playback error com.google.android.exoplayer2.ExoPlaybackException: Source error at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:632) at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:608) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:329) at android.os.HandlerThread.run(HandlerThread.java:67) Caused by: java.io.IOException: SDP format error. at com.google.android.exoplayer2.source.rtsp.RtspMediaPeriod$InternalListener.onSessionTimelineRequestFailed(RtspMediaPeriod.java:652) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.onDescribeResponseReceived(RtspClient.java:685) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:598) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:507) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$com-google-android-exoplayer2-source-rtsp-RtspClient$MessageListener(RtspClient.java:500) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener$$ExternalSyntheticLambda0.run(Unknown Source:4) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226)  at android.os.Looper.loop(Looper.java:329)  at android.os.HandlerThread.run(HandlerThread.java:67)  Caused by: com.google.android.exoplayer2.ParserException: clock=20221121T000000Z-20221122T165233Z at com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.checkManifestExpression(RtspMessageUtil.java:471) at com.google.android.exoplayer2.source.rtsp.RtspSessionTiming.parseTiming(RtspSessionTiming.java:51) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.onDescribeResponseReceived(RtspClient.java:683) at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:598)  at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:507)  at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$com-google-android-exoplayer2-source-rtsp-RtspClient$MessageListener(RtspClient.java:500)  at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener$$ExternalSyntheticLambda0.run(Unknown Source:4)  at android.os.Handler.handleCallback(Handler.java:938)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loopOnce(Looper.java:226)  at android.os.Looper.loop(Looper.java:329)  at android.os.HandlerThread.run(HandlerThread.java:67)  W/System: A resource failed to call close.

Thanks!

claincly commented 2 years ago

The issue is in the SDP message, specifically a=range:clock=20221121T000000Z-20221122T165233Z

RTSP standards defined three timing schemes: SMPTE timestamp, Normal Play Time (NPT) and absolute time (the one you have). Our RTSP currently only supports NPT.

I filed a bug about supporting it internally, but I am afraid we don't have an estimate of when we can get around to this.

ricardomorarey commented 2 years ago

OK. thank you very much!