1

I'm having this issue which another user on StackOverflow had (this is the post):

I'm doing the following:

  • Create a new AVURLAsset with a given URL. That URL points to a video on a remote web server.
  • Attempt to load the tracks property by calling loadValuesAsynchronously(forKeys:completionHandler:)
  • The initial request fails, because no internet connection exists
  • I notice that the request failed by calling statusOfValue(forKey:error:)
  • I then wait for the connection to re-appear (using some reachability code). As soon as it does, I call loadValuesAsynchronously(forKeys:completionHandler:)again.

Here's where the problems begin. I would imagine that the AVURLAsset goes ahead and attempts to reload the tracks property since it failed previously. However, this does not seem to happen. statusOfValue(forKey:error:) will still return AVKeyValueStatusFailed, although a working internet connection is available and the video is playable.

Is there a way to reset the state for this given property and to attempt another load? Is there another way to work around this? Or is the only option to recreate the AVURLAsset?

Thanks!

JEL
  • 1,540
  • 4
  • 23
  • 51
  • Possible duplicate of [Reloading keys in AVAsset when status is AVKeyValueStatusFailed](http://stackoverflow.com/questions/21139806/reloading-keys-in-avasset-when-status-is-avkeyvaluestatusfailed) –  Mar 06 '17 at 21:54
  • Why would you imagine that your AVURLAsset would check for your internet connection to pop back up and do work for you automatically? –  Mar 06 '17 at 21:55
  • @Sneak Srry I don't know what to do here - I thought maybe that `AVFoundation` had a method that allowed you to reset the keys on the `AVURLAsset` so that when `loadValuesAsynchronously(forKeys:completionHandler:)` is called a second time, it would start from scratch – JEL Mar 06 '17 at 21:57
  • I don't expect "AVURLAsset would check for your internet connection" to do this, please read my question – JEL Mar 06 '17 at 21:59
  • Check matts answer here: http://stackoverflow.com/questions/23701057/how-does-avplayer-avplayeritem-inform-my-application-about-unreachable-network you should do this with KVO observers as he mentions there. Look it up there are plenty of sample codes from Apple etc how to do this. If KVO observers doesnt help you or work in your case. You can manually observe when internet connections change and fire the reload of the asset yourself: http://stackoverflow.com/questions/27310465/detecting-network-connectivity-changes-using-reachability-nsnotification-and-ne –  Mar 06 '17 at 22:01
  • @Sneak I know how to check for internet connection and am using Apple's sample code which also has this issue here: https://developer.apple.com/library/content/samplecode/AVFoundationSimplePlayer-iOS/Introduction/Intro.html#//apple_ref/doc/uid/TP40016103 ------- the issue is how to have `AVURLAsset` reset its state for the "keys" once it failed the first time – JEL Mar 06 '17 at 22:05
  • Only way I see it is creating a new `AVURLAsset` but then you have to get into removing and adding new observers with KVO – JEL Mar 06 '17 at 22:05
  • Did you try [asset cancelLoading]? If that doesnt work neither and you are having issues with the asset (I havn't run into it myself so I can't say much more) you should create a new asset. It shouldn't be any performance bottleneck or anything doing so. :) BTW, that Apple sample code didn't have any buffer KVO as matt mentioned in the link I provided you with (or maybe I missed out on seeing it in the sample code you linked). KVO for playable etc and buffers are different things. –  Mar 06 '17 at 22:07
  • @Sneak Sure, thanks for looking at the sample code. I still don't see how with Matt's answer once the `AVURLAsset`'s key for `isPlayable` is equalled to `failed`, as is checkable with `newAsset.statusOfValue(forKey: key, error: &error) == .failed` ----- the `AVURLAsset` never returns back to it's original state (whatever that is) when calling `loadValuesAsynchronously(forKeys:completionHandler:)` to retry the operation again (there also seems to be no method like `reset()` which would do this) – JEL Mar 06 '17 at 22:22
  • I think the only way for you to handle the fail is to handle it yourself, and therefore why it actually returns the fail and error for you inside the block. If you never reach an actual playable asset , then the buffer KVO wont help neither (that will help you however when connection gets lost momentarily) You should handle the UI to notify the user that it has failed and maybe provide a "reload" button so that they can reload it when they receive connection again. Or alternatively use notifications and reachability as I mentioned earlier. maybe a combination of both. –  Mar 06 '17 at 22:31
  • @Sneak I see, if I understand correctly then, when a user pressed "reload", then a new `AVURLAsset` would be created? (this means removing/adding new observers for KVO on this new asset as well) – JEL Mar 06 '17 at 22:33
  • Yes, provided that [asset cancelLoading] call before trying to run the block method again wouldnt work, your option would be to recreate the asset. I can not try this tho you have to try and see which option works for you. GL –  Mar 06 '17 at 22:35
  • @Sneak Ok thanks! Btw I call `asset.cancelLoading()` inside of the `failed` block – JEL Mar 06 '17 at 22:37
  • Yes , if that doesnt work go with the other option and recreate a clean new one. –  Mar 06 '17 at 22:40

0 Answers0