androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.61k stars 380 forks source link

Hikvision RTSP video streams that require authentication cannot be played #357

Closed BraveMomo closed 1 year ago

BraveMomo commented 1 year ago

Unfortunately we can't answer all questions. Unclear questions or questions with insufficient information may not get attention.

Before filing a question:

When filing a question:

Describe your question in detail.

In case your question refers to a problem you are seeing in your app:

Hikvision's RTSP format video stream that requires authentication cannot be played, in fact, the format is normal, however, it is normal to play with VLC, please tell me what to do,I have joined the required libraries as per the documentation

implementation "androidx.media3:media3-exoplayer-rtsp:1.0.1"

dispatcher 0x733df5c1c0 ~ ignoring unknown event type 0x736f6674 handleWindowVisibility: no activity for token android.os.BinderProxy@beba17a dispatcher 0x72d08abc00 ~ ignoring unknown event type 0x736f6674 restart watching callActivityOnCreate pkgName:com.example.exoplayercodelab old windowMode:0 new windoMode:1, isFixedSize:false add activity client record, r= ActivityRecord{bd063b4 token=android.os.BinderProxy@beba17a {com.example.exoplayercodelab/com.example.exoplayer.PlayerActivity}} token= android.os.BinderProxy@beba17a Init 8374352 [AndroidXMedia3/1.0.1] [HWALP, ALP-AL00, HUAWEI, 29] getStreamVolume streamType: 3 volume: 6 isStreamMute streamType: 3 getStreamMaxVolume treamType: 3 mMoveStepInDp: 64, mMoveStepInPixel: 218, mUpTimeDelayed: 100 ViewRootImpl mIsInProductivePCDisplay: false OPTIONS rtsp://112.219.20.115:554/h264/ch1/main/av_stream RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 0 pkgName:com.example.exoplayercodelab old windowMode:1 new windoMode:1, isFixedSize:false dispatchInputInterval 1000000 notifyActivityState pkg:com.example.exoplayercodelab/com.example.exoplayer.PlayerActivity state:2 fg:true mUid:10506 RTSP/1.0 200 OK CSeq: 0 Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER Date: Wed, Apr 26 2023 14:04:10 GMT onAttached, package=com.example.exoplayercodelab, windowType=1, mIsHiTouchRestricted=false DESCRIBE rtsp://112.219.20.115:554/h264/ch1/main/av_stream RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 1 EGLint new_window_surface(egl_winsys_display , void , EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 RTSP/1.0 401 Unauthorized CSeq: 1 WWW-Authenticate: Digest realm="IP Camera(C2732)", nonce="9f479ccb412b209b411039131bbfec69", stale="FALSE" WWW-Authenticate: Basic realm="IP Camera(C2732)" Date: Wed, Apr 26 2023 14:04:10 GMT DESCRIBE rtsp://112.219.20.115:554/h264/ch1/main/av_stream RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 2 Authorization: Digest username="admin", realm="IP Camera(C2732)", nonce="9f479ccb412b209b411039131bbfec69", uri="rtsp://112.219.20.115:554/h264/ch1/main/av_stream", response="f68adbefef6b0fa70fb865cf123cb16a" RTSP/1.0 200 OK CSeq: 2 Content-Type: application/sdp Content-Base: rtsp://112.219.20.115:554/h264/ch1/main/av_stream/ Content-Length: 752

