Dimitri T
Dimitri T

Reputation: 951

how to play movie in AVPlayerViewController using Watch Connectivity in swift 2.2?

How can I get this video to play in AVPlayerViewController, and change the volume, triggered from Watch Connectivity commands sent from my Watch (with swift 2.2). When I click start/stop on my watch I get no response. There are no errors in my console or crashes.

 import UIKit
 import AVKit
import AVFoundation
import WatchConnectivity

@UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate {

  var window: UIWindow?

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {

    var replyValues = Dictionary<String, AnyObject>()

    let viewController = self.window!.rootViewController
        as! AVPlayerViewController
    var player = AVPlayer()
    let url = "https://example.site/sites/default/files/videos/original/video1bunny_0.mp4"
    let playerItem = AVPlayerItem( URL:NSURL( string:url )! )
    player = AVPlayer(playerItem:playerItem)
    player.rate = 1.0;

    switch message["command"] as! String {
    case "start" :
        player.play()
        replyValues["status"] = "Playing"
    case "stop" :
        player.pause()
        replyValues["status"] = "Stopped"
    case "volume" :
        let level = message["level"] as! Float
        //player.adjustVolume(level)
        replyValues["status"] = "Vol = \(level)"
    default:
        break
    }
    replyHandler(replyValues)
}

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {

    if (WCSession.isSupported()) {
        let session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()

        if session.paired != true {
            print("Apple Watch is not paired")
        }

        if session.watchAppInstalled != true {
            print("WatchKit app is not installed")
        }
    } else {
        print("WatchConnectivity is not supported on this device")
    }

    return true

} }

I was trying to adapt this code (in my ViewController.swift) which was successfully playing an mp3 in the Audio Player. (I have set up all the IBActions etc on the watch correctly).

    class ViewController: UIViewController {

var audioSession: AVAudioSession = AVAudioSession.sharedInstance()
var audioPlayer: AVAudioPlayer?

@IBOutlet weak var volumeControl: UISlider!

override func viewDidLoad() {
    super.viewDidLoad()

    var url: NSURL?

    do {
        try audioSession.setCategory(AVAudioSessionCategoryPlayback)
        url = NSURL.fileURLWithPath(
            NSBundle.mainBundle().pathForResource("vivaldi",
                ofType: "mp3")!)
    } catch {
        print("AudioSession error")
    }

    do {
        try audioPlayer = AVAudioPlayer(contentsOfURL: url!,
                            fileTypeHint: nil)
        audioPlayer?.prepareToPlay()
        audioPlayer?.volume = 0.1
    } catch let error as NSError {
        print("Error: \(error.description)")
    }
}

Upvotes: 0

Views: 976

Answers (1)

user4151918
user4151918

Reputation:

The working example

In the second example which successfully plays the MP3, you have setup a view controller property for the AVPlayer, and assigned the new audio player to that property. The view controller retains the audio player, and it plays even after the viewDidLoad code exits:

class ViewController: UIViewController {
    var audioPlayer: AVAudioPlayer?

The failing example

However in the first example which you're trying to get working, you're using a local variable which goes out of scope as soon as that block of code exits:

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    var player = AVPlayer()

The audio player has been released, and no longer exists.

You should retain that instance of the audio player, as you did in the working example.

Upvotes: 2

Related Questions