5

Basically I am trying to play an m3u8 (HLS Live Stream) using AVPlayer in Cocoa Swift. I'm relatively new to the language, so basically grabbed some example code for playing local video files and tried modifying it to play a live stream... But get this instead:

https://i.stack.imgur.com/bU9GM.png

This is what I got so far (commented lines are to play local file, which does work):

import Cocoa
import AVKit
import Foundation
import AVFoundation

class ViewController: NSViewController {

    @IBOutlet weak var playerView: AVPlayerView!

    var videoPlayer:AVPlayer!

    override func viewDidLoad() {
        super.viewDidLoad()

        //let path = NSBundle.mainBundle().pathForResource("sample", ofType: "mov")
        //var fileURL = NSURL(fileURLWithPath: path!)
        let fileURL = NSURL(string: "http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8")
        let avAsset = AVURLAsset(URL: fileURL!, options: nil)

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

    override var representedObject: AnyObject? {
        didSet {
            // Update the view, if already loaded.
        }
    }
}

Any help on how to make this code work, or lead me in the right direction is much appreciated!

user3063455
  • 123
  • 1
  • 11

1 Answers1

4

I tried to paste your code into a new OS X project (or macOS as we must start calling it now :))

When I launched the project I got this error in the console:

2016-06-21 09:09:27.860 Videoplayer[2494:169209] 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.

I don't know if you have the console enabled, it is the bottom part of your screen, provided you have the debug area enabled.

If you haven't got the debug area enabled, then you enable it in the top of Xcode

enable debug area

And then you need to make sure that you show the console as well, which is done in the bottom part of Xcode:

enable console

OK, now you can see the error, then how to fix it :)

This message basically tells you that Apple has blocked access to HTTP. This was introduced in OS X 10.11 and iOS 9, but can be disabled.

As it says in the console:

Temporary exceptions can be configured via your app's Info.plist file.

This means that you should add a new key to your info.plist file.

You can add it as "raw" plist data, which looks like this:

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

Or you can add it in the plist editor, where it looks like this:

editing plist

This question and the great answers describes the process better that I can

If I do this, I am able to get your code running and can watch the live stream, so I hope this helps you too.

Community
  • 1
  • 1
pbodsk
  • 6,787
  • 3
  • 21
  • 51
  • Wow thank you so much! Should have realized that was the problem – user3063455 Jun 21 '16 at 17:51
  • @pbodsk - I get this error on code statement let avAsset = AVURLAsset(URL: my_url!, options: nil) - 'NSURL' is not implicitly convertible to 'URL'; did you mean to use 'as' to explicitly convert? Any ideas as to why you guys don't get that error but I do? – Neal Davis Nov 11 '17 at 15:22
  • @NealDavis You probably get that because this answer and question is about a year and a half old and was written before "the grand Swift rewrite" that happened with Swift 3 in the summer/autumn of 2016. Part of that was that `NSURL` was changed to `URL` as the type to use for urls. When this question was asked you had to pass an occurrence of a `NSURL to the `AVURLAsset` `init` method and now you pass an occurrence of a `URL`. So I'm guessing that you're creating a `NSURL` and handing that to your `AVURLAsset` where it expects "just" a `URL` now. So try changing the type of `my_url` to `URL` – pbodsk Nov 11 '17 at 15:32
  • If I put the exact code in my project: `let fileURL = URL(string: "http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8") let avAsset = AVURLAsset(url: fileURL!, options: nil) let playerItem = AVPlayerItem(asset: avAsset) videoPlayer = AVPlayer(playerItem: playerItem) let playerView = self.playerView playerView?.player = videoPlayer videoPlayer.play()` I have to add line: `let playerView = self.playerView` or I get an nil object exception on `playerView.player = videoPlayer` line? Any ideas? – Neal Davis Nov 11 '17 at 16:10
  • @pbodsk - I changed per your comment but see my last comment above - with exact same code as above I get a nil object exception at `playerView.player = videoPlayer` I don't understand why? – Neal Davis Nov 11 '17 at 16:14
  • @pbodsk - here is error with exact same code: `playerView.player = videoPlayer` Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value – Neal Davis Nov 11 '17 at 16:17
  • @pbodsk - I hear the sound track to the video but no video showing in my window? Any ideas why? Maybe something to do with adding the line per above: `let playerView = self.playerView`? But I have to add it or I get exception as mentioned above – Neal Davis Nov 11 '17 at 16:31
  • @NealDavis, I added an answer to [your question](https://stackoverflow.com/a/47241017/4063602) – pbodsk Nov 11 '17 at 17:52