v=0 o=- 1682517850717533 1682517850717533 IN IP4 172.29.2.115 s=Media Presentation e=NONE b=AS:5100 t=0 0 a=control:rtsp://112.219.20.115:554/h264/ch1/main/av_stream/ m=video 0 RTP/AVP 96 c=IN IP4 0.0.0.0 b=AS:5000 a=recvonly a=x-dimensions:1920,1080 a=control:rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=1 a=rtpmap:96 H264/90000 a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z00AKpY1QPAET8s3AQEBQAABwgAAV+QB,aO48gA== m=audio 0 RTP/AVP 8 c=IN IP4 0.0.0.0 b=AS:50 a=recvonly a=control:rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=2 a=rtpmap:8 PCMA/8000 a=Media_header:MEDIAINFO=494D4B48010200000400000111710110401F000000FA000000000000000000000000000000000000; a=appversion:1.0 SETUP rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=1 RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 3 Authorization: Digest username="admin", realm="IP Camera(C2732)", nonce="9f479ccb412b209b411039131bbfec69", uri="rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=1", response="326cfbe5881ce96cff4aec931de334f6" Transport: RTP/AVP;unicast;client_port=36618-36619 IOmx service obtained removeInvalidNode all the node in jank list is out of time In onAllocateComponent create compenent, codec name: OMX.hisi.video.decoder.avc connecting to surface 0x72d0b5f010, reason connectToSurface [OMX.hisi.video.decoder.avc] setting surface generation to 28574727 disconnecting from surface 0x72d0b5f010, reason connectToSurface(reconnect) connecting to surface 0x72d0b5f010, reason connectToSurface(reconnect) [OMX.hisi.video.decoder.avc] setPortMode on output to DynamicANWBuffer failed w/ err -2147483648 [OMX.hisi.video.decoder.avc] got color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) err=0(NO_ERROR) [OMX.hisi.video.decoder.avc] got color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) err=0(NO_ERROR) [OMX.hisi.video.decoder.avc] using color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) and dataspace 0x104 onStart Set to window composer mode as 1 gralloc usage: 0(OMX) => 0x2900(ACodec) disconnecting from surface 0x72d0b5f010, reason setNativeWindowSizeFormatAndUsage connecting to surface 0x72d0b5f010, reason setNativeWindowSizeFormatAndUsage set up nativeWindow 0x72d0b5f010 for 1920x1080, color 0x30d, rotation 0, usage 0x2900 disableOutlineDraw is true [OMX.hisi.video.decoder.avc] Allocating 5 buffers from a native window of size 3342336 on output port showOrHideHighlightView: hasFocus=true; winMode=1; isMrgNull=true startInputReason = 1 isCasting false because IHwDistributedWindowManager is invalid. init Rme, version is: v1.0 current pid:27905 AppType:-1 allocate(c2.android.g711.alaw.decoder) [OMX.hisi.video.decoder.avc] got color aspects (R:1(Full), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) err=0(NO_ERROR) [OMX.hisi.video.decoder.avc] got color aspects (R:1(Full), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) err=0(NO_ERROR) [OMX.hisi.video.decoder.avc] using color aspects (R:1(Full), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) and dataspace 0x8c10000 Created component [c2.android.g711.alaw.decoder] read media type: audio/g711-alaw extent() != 1 for single value type: algo.buffers.max-count.values extent() != 1 for single value type: output.subscribed-indices.values extent() != 1 for single value type: input.buffers.allocator-ids.values extent() != 1 for single value type: output.buffers.allocator-ids.values extent() != 1 for single value type: algo.buffers.allocator-ids.values extent() != 1 for single value type: output.buffers.pool-ids.values extent() != 1 for single value type: algo.buffers.pool-ids.values query failed after returning 7 values (BAD_INDEX) c2 config is Dict { c2::u32 coded.bitrate.value = 64000 c2::u32 input.buffers.max-size.value = 8192 c2::u32 input.delay.value = 0 string input.media-type.value = "audio/g711-alaw" string output.media-type.value = "audio/raw" c2::u32 raw.channel-count.value = 1 c2::u32 raw.sample-rate.value = 8000 } query -- param skipped: index = 1107298332. setup formats input: AMessage(what = 0x00000000) = { int32_t channel-count = 1 int32_t max-input-size = 8192 string mime = "audio/g711-alaw" int32_t sample-rate = 8000 } and output: AMessage(what = 0x00000000) = { int32_t channel-count = 1 string mime = "audio/raw" int32_t sample-rate = 8000 } query -- param skipped: index = 1342179345. query -- param skipped: index = 2415921170.

of cleaned connections: 0

