I have a video which opens in an MPMoviePlayerController in my app. It all works great except for the Done button which should close the player. The first time that the video is played the Done button works great. But if you pause it when you are watching it, then hit Done the second time you try to play the video, the Done button doesn't work. I have made a screen recording here to make it a bit simpler to understand:
http://1drv.ms/1Jcdodc
Can anyone help?
This is my code that I am using:
import UIKit
import MediaPlayer
class MainContent: UIViewController {
//Movie Player variables
var movieViewController : MPMoviePlayerViewController?
var movieplayer : MPMoviePlayerController!
override func viewDidLoad() {
super.viewDidLoad()
//Video Player setup
NSNotificationCenter.defaultCenter().addObserver(self, selector: "doneButtonClick:", name: MPMoviePlayerPlaybackDidFinishNotification, object: nil)
var url = NSURL(string: "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v")!
movieViewController = MPMoviePlayerViewController(contentURL: url)
}
func doneButtonClick(sender:NSNotification?){
let value = UIInterfaceOrientation.Portrait.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
}
//when watch button is pressed, present the movie player
#IBAction func watchPressed(sender: AnyObject)
{self.presentMoviePlayerViewControllerAnimated(movieViewController)}
}
To fix this issue, I added the myMoviePlayerViewController.moviePlayer.stop() to the 'doneButtonClick' function. I then added the myMoviePlayerViewController.moviePlayer.play() again to the
#IBAction func watchPressed(sender: AnyObject)
{self.presentMoviePlayerViewControllerAnimated(movieViewController)}
}
So all in all a simple fix! Code is below:
import UIKit
import MediaPlayer
class MainContent: UIViewController {
//Movie Player variables
var movieViewController : MPMoviePlayerViewController?
var movieplayer : MPMoviePlayerController!
override func viewDidLoad() {
super.viewDidLoad()
//Video Player setup
NSNotificationCenter.defaultCenter().addObserver(self, selector: "doneButtonClick:", name: MPMoviePlayerPlaybackDidFinishNotification, object: nil)
var url = NSURL(string: "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v")!
movieViewController = MPMoviePlayerViewController(contentURL: url)
}
func doneButtonClick(sender:NSNotification?){
let value = UIInterfaceOrientation.Portrait.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
movieViewController?.moviePlayer.stop()
}
#IBAction func watchPressed(sender: AnyObject){
self.presentMoviePlayerViewControllerAnimated(movieViewController)
movieViewController?.moviePlayer.play()
}
}
Related
I currently have my app linking to a certain URL upon opening the app, and this obviously can have a delay between opening it and the webView actually loading, so I want it to display an activity indicator whenever the webView is loading, I have the following code in my ViewController.swift:
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet weak var webView: UIWebView!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
let url = URL(string: "url to site")
webView.loadRequest(URLRequest(url: url!)
}
func webViewDidStartLoad(webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView){
activityIndicator.stopAnimating()
}
The activity indicator shows up from the beginning but it does not disappear once the webView loads and stays their forever.
The way you have your code organized is a bit confusing. It appears you are declaring your funcs inside the #IBAction function. If this is the case, this will not work.
Try this instead
class ViewController: UIViewController, UIWebviewDelegate {
override func viewDidLoad() {
...
webView.delegate = self
// You should add this to your Storyboard, above the webview instead of here in the code
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
// I forget the actual method name - look it up
view.insertSubview(activityIndicator, above: webView)
}
#IBAction func openButton(_ sender: Any) {
let url = URL(string: "websiteURL")
webView.loadRequest(URLRequest(url: url!))
}
func webViewDidStartLoad(webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView){
activityIndicator.stopAnimating()
}
// You'll also want to add the "didFail" method
}
The issue is a syntax issue, you have to add an underscore in the functions.
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
let url = URL(string: "your URL")
webView.loadRequest(URLRequest(url: url!))
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool{
activityIndicator.startAnimating()
return true
}
func webViewDidStartLoad(_ webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(_ webView: UIWebView){
activityIndicator.stopAnimating()
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error){
activityIndicator.stopAnimating()
}
I have a view with a series of action buttons. All these buttons are connected to a function that allows me to play a video. I retrieve the name of the video in the button title. The problem is that I need to press the button twice to get the right video, otherwise the last video is playing
Here is the code that is associated.
import UIKit
import AVKit
import AVFoundation
class levresViewController: UIViewController,UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var varVue2="toto"
var playerController = AVPlayerViewController()
var player:AVPlayer?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let videoString:String? = Bundle.main.path(forResource: varVue2, ofType: ".mp4")
if let url = videoString {
let videoURL=NSURL(fileURLWithPath: url)
self.player = AVPlayer(url: videoURL as URL)
self.playerController.player = self.player
}
// Do any additional setup after loading the view.
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playVideo(_ sender: UIButton) {
varVue2=sender.currentTitle!
self.present(self.playerController,animated:true,completion:{
self.playerController.player?.play()
})
}
}
I am new to Mac OSX and with Apple promoting the fact that the bodies of code are becoming similar decided to tell the folk I am writing code for we should be able to do a Mac OSX version. iPhone and iPad versions are all good and about to release second version so no issues there.
So I am subclassing NSWindowController to get access to the Toolbar and worked out how to remove and add items on the toolbar, but for the life of me I can not get one NSViewController (firstViewController) to dismiss and bring up the second NSViewController (secondViewController) in the same NSWindowController.
So the 2 issues are that
1. I want to be able to performSegueWithIdentifier from the first NSViewController in code and
2. bring up the second NSViewController by replacing the first NSViewController in the same NSWindowController.
If I add a button to the firstViewController and put a segue to the secondViewController then when I select the button the secondViewController comes up just fine but in a seperate window not the same NSWindowController that I want it to and the firstViewController does not get replaced but stays in the NSWindowController.
So I know the segue idea will work but its not working in code and when I do insert the segue from a button it works but into a seperate NSViewController that is not part of the NSWindowController.
I am trying to find some programming guide from Apple on the issue but no luck so far.
Here is an overview from my Storyboard:
Here is my NSWindowController subclassed and the func loginToMe2Team is trigger from the NSToolBar and its working just find as the print statements show up on the console.
import Cocoa
class me2teamWindowsController: NSWindowController {
#IBOutlet var mySignUp : NSToolbarItem!
#IBOutlet var myToolbar : NSToolbar!
let controller = ViewController()
override func windowDidLoad() {
super.windowDidLoad()
print("window loaded")
}
override func windowWillLoad() {
print("window will load")
}
#IBAction func logInToMe2Team(sender: AnyObject){
controller.LogIn() //THIS IS THE FUNC I AM TESTING WITH
}
#IBAction func signUpToMe2Team(sender: AnyObject){
controller.signUp()
}
Here is my NSViewController subclassed with the func LogIn. Its getting selected just fine but the performSegueWithIdentifier is not. And I did cut and past the Identifier to make absolutely sure it was the same.
import Cocoa
import WebKit
class ViewController: NSViewController {
#IBOutlet weak var theWebPage: WebView!
#IBOutlet weak var progressIndicator: NSProgressIndicator!
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "https://thewebpage.com.au"
self.theWebPage.mainFrame.loadRequest(NSURLRequest(URL: NSURL(string: urlString)!))
}
override func viewDidAppear() {
}
func LogIn() {
print("I logged in")
self.performSegueWithIdentifier("goToTeamPage", sender: self)
//THIS IS THE BIT THATS NOT WORKING
}
func signUp() {
print("I have to sign up now")
}
override var representedObject: AnyObject? {
didSet {
}
}
func webView(sender: WebView!, didStartProvisionalLoadForFrame frame: WebFrame!)
{
self.progressIndicator.startAnimation(self)
}
func webView(sender: WebView!, didFinishLoadForFrame frame: WebFrame!)
{
self.progressIndicator.stopAnimation(self)
}
}
You need to use a custom segue class (or possibly NSTabViewController if it’s enough for your needs). Set the segue’s type to Custom, with your class name specified:
…and implement it. With no animation, it’s simple:
class ReplaceSegue: NSStoryboardSegue {
override func perform() {
if let src = self.sourceController as? NSViewController,
let dest = self.destinationController as? NSViewController,
let window = src.view.window {
// this updates the content and adjusts window size
window.contentViewController = dest
}
}
}
In my case, I was using a sheet and wanted to transition to a different sheet with a different size, so I needed to do more:
class ReplaceSheetSegue: NSStoryboardSegue {
override func perform() {
if let src = self.sourceController as? NSViewController,
let dest = self.destinationController as? NSViewController,
let window = src.view.window {
// calculate new frame:
var rect = window.frameRectForContentRect(dest.view.frame)
rect.origin.x += (src.view.frame.width - dest.view.frame.width) / 2
rect.origin.y += src.view.frame.height - dest.view.frame.height
// don’t shrink visible content, prevent minsize from intervening:
window.contentViewController = nil
// animate resizing (TODO: crossover blending):
window.setFrame(window.convertRectToScreen(rect), display: true, animate: true)
// set new controller
window.contentViewController = dest
}
}
}
I am having trouble playing a video in my view controller. I have a play button and when I press it, I want the video which I imported into xcode to play. Having some errors come up and I am stumped. Any ideas?
import UIKit
import MediaPlayer
import AVFoundation
class AuroraViewController: UIViewController {
var moviePlayer: AVPlayer?
#IBOutlet var AuroraViewController: UIView!
#IBAction func playButtonPressed(sender: AnyObject) {
playVideo()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func playVideo() {
if let path = NSBundle.mainBundle().pathForResource("Aurora", ofType:"mp4") {
let url = NSURL(fileURLWithPath: path)
Here I begin to get errors and need help with what it is complaining about
moviePlayer = AVPlayer(contentURL: url)
self.moviePlayer = moviePlayer
moviePlayer.view.frame = self.view.bounds
moviePlayer.prepareToPlay()
moviePlayer.scalingMode = .AspectFill
view.addSubview(moviePlayer.view)
} else {
debugPrint("oops, something wrong when playing video.m4v")
}
}
}
I need to create a button where when I press it, just one sounds gets played. When I press it again, I want a different sound to get play. I have 4 sounds that I want to get played randomly. Therefor when I press the button let's say 8 times, I will hear 8 sounds, randomly.
I put the sound file names in an array and implemented the arc4random to randomise. I am working with AVFoundation and that's where I get stuck. I do not know how to play this array.
I know how to play 1 sound, but not how to implement this in the button. Anyone any idea?
import UIKit
import AVFoundation
class ViewController: UIViewController {
let soundFilenames = ["sound_1.mp3", "sound_2.mp3"]
let randomIndex = Int(arc4random_uniform(UInt32(soundFilenames.count)))
let selectedFilename = soundFilenames[randomIndex]
#IBAction func tap(sender: UIButton) {
// Audio code?
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Edit :
#IBAction func tap(sender: UIButton) {
let soundFilenames = ["Sound1.mp3", "Sound2.mp3"]
let randomIndex = Int(arc4random_uniform(UInt32(soundFilenames.count)))
let selectedFilename = soundFilenames[randomIndex]
let sound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("selectedFilename", ofType: "mp3")!)
var audioPlayer : AVAudioPlayer?
audioPlayer = AVAudioPlayer(contentsOfURL: sound, error: nil)
audioPlayer!.prepareToPlay()
audioPlayer!.play()
}
Edit 2 :
var audioPlayer : AVAudioPlayer?
#IBAction func tap(sender: UIButton) {
let soundFilenames = ["Sound1", "Sound2"]
let randomIndex = Int(arc4random_uniform(UInt32(soundFilenames.count)))
let selectedFilename = soundFilenames[randomIndex]
let sound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("selectedFilename", ofType: "mp3")!)
audioPlayer = AVAudioPlayer(contentsOfURL: sound, error: nil)
audioPlayer!.prepareToPlay()
audioPlayer!.play()
}
If that is your exact copy/pasted code, your let sound statement could use a proofread.
let sound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("selectedFilename", ofType: "mp3")!)
not
let sound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("selectedFilemane", ofType: "mp3")!)
You mentioned you know how to play a sound, but have you done that yet with this code?