React-native-track-player: [iOS] TrackPlayer.setRate() crashes in debug mode

Created on 29 Mar 2019  路  12Comments  路  Source: react-native-kit/react-native-track-player

Hey developing on the simulator for iOS and whenever I call TrackPlayer.setRate(1) my xCode crashes. I know this was working earlier even on the same version because I was messing around with it to see if it worked.
I'm on the dev branch of the react-native-track-player.

Not to great at iOS development so was wondering if this is something obvious that I'm doing wrong since it was working great literally minutes before it kept crashing on me.

Repro steps:

  1. Initialize TrackPlayer with await TrackPlayer.setupPlayer()
  2. Call `TrackPlayer.setRate(1) quickly as if you're dragging a slider setting the speed rate.
  3. XCode should crash with this error
2019-03-28 17:57:55.503725-0700 Repod[15276:595377] Task <AC8E6098-246B-4A20-A6A5-961014417AB9>.<1> load failed with error Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://content.production.cdn.art19.com/episodes/fdb8107c-8e89-47a3-84f0-a16e6842aadf/060e946dcf23085f3df431255d9ce62232a3684afdc3e3704aeb6b86cdfbeaa41ad6e035cf4872ca51f8a33b223ae6ff1d07b114fc573498dc31a3fdb74eb5b5/20190305%20TD%20MASTER%20SUBMIX%20CW%20FINAL.mp3, NSErrorFailingURLKey=https://content.production.cdn.art19.com/episodes/fdb8107c-8e89-47a3-84f0-a16e6842aadf/060e946dcf23085f3df431255d9ce62232a3684afdc3e3704aeb6b86cdfbeaa41ad6e035cf4872ca51f8a33b223ae6ff1d07b114fc573498dc31a3fdb74eb5b5/20190305%20TD%20MASTER%20SUBMIX%20CW%20FINAL.mp3, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <AC8E6098-246B-4A20-A6A5-961014417AB9>.<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <AC8E6098-246B-4A20-A6A5-961014417AB9>.<1>, NSLocalizedDescription=cancelled} [-999]
Setting rate to 1.6
Simultaneous accesses to 0x600003f158d0, but modification requires exclusive access.
Previous access (a modification) started at Repod`AudioPlayer.rate.setter + 68 (0x104a881c4).
Current access (a read) started at:
0    libswiftCore.dylib                 0x000000010df98d10 swift_beginAccess + 469
1    Repod                              0x0000000104a86850 AudioPlayer.wrapper.getter + 59
2    Repod                              0x0000000104a8a130 AudioPlayer.updatePlaybackValues() + 206
3    Repod                              0x0000000104a8a810 AudioPlayer.AVWrapper(didChangeState:) + 79
4    Repod                              0x0000000104a8ae20 protocol witness for AVPlayerWrapperDelegate.AVWrapper(didChangeState:) in conformance AudioPlayer + 23
5    Repod                              0x0000000104ab7a80 AVPlayerWrapper._state.didset + 371
6    Repod                              0x0000000104ab7c60 AVPlayerWrapper._state.setter + 184
7    Repod                              0x0000000104abaaf0 AVPlayerWrapper.player(didChangeTimeControlStatus:) + 250
8    Repod                              0x0000000104abb130 protocol witness for AVPlayerObserverDelegate.player(didChangeTimeControlStatus:) in conformance AVPlayerWrapper + 9
9    Repod                              0x0000000104a8e350 AVPlayerObserver.handleTimeControlStatusChange(_:) + 860
10   Repod                              0x0000000104a8d3b0 AVPlayerObserver.observeValue(forKeyPath:of:change:context:) + 693
11   Repod                              0x0000000104a8dc90 @objc AVPlayerObserver.observeValue(forKeyPath:of:change:context:) + 635
12   Foundation                         0x0000000106886e9f NSKeyValueNotifyObserver + 332
13   Foundation                         0x000000010688a4ad NSKeyValueDidChange + 489
14   Foundation                         0x0000000106886569 NSKeyValueDidChangeWithPerThreadPendingNotifications + 143
15   AVFoundation                       0x000000010781352c -[AVPlayer setRate:withVolumeRampDuration:playImmediately:rateChangeReason:] + 684
16   AVFoundation                       0x00000001078139ef -[AVPlayer setRate:] + 82
17   Repod                              0x0000000104ab9580 AVPlayerWrapper.rate.setter + 73
18   Repod                              0x0000000104aba770 protocol witness for AVPlayerWrapperProtocol.rate.setter in conformance AVPlayerWrapper + 24
19   Repod                              0x0000000104a88180 AudioPlayer.rate.setter + 125
20   Repod                              0x0000000104aab2a0 RNTrackPlayer.setRate(rate:resolve:reject:) + 571
21   Repod                              0x0000000104aab560 @objc RNTrackPlayer.setRate(rate:resolve:reject:) + 245
22   CoreFoundation                     0x0000000109196fb0 __invoking___ + 140
23   CoreFoundation                     0x0000000109194390 -[NSInvocation invoke] + 325
24   CoreFoundation                     0x00000001091948f0 -[NSInvocation invokeWithTarget:] + 54
25   Repod                              0x0000000104b6eca0 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 2810
26   Repod                              0x0000000104c2b2b0 facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&) + 790
27   Repod                              0x0000000104c2b060 facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)::$_0::operator()() const + 127
28   Repod                              0x0000000104c2b040 invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int) + 25
29   libdispatch.dylib                  0x000000010e938589 _dispatch_call_block_and_release + 12
30   libdispatch.dylib                  0x000000010e9395fa _dispatch_client_callout + 8
31   libdispatch.dylib                  0x000000010e9407f4 _dispatch_lane_serial_drain + 791
32   libdispatch.dylib                  0x000000010e9415d8 _dispatch_lane_invoke + 428
33   libdispatch.dylib                  0x000000010e94b5bd _dispatch_workloop_worker_thread + 733
34   libsystem_pthread.dylib            0x000000010ed28483 _pthread_wqthread + 409
35   libsystem_pthread.dylib            0x000000010ed28408 start_wqthread + 13