create new connection 119852744883380 [c2.android.g711.alaw.decoder#594] Created input block pool with allocatorID 16 => poolID 20 - OK (0) [c2.android.g711.alaw.decoder#594] Created output block pool with allocatorID 16 => poolID 837 - OK [c2.android.g711.alaw.decoder#594] Configured output block pool ids 837 => OK RTSP/1.0 200 OK CSeq: 3 Session: 1299260789;timeout=60 Transport: RTP/AVP;unicast;client_port=36618-36619;server_port=8314-8315;ssrc=0cb32b85;mode="play" Date: Wed, Apr 26 2023 14:04:10 GMT SETUP rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=2 RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 4 Session: 1299260789 Authorization: Digest username="admin", realm="IP Camera(C2732)", nonce="9f479ccb412b209b411039131bbfec69", uri="rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=2", response="bfa5baea544f77c99fc5906efc47c1bf" Transport: RTP/AVP;unicast;client_port=60830-60831 win=Window{aad0f59 u0 Splash Screen com.example.exoplayercodelab EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true RTSP/1.0 200 OK CSeq: 4 Session: 1299260789;timeout=60 Transport: RTP/AVP;unicast;client_port=60830-60831;server_port=8316-8317;ssrc=529f1429;mode="play" Date: Wed, Apr 26 2023 14:04:10 GMT PLAY rtsp://112.219.20.115:554/h264/ch1/main/av_stream RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 5 Session: 1299260789 Authorization: Digest username="admin", realm="IP Camera(C2732)", nonce="9f479ccb412b209b411039131bbfec69", uri="rtsp://112.219.20.115:554/h264/ch1/main/av_stream", response="875d5fdb15409bddb81f43d91eabb571" Range: npt=0.000- RTSP/1.0 200 OK CSeq: 5 Session: 1299260789 RTP-Info: url=rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=1;seq=14301;rtptime=1091472994,url=rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=2;seq=47273;rtptime=1576408 Date: Wed, Apr 26 2023 14:04:10 GMT dispatcher 0x72d08abc00 ~ ignoring unknown event type 0x736f6674 dispatcher 0x733df5c1c0 ~ ignoring unknown event type 0x736f6674 TEARDOWN rtsp://112.219.20.115:554/h264/ch1/main/av_stream RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 6 Session: 1299260789 Authorization: Digest username="admin", realm="IP Camera(C2732)", nonce="9f479ccb412b209b411039131bbfec69", uri="rtsp://112.219.20.115:554/h264/ch1/main/av_stream", response="1eba7a65e77e65a3e929b08e88bba6bc" SETUP rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=1 RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 7 Transport: RTP/AVP/TCP;unicast;interleaved=0-1 RTSP/1.0 401 Unauthorized CSeq: 7 WWW-Authenticate: Digest realm="IP Camera(C2732)", nonce="02da6fdeaa3be9ed907dca3a38255b61", stale="FALSE" WWW-Authenticate: Basic realm="IP Camera(C2732)" Date: Wed, Apr 26 2023 14:04:18 GMT SETUP rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=1 RTSP/1.0 User-Agent: AndroidXMedia3/1.0.1 CSeq: 8 Authorization: Digest username="admin", realm="IP Camera(C2732)", nonce="02da6fdeaa3be9ed907dca3a38255b61", uri="rtsp://112.219.20.115:554/h264/ch1/main/av_stream/trackID=1", response="8d3447c332ce45a454a9c7d0f64e2f4f" Transport: RTP/AVP/TCP;unicast;interleaved=0-1 RTSP/1.0 401 Unauthorized CSeq: 8 WWW-Authenticate: Digest realm="IP Camera(C2732)", nonce="a0efb3318a2e828eefcdf6f56d433cd5", stale="FALSE" WWW-Authenticate: Basic realm="IP Camera(C2732)" Date: Wed, Apr 26 2023 14:04:18 GMT Playback error androidx.media3.exoplayer.ExoPlaybackException: Source error at androidx.media3.exoplayer.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:652) at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:628) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:219) at android.os.HandlerThread.run(HandlerThread.java:67) Caused by: androidx.media3.exoplayer.rtsp.RtspMediaSource$RtspPlaybackException: SETUP 401 at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:585) at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:508) at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$androidx-media3-exoplayer-rtsp-RtspClient$MessageListener(RtspClient.java:501) at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener$$ExternalSyntheticLambda0.run(Unknown Source:4) at android.os.Handler.handleCallback(Handler.java:900) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loop(Looper.java:219)  at android.os.HandlerThread.run(HandlerThread.java:67)  kWhatFlush processing is complete [OMX.hisi.video.decoder.avc] ExecutingState flushing now (codec owns 1/5 input, 1/5 output). Start Processing kWhatFlushCompleted kWhatFlush processing is complete [c2.android.g711.alaw.decoder#594] flush Start Processing kWhatFlushCompleted query failed after returning 7 values (BAD_INDEX) query -- param skipped: index = 1342179345. query -- param skipped: index = 2415921170. [c2.android.g711.alaw.decoder#594] onWorkDone: output format changed to AMessage(what = 0x00000000) = { int32_t channel-count = 1 string mime = "audio/raw" int32_t sample-rate = 8000 } forcing OMX state to Idle when received shutdown in ExecutingState disconnecting from surface 0x72d0b5f010, reason disconnectFromSurface buffer invalidation added bp:3 1 buffer invalidation deleted bp:3 bufferpool2 0x72be54fa20 : 0(0 size) total buffers - 0(0 size) used buffers - 0/5 (recycle/alloc) - 0/0 (fetch/transfer) Destruction - bufferpool2 0x72be54fa20 cached: 0/0M, 0/0% in use; allocs: 5, 0% recycled; transfers: 0, 0% unfetced

In case your question is related to a piece of media:

Don't forget to check ExoPlayer's supported formats and devices, if applicable (https://developer.android.com/guide/topics/media/exoplayer/supported-formats).

If there's something you don't want to post publicly, please submit the issue, then email the link/bug report to dev.exoplayer@gmail.com using a subject in the format "Issue #1234", where #1234 is your issue number (we don't reply to emails).

microkatz commented 1 year ago

Hello @BraveHL,

Thank you for reporting your issue. This is the scenario as I see from your logs: 1) RTSP Setup for UDP stream: I see the Describe, Setup, Play for successful RTSP stream setup. Setup request has attribute "Transport: RTP/AVP" 2) The ExoPlayer RTSP client did not receive any RTP packets so it retries with TCP. When it retries, it removes the authorization info from the UDP session. I see a new SETUP command with attribute "Transport: RTP/AVP/TCP" 3) The attempt with TCP calls SETUP without authorization info and rightfully gets HTTP 401 with authentication challenge. 4) The RTSP client attempts to resend the message with the authentication header info but receives another HTTP 401 error. 5) ExoPlayer dispatches PlaybackError

