Rolamix / cordova-plugin-playlist

🎶 A Cordova plugin for Android and iOS with native support for audio playlists, background support, and lock screen controls 🎶
MIT License
32 stars 32 forks source link

Prevent INFINITY value being written to JSON #5

Closed robinbanbury closed 5 years ago

robinbanbury commented 5 years ago

Prevent the audio track playback percentage from being set to INFINITY if the track position appears to be INFINITY. This can happen before the track starts playing.

Description

There already exists code to set the 'track position' metadata to 0 if the track position is INFINITY or not a number. The key is to do that before the playback percentage is calculated. The playback percentage is ultimately serialised to JSON, and if that value is INFINITY, the plugin will crash.

Related Issue

4

Motivation and Context

Streaming tracks from SoundCloud on iOS can produce a playback position of INFINITY before the track starts playing. This can cause the entire app to crash.

How Has This Been Tested?

Before and after test on a live device with multiple SoundCloud tracks

Screenshots (if appropriate):

None appropriate, but logs before:

2018-07-05 00:02:20.079333+0100 ionic2-soundcloud[1150:316830] Apache Cordova native platform version 4.5.3 is starting.
2018-07-05 00:02:20.080033+0100 ionic2-soundcloud[1150:316830] Multi-tasking -> Device: YES, App: YES
2018-07-05 00:02:20.091739+0100 ionic2-soundcloud[1150:316830] CDVWKWebViewEngine: trying to inject XHR polyfill
2018-07-05 00:02:20.121938+0100 ionic2-soundcloud[1150:316830] CDVWKWebViewEngine will reload WKWebView if required on resume
2018-07-05 00:02:20.122043+0100 ionic2-soundcloud[1150:316830] Using Ionic WKWebView
2018-07-05 00:02:20.122471+0100 ionic2-soundcloud[1150:316830] [CDVTimer][console] 0.056982ms
2018-07-05 00:02:20.122765+0100 ionic2-soundcloud[1150:316830] [CDVTimer][handleopenurl] 0.187039ms
2018-07-05 00:02:20.124362+0100 ionic2-soundcloud[1150:316830] [CDVTimer][intentandnavigationfilter] 1.539946ms
2018-07-05 00:02:20.124525+0100 ionic2-soundcloud[1150:316830] [CDVTimer][gesturehandler] 0.092983ms
2018-07-05 00:02:20.125317+0100 ionic2-soundcloud[1150:316830] [CDVTimer][keyboard] 0.633001ms
2018-07-05 00:02:20.148291+0100 ionic2-soundcloud[1150:316830] [CDVTimer][splashscreen] 22.867918ms
2018-07-05 00:02:20.237981+0100 ionic2-soundcloud[1150:316830] [CDVTimer][rmxaudioplayer] 89.603066ms
2018-07-05 00:02:20.238063+0100 ionic2-soundcloud[1150:316830] [CDVTimer][TotalPluginStartup] 115.698099ms
2018-07-05 00:02:20.441316+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer, queuePlayerCleared
2018-07-05 00:02:20.441378+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer, removeAllTracks, ==> RMXSTATUS_PLAYLIST_CLEARED
2018-07-05 00:02:21.576286+0100 ionic2-soundcloud[1150:316830] Ionic Native: deviceready event fired after 683 ms
2018-07-05 00:02:21.576442+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.execute=initialize
2018-07-05 00:02:21.576619+0100 ionic2-soundcloud[1150:316830] WARN: Native: tried calling StatusBar.styleDefault, but the StatusBar plugin is not installed.
2018-07-05 00:02:21.576702+0100 ionic2-soundcloud[1150:316830] WARN: Install the StatusBar plugin: 'ionic cordova plugin add cordova-plugin-statusbar'
2018-07-05 00:02:21.588803+0100 ionic2-soundcloud[1150:316830] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:02:21.589138+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.execute=setOptions, {
    resetStreamOnPause = 1;
    verbose = 1;
}
2018-07-05 00:02:21.589606+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.execute=setOptions, {
    resetStreamOnPause = 1;
    verbose = 1;
}
2018-07-05 00:02:21.596359+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.execute=setPlaybackVolume, 0.5
2018-07-05 00:02:21.608418+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.execute=setPlaylistItems, {
}, (
        {
        album = "Test Files";
        albumArt = "https://i1.sndcdn.com/artworks-000192365267-77o515-large.jpg";
        artist = "Mount Nakara";
        assetUrl = "https://api.soundcloud.com/tracks/274436003/stream?client_id=XXXXXXXXXXXXXXXXXXXX";
        isStream = 1;
        title = "Test 1";
        trackId = 12345;
    }
)
2018-07-05 00:02:21.619147+0100 ionic2-soundcloud[1150:316848] CredStore - performQuery - Error copying matching creds.  Error=-25300, query={
    class = inet;
    "m_Limit" = "m_LimitAll";
    "r_Attributes" = 1;
    sync = syna;
}
2018-07-05 00:02:21.622299+0100 ionic2-soundcloud[1150:316848] Queue changed current item to: {
    album = "Test Files";
    albumArt = "https://i1.sndcdn.com/artworks-000192365267-77o515-large.jpg";
    artist = "Mount Nakara";
    assetUrl = "https://api.soundcloud.com/tracks/274436003/stream?client_id=XXXXXXXXXXXXXXXXXXXX";
    isStream = 1;
    title = "Test 1";
    trackId = 12345;
}
2018-07-05 00:02:21.622364+0100 ionic2-soundcloud[1150:316848] New item ID: 12345
2018-07-05 00:02:21.622474+0100 ionic2-soundcloud[1150:316848] Queue is at end: NO
2018-07-05 00:02:21.629015+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.onStatus: Track Added(110) [12345]:  [object Object]
2018-07-05 00:02:21.633461+0100 ionic2-soundcloud[1150:316830] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:02:21.633907+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.onStatus: Loading(10) [12345]:
2018-07-05 00:02:21.634009+0100 ionic2-soundcloud[1150:316830] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:02:21.651973+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.onStatus: Track Changed(100) [12345]:  [object Object]
2018-07-05 00:02:21.652334+0100 ionic2-soundcloud[1150:316830] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:02:21.672392+0100 ionic2-soundcloud[1150:316830] RmxAudioPlayer.execute=play
2018-07-05 00:02:21.679928+0100 ionic2-soundcloud[1150:316830] Playback rate changed: 1.000000, is playing: 1
2018-07-05 00:02:21.680610+0100 ionic2-soundcloud[1150:316830] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid number value (infinite) in JSON write'
*** First throw call stack:
(0x181e8ed8c 0x1810485ec 0x181e8ec6c 0x182965c94 0x1829647d4 0x182966b40 0x181db2564 0x18296611c 0x182966b40 0x181d5d3a0 0x18296611c 0x182966b40 0x181d5d3a0 0x18296611c 0x182966e0c 0x181e27f38 0x182966538 0x182964584 0x1829655d4 0x104cff500 0x104d0a0c0 0x104cfef44 0x104cf4780 0x104cef144 0x18281d2f8 0x18281ce30 0x1828a1ca0 0x1878e960c 0x1878f0404 0x1878f0504 0x104cecb80 0x104ce9e74 0x104d08e7c 0x104cc0c80 0x104cc0ae4 0x104cc2760 0x191b92d14 0x191b2fb54 0x191b31cc4 0x191899634 0x191ad86d4 0x19185c618 0x19185f020 0x1894c4148 0x1894c4408 0x181e37404 0x181e36c2c 0x181e3479c 0x181d54da8 0x183d39020 0x18bd71758 0x104cb72d8 0x1817e5fc0)
libc++abi.dylib: terminating with uncaught exception of type NSException