The stack trace looks like its having a permissions issue which might make sense why it worked initially and then crashed after? Potentially we're writing to and reading from some array at the same time. I did change rates quickly

Edit
It works the first time on any device (simulator or real device) but then will throw this, and then anytime rate is set after this it's just crashing.

iOS

Most helpful comment

@CapitanRedBeard

Can this patch fix your issue?

node_modules/react-native-track-player/ios/RNTrackPlayer/Vendor/AudioPlayer/AVPlayerWrapper/AVPlayerWrapperProtocol.swift

-protocol AVPlayerWrapperProtocol {
+protocol AVPlayerWrapperProtocol: class {

All 12 comments

Apparently this might blow up in release mode too in Swift 5: https://swift.org/blog/swift-5-exclusivity/

For anyone else the only way I can get around this is to only call TrackPlayer.setRate(rate) when in release mode which I know isn't great.

I will look into this, another thing you could do, is @debounce your slider so it doesn't rapidly fire events through the bridge trying to update the rate.

@dcvz Yeah ended up doing this although it doesn't seem the fix the problem. If I call setRate a certain about of times within the app lifetime it will start to throw this, and then after that it will throw it on every new time. The time in which is starts throwing seems to very. I've seen it on fresh install and I've seen it take a few iterations so I can't quite narrow it down. Right now I'm just avoiding using the setRate method at all in dev mode (if (!__DEV__) { TrackPlayer.setRate(...)), but that's obviously a temporary solution

@CapitanRedBeard

Can this patch fix your issue?

node_modules/react-native-track-player/ios/RNTrackPlayer/Vendor/AudioPlayer/AVPlayerWrapper/AVPlayerWrapperProtocol.swift

-protocol AVPlayerWrapperProtocol {
+protocol AVPlayerWrapperProtocol: class {

I can't repo this crash locally but in production, i see lots of report of this crash. Here is the sentry crash report
https://sentry.io/share/issue/6dc1f3e2dcd2430aa11b3e3b095b7703/

Thread 14 Crashed:
0   libswiftCore.dylib              0x3e508f7ec         swift_isUniquelyReferenced_nonNull_native
1   AmharicRadio                    0x2007fe264         __cxa_throw
2   AmharicRadio                    0x2007fcc4c         __cxa_throw
3   AmharicRadio                    0x2007fce38         __cxa_throw
4   AmharicRadio                    0x2008099e0         __cxa_throw
5   AmharicRadio                    0x20081cd2c         __cxa_throw
6   AmharicRadio                    0x20081b444         __cxa_throw
7   AmharicRadio                    0x20081aaf4         __cxa_throw
8   AmharicRadio                    0x20081ac68         __cxa_throw
9   Foundation                      0x38acbdb78         NSKeyValueNotifyObserver
10  Foundation                      0x38acbff0c         NSKeyValueDidChange
11  Foundation                      0x38acbd42c         NSKeyValueDidChangeWithPerThreadPendingNotifications.llvm.1079274171907039812
12  AVFoundation                    0x3956b947c         -[AVPlayer setRate:withVolumeRampDuration:playImmediately:rateChangeReason:]
13  AVFoundation                    0x3956b960c         -[AVPlayer setRate:]
14  AmharicRadio                    0x20081e700         __cxa_throw
15  AmharicRadio                    0x200808cb0         __cxa_throw
16  AmharicRadio                    0x20082c1c4         __cxa_throw
17  AmharicRadio                    0x2008243bc         __cxa_throw
18  CoreFoundation                  0x38980fba0         __invoking___
19  CoreFoundation                  0x3896f1c90         -[NSInvocation invoke]
20  CoreFoundation                  0x3896f28c4         -[NSInvocation invokeWithTarget:]
21  AmharicRadio                    0x200396808         _ZN8facebook5react11JSIExecutor21defaultTimeoutInvokerERKNSt3__18functionIFvvEEENS3_IFNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEvEEE
22  AmharicRadio                    0x2003d5eec         _ZN8facebook5react11JSIExecutor21defaultTimeoutInvokerERKNSt3__18functionIFvvEEENS3_IFNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEvEEE
23  AmharicRadio                    0x2003d5c4c         _ZN8facebook5react11JSIExecutor21defaultTimeoutInvokerERKNSt3__18functionIFvvEEENS3_IFNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEvEEE
24  libdispatch.dylib               0x388d41a38         _dispatch_call_block_and_release
25  libdispatch.dylib               0x388d427d4         _dispatch_client_callout
26  libdispatch.dylib               0x388d1ddec         _dispatch_lane_serial_drain$VARIANT$armv81
27  libdispatch.dylib               0x388d1e92c         _dispatch_lane_invoke$VARIANT$armv81
28  libdispatch.dylib               0x388d26e08         _dispatch_workloop_worker_thread
29  libsystem_pthread.dylib         0x389156114         _pthread_wqthread

I've got similar crash in debug mode without trying to change rate, and it seems to be connected with automaticallyWaitsToMinimizeStalling and https://github.com/react-native-kit/react-native-track-player/pull/490 ,

Simultaneous accesses to 0x608000141e50, but modification requires exclusive access.
Previous access (a modification) started at AzRadio`AudioPlayer.automaticallyWaitsToMinimizeStalling.setter + 91 (0x107708a3b).
Current access (a read) started at:
0    libswiftCore.dylib                 0x000000010f2a7d10 swift_beginAccess + 469
1    AzRadio                            0x0000000107707680 AudioPlayer.wrapper.getter + 59
2    AzRadio                            0x000000010770b030 AudioPlayer.updatePlaybackValues() + 206
3    AzRadio                            0x000000010770b710 AudioPlayer.AVWrapper(didChangeState:) + 79
4    AzRadio                            0x000000010770bd20 protocol witness for AVPlayerWrapperDelegate.AVWrapper(didChangeState:) in conformance AudioPlayer + 23
5    AzRadio                            0x000000010773a120 AVPlayerWrapper._state.didset + 371
6    AzRadio                            0x000000010773a300 AVPlayerWrapper._state.setter + 184
7    AzRadio                            0x000000010773d4d0 AVPlayerWrapper.player(didChangeTimeControlStatus:) + 218
8    AzRadio                            0x000000010773db10 protocol witness for AVPlayerObserverDelegate.player(didChangeTimeControlStatus:) in conformance AVPlayerWrapper + 9
9    AzRadio                            0x000000010770f1b0 AVPlayerObserver.handleTimeControlStatusChange(_:) + 860
10   AzRadio                            0x000000010770e2b0 AVPlayerObserver.observeValue(forKeyPath:of:change:context:) + 693
11   AzRadio                            0x000000010770eaf0 @objc AVPlayerObserver.observeValue(forKeyPath:of:change:context:) + 635
12   Foundation                         0x00000001084056fd NSKeyValueNotifyObserver + 351
13   Foundation                         0x0000000108404f2f NSKeyValueDidChange + 484
14   Foundation                         0x00000001083d581a -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 111
15   AVFoundation                       0x000000010a476f4c -[AVPlayer _didChangeValueForTimeControlStatusAndReason] + 60
16   AVFoundation                       0x000000010a47dd4f -[AVPlayer setAutomaticallyWaitsToMinimizeStalling:] + 362
17   AzRadio                            0x000000010773acd0 AVPlayerWrapper.automaticallyWaitsToMinimizeStalling.setter + 75
18   AzRadio                            0x000000010773d3b0 protocol witness for AVPlayerWrapperProtocol.automaticallyWaitsToMinimizeStalling.setter in conformance AVPlayerWrapper + 30
19   AzRadio                            0x00000001077089e0 AudioPlayer.automaticallyWaitsToMinimizeStalling.setter + 162
20   AzRadio                            0x0000000107721290 RNTrackPlayer.setupPlayer(config:resolve:reject:) + 438
21   AzRadio                            0x0000000107722060 @objc RNTrackPlayer.setupPlayer(config:resolve:reject:) + 335
22   CoreFoundation                     0x000000010b39bbe0 __invoking___ + 140
23   CoreFoundation                     0x000000010b39ba00 -[NSInvocation invoke] + 320
24   CoreFoundation                     0x000000010b3b3920 -[NSInvocation invokeWithTarget:] + 54
25   AzRadio                            0x00000001072618c0 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 2810
26   AzRadio                            0x00000001073097b0 facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&) + 790
27   AzRadio                            0x0000000107309560 facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)::$_0::operator()() const + 127
28   AzRadio                            0x0000000107309540 invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int) + 25
29   libdispatch.dylib                  0x000000010fc3d49a _dispatch_call_block_and_release + 12
30   libdispatch.dylib                  0x000000010fc66054 _dispatch_client_callout + 8
31   libdispatch.dylib                  0x000000010fc44872 _dispatch_queue_serial_drain + 221
32   libdispatch.dylib                  0x000000010fc4522d _dispatch_queue_invoke + 1084
33   libdispatch.dylib                  0x000000010fc458a4 _dispatch_queue_override_invoke + 654
34   libdispatch.dylib                  0x000000010fc47c4a _dispatch_root_queue_drain + 634
35   libdispatch.dylib                  0x000000010fc47b74 _dispatch_worker_thread3 + 123
36   libsystem_pthread.dylib            0x0000000110000bfe _pthread_wqthread + 1387
37   libsystem_pthread.dylib            0x0000000110000bdc start_wqthread + 13

I've applied a patch that @minhtc suggested above (thanks!) and it helped, no more crashes like that or when setting rate.
Unfortunately I'm not familiar with swift enough to understand what that change means, how it fixes the issue and if it does not affect something else. @minhtc could you maybe create a pr to initiate review and further discussion?

I am running into a similar issue, except setRate works fine when TrackPlayer is playing, but when I call setRate and TrackPlayer is paused, the app crashes. I'm using iOS Simulator, and haven't tried in production.

UPDATE: @minhtc's patch resolved the issue for me.

@minhtc can you create a PR with your fix, please?

@Guichaguri Sure, the PR should be created on the Vendor module repo.

The AVPlayerWrapperProtocol type without class bound will acts with the struct level of restriction, change to a class instead of struct should fix this issue.

@Guichaguri: The PR has been merged, I think you could close this issue. Thanks!

Thanks @minhtc

Was this page helpful?
0 / 5 - 0 ratings