What is odd is all the previous RTSP requests with authentication headers during the UDP attempt passed. It only failed when trying to setup with TCP. Does your camera have some odd configuration where your credentials are only viable for UDP streaming and not TCP?

BraveMomo commented 1 year ago

Hello @BraveHL,

Thank you for reporting your issue. This is the scenario as I see from your logs:

  1. RTSP Setup for UDP stream: I see the Describe, Setup, Play for successful RTSP stream setup. Setup request has attribute "Transport: RTP/AVP"
  2. The ExoPlayer RTSP client did not receive any RTP packets so it retries with TCP. When it retries, it removes the authorization info from the UDP session. I see a new SETUP command with attribute "Transport: RTP/AVP/TCP"
  3. The attempt with TCP calls SETUP without authorization info and rightfully gets HTTP 401 with authentication challenge.
  4. The RTSP client attempts to resend the message with the authentication header info but receives another HTTP 401 error.
  5. ExoPlayer dispatches PlaybackError

What is odd is all the previous RTSP requests with authentication headers during the UDP attempt passed. It only failed when trying to setup with TCP. Does your camera have some odd configuration where your credentials are only viable for UDP streaming and not TCP?

I don't know much about what you said, I don't know much about this piece of video streaming, I use the company's Hikvision camera, everything is almost the default setting, I can't easily modify it, how should I modify the code to solve this problem?

microkatz commented 1 year ago

@BraveHL.

I understand. I'm not sure that its an issue of our library but rather an issue of the camera. However, I can still try and help.

We can try simplifying the scenario. Although the camera does not advertise its inability to support streaming over UDP, I can see from the logs that it does not support that. I would suggest that we configure the Player to try and use TCP from the start.

In your setup of RtspMediaSource.Factory, you would want to run the command setForceUseRtpTcp(true).

If you were following our dev page for setup. It would look something like this:

// Create an RTSP media source pointing to an RTSP uri.
MediaSource mediaSource =
    new RtspMediaSource.Factory()
        .setForceUseRtpTcp(true)
        .createMediaSource(MediaItem.fromUri(rtspUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media source to be played.
player.setMediaSource(mediaSource);
// Prepare the player.
player.prepare();

If that works then you can maybe make setForceUseRtpTcp to be conditionally dependent on whether you are streaming from that quirky Hikvision device.

If that doesn't work then please comment back with logs. Thank you!

BraveMomo commented 1 year ago

@BraveHL.

I understand. I'm not sure that its an issue of our library but rather an issue of the camera. However, I can still try and help.

We can try simplifying the scenario. Although the camera does not advertise its inability to support streaming over UDP, I can see from the logs that it does not support that. I would suggest that we configure the Player to try and use TCP from the start.

In your setup of RtspMediaSource.Factory, you would want to run the command setForceUseRtpTcp(true).

If you were following our dev page for setup. It would look something like this:

// Create an RTSP media source pointing to an RTSP uri.
MediaSource mediaSource =
    new RtspMediaSource.Factory()
        .setForceUseRtpTcp(true)
        .createMediaSource(MediaItem.fromUri(rtspUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media source to be played.
player.setMediaSource(mediaSource);
// Prepare the player.
player.prepare();

If that works then you can maybe make setForceUseRtpTcp to be conditionally dependent on whether you are streaming from that quirky Hikvision device.

If that doesn't work then please comment back with logs. Thank you!

Writing like this doesn't work, it seems that nothing happened, here is the log

handleWindowVisibility: no activity for token android.os.BinderProxy@cec9c00 restart watching dispatcher 0xbc940300 ~ ignoring unknown event type 0x736f6674 callActivityOnCreate pkgName:com.example.media old windowMode:0 new windoMode:1, isFixedSize:false add activity client record, r= ActivityRecord{acd5f2d token=android.os.BinderProxy@cec9c00 {com.example.media/com.example.media.MainActivity}} token= android.os.BinderProxy@cec9c00 Init 1d331f3 [AndroidXMedia3/1.0.1] [HWALP, ALP-AL00, HUAWEI, 29] getStreamVolume streamType: 3 volume: 0 isStreamMute streamType: 3 getStreamMaxVolume treamType: 3 Init 14dc129 [AndroidXMedia3/1.0.1] [HWALP, ALP-AL00, HUAWEI, 29] getStreamVolume streamType: 3 volume: 0 isStreamMute streamType: 3 getStreamMaxVolume treamType: 3 mMoveStepInDp: 64, mMoveStepInPixel: 218, mUpTimeDelayed: 100 ViewRootImpl mIsInProductivePCDisplay: false dispatcher 0xe58acbb0 ~ ignoring unknown event type 0x736f6674 pkgName:com.example.media old windowMode:1 new windoMode:1, isFixedSize:false dispatchInputInterval 1000000 notifyActivityState pkg:com.example.media/com.example.media.MainActivity state:2 fg:true mUid:10523 disableOutlineDraw is true onAttached, package=com.example.media, windowType=1, mIsHiTouchRestricted=false EGLint new_window_surface(egl_winsys_display , void , EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 removeInvalidNode all the node in jank list is out of time showOrHideHighlightView: hasFocus=true; winMode=1; isMrgNull=true startInputReason = 1 isCasting false because IHwDistributedWindowManager is invalid. init Rme, version is: v1.0 current pid:5829 AppType:-1 win=Window{a9bd759 u0 Splash Screen com.example.media EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true dispatcher 0xe58acbb0 ~ ignoring unknown event type 0x736f6674 dispatcher 0xbc940300 ~ ignoring unknown event type 0x736f6674 stop UiProbe not watching, wait. APS: EventAnalyzed: initAPS: version is 11.0.0.4 Fpsrequest create,type:EXACTLY_IDENTIFY Fpsrequest create,type:EXACTLY_IDENTIFY Fpsrequest create,type:OPENGL_SETTING FpsController create APS: EventAnalyzed: reInitFpsPara :mBaseFps = 60; mMaxFps = 60 Setting device_provisioned has moved from android.provider.Settings.Secure to android.provider.Settings.Global. User setup is finished. HwApsManagerService, registerCallback, start ! APS: EventAnalyzed: registerCallbackInApsManagerService, mPkgName:com.example.media; result = true removeInvalidNode all the node in jank list is out of time

microkatz commented 1 year ago

@BraveHL

Writing like this doesn't work, it seems that nothing happened, here is the log

I don't see any of the RTSP related logs like we saw from the report in your first post. How different is your code from the first scenario to the new code when you were only supposed to add .setForceUseRtpTcp(true) to the RtspMediaSource.Factory()? It should be exactly the same except for that one factory setting change.

Can you also add player.addAnalyticsListener(new EventLogger()) if its not there already? Make sure its added before any call to prepare() or setMediaSource().

BraveMomo commented 1 year ago
setForceUseRtpTcp

When changed to setForceUseRtpTcp's writing, I wrote it incorrectly, and after correcting it it loads normally, thanks

microkatz commented 1 year ago

Great! I'm glad the solution worked for you. I'm going to close this issue. Please reopen if that is not the case.