56

Is there a way to access the URL from an AVPlayer object that has been initialized with a URL, as in:

NSURL *url = [NSURL URLWithString: @"http://www.example.org/audio"];
self.player = [AVPlayer playerWithURL: url];
Claudijo
  • 1,321
  • 1
  • 10
  • 15
  • The `AVPlayer` [docs](https://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVPlayer_Class/Reference/Reference.html) don't appear to give a way to grab the URL. You can try to see if it responds to `valueForKey:` with various permutations of `@"URL"`, but I doubt it will be exposed. – coneybeare Dec 26 '12 at 03:46

4 Answers4

102

An AVPlayer plays an AVPlayerItem. AVPlayerItems are backed by objects of the class AVAsset. When you use the playerWithURL: method of AVPlayer it automatically creates the AVPlayerItem backed by an asset that is a subclass of AVAsset named AVURLAsset. AVURLAsset has a URL property.

So, yes, in the case you provided you can get the NSURL of the currently playing item fairly easily. Here's an example function of how to do this:

-(NSURL *)urlOfCurrentlyPlayingInPlayer:(AVPlayer *)player{
    // get current asset
    AVAsset *currentPlayerAsset = player.currentItem.asset;
    // make sure the current asset is an AVURLAsset
    if (![currentPlayerAsset isKindOfClass:AVURLAsset.class]) return nil;
    // return the NSURL
    return [(AVURLAsset *)currentPlayerAsset URL];
}

Not a swift expert, but it seems it can be done in swift more briefly.

func urlOfCurrentlyPlayingInPlayer(player : AVPlayer) -> URL? {
    return ((player.currentItem?.asset) as? AVURLAsset)?.url
}
NJones
  • 27,139
  • 8
  • 70
  • 88
  • May want to check that `player.currentItem` is not `nil` also in the case of an empty init – jocull Jun 19 '13 at 16:17
  • 2
    @jocull You certainly could check for `nil` so as to not waste time sending messages to `nil`. But the beauty of objective-c is that this code is completely safe. In objective-c sending a message to `nil` doesn't crash and simply returns a 'nil` or `0` or `NO`(depending on return type, they're all the same anyway). So the only check required is the the if statement I included to make sure the asset is a url-asset because if it wasn't then it wouldn't respond to the `-URL` selector, and would crash. – NJones Sep 22 '13 at 15:22
  • I forget what was happening when I wrote this, but if `player.currentItem` is nil then trying to use `player.currentItem.asset` will crash. That's the only thing to really watch out for. – jocull Sep 22 '13 at 20:05
17

Oneliner swift 4.1

let url: URL? = (player?.currentItem?.asset as? AVURLAsset)?.url
Sentry.co
  • 5,355
  • 43
  • 38
13

Solution for Swift 3

func getVideoUrl() -> URL? {
    let asset = self.player?.currentItem?.asset
    if asset == nil {
        return nil
    }
    if let urlAsset = asset as? AVURLAsset {
        return urlAsset.url
    }
    return nil
}
Eric Conner
  • 10,422
  • 6
  • 51
  • 67
5

AVPlayerItem extension base on @eonist answer.

extension AVPlayerItem {
    var url: URL? {
        return (asset as? AVURLAsset)?.url
    }
}