Neal Davis
Neal Davis

Reputation: 668

AVPlayer won't let me access URL

I am Attempting very simple Xcode OS X program with swift 4.0 - this program builds and runs but I'm getting errors accessing the URL video file. Probably related to privilege or security setting somewhere but can't figure out where. Here is my program under class ViewController: NSViewController:

@IBOutlet var playerView: AVPlayerView!
//var url: URL!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    // guard let url = URL(string: "https://devimages.apple.com.edgekey.net/samplecode/avfoundationMedia/AVF oundationQueuePlayer_HLS2/master.m3u8")
    //    else {
    //        return
    //    }

   let url1 = URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")


    let player = AVPlayer(url: url1!)
    // Create a new AVPlayer and associate it with the player view

    let playerView = self.playerView
    playerView?.player = player
    playerView?.player!.play();
}

Also I have modified the info.plist file with the following:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict/>
</dict>

I get the following runtime errors trying to access either of the URLs above why?

2017-11-05 10:12:21.757333-0800 AVPlayer[54381:5617593] startLogging: logging starts... 2017-11-05 10:12:21.758024-0800 AVPlayer[54381:5617612] setMessageLoggingBlock: called 2017-11-05 10:12:21.758520-0800 AVPlayer[54381:5617612] initWithSessionInfo: XPC connection interrupted 2017-11-05 10:12:21.758842-0800 AVPlayer[54381:5617612] startConfigurationWithCompletionHandler: Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.rtcreportingd" UserInfo={NSDebugDescription=connection to service named com.apple.rtcreportingd} 2017-11-05 10:12:21.759003-0800 AVPlayer[54381:5617612] startConfigurationWithCompletionHandler: Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.rtcreportingd" UserInfo={NSDebugDescription=connection to service named com.apple.rtcreportingd} 2017-11-05 10:12:21.925221-0800 AVPlayer[54381:5617654] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

Upvotes: 3

Views: 5325

Answers (2)

pbodsk
pbodsk

Reputation: 6876

I found your question after you commented on a question I had answered previously, so lets continue here :)

I can get your code working by combining my original answer to that question with the answer provided by @callam above so...give him the credit for the correct answer :)

To summarize, you need to:

  1. Add a AVPlayerView to your Storyboard and connect it to your ViewController
  2. Setup your ViewController
  3. Manage App Transport Security and the outgoing connection.

In greater detail

1. Add a AVPlayerView to your Storyboard and connect it to your ViewController

Drag a AVKit Player View to your view in the storyboard

Add AVKit player view

In your ViewController class, create an outlet for the view:

 @IBOutlet weak var playerView: AVPlayerView!

And connect it.

2. Setup your ViewController

Here is my code:

import Cocoa
import AVKit

class ViewController: NSViewController {

    @IBOutlet weak var playerView: AVPlayerView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let fileURL = URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
        let avAsset = AVURLAsset(url: fileURL!, options: nil)

        let playerItem = AVPlayerItem(asset: avAsset)
        let videoPlayer = AVPlayer(playerItem: playerItem)
        playerView.player = videoPlayer
        videoPlayer.play()
    }
}

Seems familiar no :)

Notice I create the videoPlayer right here, no need to for me to use the let playerView = self.playerView you mention in your comments.

If you just do these two steps, you end up with a player view that cannot play video and errors in your console. So you need to add the final piece to the puzzle, kindly provided by @callam above.

3. Manage App Transport Security and the outgoing connection.

First, if you cannot use a HTTPS connection you must allow HTTP connections in your info.plist file.

Here is my .plist file in its entirety

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSMinimumSystemVersion</key>
    <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
    <key>NSHumanReadableCopyright</key>
    <string>Copyright © 2017 :) </string>
    <key>NSMainStoryboardFile</key>
    <string>Main</string>
    <key>NSPrincipalClass</key>
    <string>NSApplication</string>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
</dict>
</plist>

The important part being the NSAppTransportSecurity part

And then finally, you must enable Outgoing Connections (Client) under Capabilities of your project

enable Outgoing Connections

If I do that, I end up with this:

The final result

But notice though, that I still see errors in the console.

Hope you are able to get to the same result following these steps :)

Upvotes: 9

Callam
Callam

Reputation: 11539

Even if you enable arbitrary loads, attempts to connect using insecure HTTP fail.

Change the protocol in your URL to https:// or add the domain to NSExceptionDomains.

let url1 = URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")

https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35

I believe the XPC error can be fixed by selecting Outgoing Connections in your App Capabilities

App Sandbox

https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html

Upvotes: 4

Related Questions