Logs after:

2018-07-05 00:13:58.780387+0100 ionic2-soundcloud[1157:320489] Apache Cordova native platform version 4.5.3 is starting.
2018-07-05 00:13:58.781015+0100 ionic2-soundcloud[1157:320489] Multi-tasking -> Device: YES, App: YES
2018-07-05 00:13:58.790416+0100 ionic2-soundcloud[1157:320489] CDVWKWebViewEngine: trying to inject XHR polyfill
2018-07-05 00:13:58.822192+0100 ionic2-soundcloud[1157:320489] CDVWKWebViewEngine will reload WKWebView if required on resume
2018-07-05 00:13:58.822300+0100 ionic2-soundcloud[1157:320489] Using Ionic WKWebView
2018-07-05 00:13:58.822749+0100 ionic2-soundcloud[1157:320489] [CDVTimer][console] 0.092030ms
2018-07-05 00:13:58.822897+0100 ionic2-soundcloud[1157:320489] [CDVTimer][handleopenurl] 0.061035ms
2018-07-05 00:13:58.824361+0100 ionic2-soundcloud[1157:320489] [CDVTimer][intentandnavigationfilter] 1.424909ms
2018-07-05 00:13:58.824470+0100 ionic2-soundcloud[1157:320489] [CDVTimer][gesturehandler] 0.050902ms
2018-07-05 00:13:58.825002+0100 ionic2-soundcloud[1157:320489] [CDVTimer][keyboard] 0.427961ms
2018-07-05 00:13:58.847863+0100 ionic2-soundcloud[1157:320489] [CDVTimer][splashscreen] 22.774100ms
2018-07-05 00:13:58.933852+0100 ionic2-soundcloud[1157:320489] [CDVTimer][rmxaudioplayer] 85.887074ms
2018-07-05 00:13:58.933923+0100 ionic2-soundcloud[1157:320489] [CDVTimer][TotalPluginStartup] 111.312985ms
2018-07-05 00:13:59.096510+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer, queuePlayerCleared
2018-07-05 00:13:59.096670+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer, removeAllTracks, ==> RMXSTATUS_PLAYLIST_CLEARED
2018-07-05 00:14:00.219999+0100 ionic2-soundcloud[1157:320489] Ionic Native: deviceready event fired after 653 ms
2018-07-05 00:14:00.220194+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.execute=initialize
2018-07-05 00:14:00.226403+0100 ionic2-soundcloud[1157:320489] WARN: Native: tried calling StatusBar.styleDefault, but the StatusBar plugin is not installed.
2018-07-05 00:14:00.226597+0100 ionic2-soundcloud[1157:320489] WARN: Install the StatusBar plugin: 'ionic cordova plugin add cordova-plugin-statusbar'
2018-07-05 00:14:00.242886+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.243103+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.execute=setOptions, {
    resetStreamOnPause = 1;
    verbose = 1;
}
2018-07-05 00:14:00.246301+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.execute=setOptions, {
    resetStreamOnPause = 1;
    verbose = 1;
}
2018-07-05 00:14:00.246475+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.execute=setPlaybackVolume, 0.5
2018-07-05 00:14:00.261441+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.execute=setPlaylistItems, {
}, (
        {
        album = "Test Files";
        albumArt = "https://i1.sndcdn.com/artworks-000192365267-77o515-large.jpg";
        artist = "Mount Nakara";
        assetUrl = "https://api.soundcloud.com/tracks/274436003/stream?client_id=XXXXXXXXXXXXXXXXXXXX";
        isStream = 1;
        title = "Test 1";
        trackId = 12345;
    }
)
2018-07-05 00:14:00.270361+0100 ionic2-soundcloud[1157:320604] CredStore - performQuery - Error copying matching creds.  Error=-25300, query={
    class = inet;
    "m_Limit" = "m_LimitAll";
    "r_Attributes" = 1;
    sync = syna;
}
2018-07-05 00:14:00.274827+0100 ionic2-soundcloud[1157:320604] Queue changed current item to: {
    album = "Test Files";
    albumArt = "https://i1.sndcdn.com/artworks-000192365267-77o515-large.jpg";
    artist = "Mount Nakara";
    assetUrl = "https://api.soundcloud.com/tracks/274436003/stream?client_id=XXXXXXXXXXXXXXXXXXXX";
    isStream = 1;
    title = "Test 1";
    trackId = 12345;
}
2018-07-05 00:14:00.288346+0100 ionic2-soundcloud[1157:320604] New item ID: 12345
2018-07-05 00:14:00.288708+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Track Added(110) [12345]:  [object Object]
2018-07-05 00:14:00.291768+0100 ionic2-soundcloud[1157:320604] Queue is at end: NO
2018-07-05 00:14:00.292212+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.297836+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Loading(10) [12345]:
2018-07-05 00:14:00.298951+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.336367+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Track Changed(100) [12345]:  [object Object]
2018-07-05 00:14:00.336989+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.337332+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.execute=play
2018-07-05 00:14:00.339505+0100 ionic2-soundcloud[1157:320489] Playback rate changed: 1.000000, is playing: 1
2018-07-05 00:14:00.413058+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Playing(30) [12345]:  [object Object]
2018-07-05 00:14:00.413502+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.774108+0100 ionic2-soundcloud[1157:320489] The track duration was changed [12345]: 275.539581
2018-07-05 00:14:00.785376+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Duration Changed(55) [12345]:  [object Object]
2018-07-05 00:14:00.785596+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.803079+0100 ionic2-soundcloud[1157:320489] playbackDuration ==> 0
2018-07-05 00:14:00.803142+0100 ionic2-soundcloud[1157:320489] MPNowPlayingInfoPropertyElapsedPlaybackTime ==> 0
2018-07-05 00:14:00.803190+0100 ionic2-soundcloud[1157:320489] title ==> Test 1
2018-07-05 00:14:00.803220+0100 ionic2-soundcloud[1157:320489] MPNowPlayingInfoPropertyPlaybackRate ==> 1
2018-07-05 00:14:00.803245+0100 ionic2-soundcloud[1157:320489] albumTitle ==> Test Files
2018-07-05 00:14:00.803270+0100 ionic2-soundcloud[1157:320489] artist ==> Mount Nakara
2018-07-05 00:14:00.810929+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Playback Position Changed(40) [12345]:  [object Object]
2018-07-05 00:14:00.811075+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.842048+0100 ionic2-soundcloud[1157:320489]  . . . 0.00000 -> 0.99265 (0.4 %) [12345]
2018-07-05 00:14:00.842665+0100 ionic2-soundcloud[1157:320489] PlayerItem status changed to AVPlayerItemStatusReadyToPlay [12345]
2018-07-05 00:14:00.934850+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Buffering(25) [12345]:  [object Object]
2018-07-05 00:14:00.937765+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:00.938936+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: CanPlay(11) [12345]:  [object Object]
2018-07-05 00:14:00.939450+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:01.194536+0100 ionic2-soundcloud[1157:320489] playbackDuration ==> 275.5396
2018-07-05 00:14:01.194630+0100 ionic2-soundcloud[1157:320489] MPNowPlayingInfoPropertyElapsedPlaybackTime ==> 0
2018-07-05 00:14:01.194697+0100 ionic2-soundcloud[1157:320489] title ==> Test 1
2018-07-05 00:14:01.194738+0100 ionic2-soundcloud[1157:320489] MPNowPlayingInfoPropertyPlaybackRate ==> 1
2018-07-05 00:14:01.194775+0100 ionic2-soundcloud[1157:320489] albumTitle ==> Test Files
2018-07-05 00:14:01.194811+0100 ionic2-soundcloud[1157:320489] artist ==> Mount Nakara
2018-07-05 00:14:01.197078+0100 ionic2-soundcloud[1157:320489] playbackDuration ==> 275.5396
2018-07-05 00:14:01.197380+0100 ionic2-soundcloud[1157:320489] MPNowPlayingInfoPropertyElapsedPlaybackTime ==> -0.02723444
2018-07-05 00:14:01.197501+0100 ionic2-soundcloud[1157:320489] title ==> Test 1
2018-07-05 00:14:01.197577+0100 ionic2-soundcloud[1157:320489] MPNowPlayingInfoPropertyPlaybackRate ==> 1
2018-07-05 00:14:01.197645+0100 ionic2-soundcloud[1157:320489] albumTitle ==> Test Files
2018-07-05 00:14:01.197803+0100 ionic2-soundcloud[1157:320489] artist ==> Mount Nakara
2018-07-05 00:14:01.207772+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Playback Position Changed(40) [12345]:  [object Object]
2018-07-05 00:14:01.207889+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:01.207967+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Playback Position Changed(40) [12345]:  [object Object]
2018-07-05 00:14:01.208039+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:01.491819+0100 ionic2-soundcloud[1157:320489]  . . . 0.00000 -> 132.04898 (47.9 %) [12345]
2018-07-05 00:14:01.496017+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Buffering(25) [12345]:  [object Object]
2018-07-05 00:14:01.496358+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:02.036906+0100 ionic2-soundcloud[1157:320489]  . . . 0.00000 -> 275.53958 (100.0 %) [12345]
2018-07-05 00:14:02.041018+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Buffering(25) [12345]:  [object Object]
2018-07-05 00:14:02.041266+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:02.041753+0100 ionic2-soundcloud[1157:320489] RmxAudioPlayer.onStatus: Loaded(15) [12345]:  [object Object]
2018-07-05 00:14:02.042035+0100 ionic2-soundcloud[1157:320489] YourService: Got RmxAudioPlayer onStatus:  [object Object]
2018-07-05 00:14:02.223457+0100 ionic2-soundcloud[1157:320489] playbackDuration ==> 275.5396
2018-07-05 00:14:02.223796+0100 ionic2-soundcloud[1157:320489] MPNowPlayingInfoPropertyElapsedPlaybackTime ==> -0.02421281
...

Types of changes

Checklist:

robinbanbury commented 5 years ago

@codinronan do you have some time to look at this PR? Hopefully the fix is quite straightforward and self-explanatory

codinronan commented 5 years ago

Nice! Thank you for finding these, this one I was trying to track down. Nice catch