Reputation: 951
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
Reputation:
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?
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