I have a video I'm trying to play using MPMoviePlayerController and it loads fine, but cuts out after 5 seconds. I found this post, but it isn't really applicable for swift.
MPMoviePlayerController stops playing the video after 5s
Here is my code.
import MediaPlayer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var moviePlayer: MPMoviePlayerController?
let url = NSURL(string: "http://path/to/video.m3u8")
moviePlayer = MPMoviePlayerController(contentURL: url)
if let player = moviePlayer {
player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
player.view.sizeToFit()
player.scalingMode = MPMovieScalingMode.None
player.movieSourceType = MPMovieSourceType.Streaming
//player.repeatMode = MPMovieRepeatMode.One
player.play()
self.view.addSubview(player.view)
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "metadataUpdated",
name: MPMoviePlayerTimedMetadataUpdatedNotification,
object: nil)
}
}
Could your moviePlayer be going out of scope? Have you tried making it a member variable?
moviePlayer is a local variable of viewDidLoad, so once that function finishes, I don't see any reason why your player would not be deallocated.
If you instead make it a variable of the class, its lifetime will be extended to match your class's lifetime.
something like
class ViewController: UIViewController {
var player: MPMoviePlayerController?
override func viewDidLoad() {
// ...
self.player = MPMoviePlayerController(contentURL: url) // won't go out of scope at end of viewDidLoad()
// ...
}
Related
The code I was using to embed a local video in a UIView isn't working on IOS 12. The audio is playing but I get a black screen.
from apple developer site:
Do not subclass AVPlayerViewController. Overriding this class’s methods is unsupported and results in undefined behavior.
the code works fine on IOS 11, any idea what do I need to change in the code?
thanks
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
var avPlayer: AVPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let filepath: String? = Bundle.main.path(forResource: "qidong", ofType: "mp4")
let fileURL = URL.init(fileURLWithPath: filepath!)
avPlayer = AVPlayer(url: fileURL)
let avPlayerController = AVPlayerViewController()
avPlayerController.player = avPlayer
avPlayerController.view.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
avPlayerController.showsPlaybackControls = false
avPlayerController.player?.play()
self.view.addSubview(avPlayerController.view)
}
}
You need to add the AVPlayerViewController as a child view controller so something like this:
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
var avPlayer: AVPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let filepath: String? = Bundle.main.path(forResource: "qidong", ofType: "mp4")
let fileURL = URL.init(fileURLWithPath: filepath!)
avPlayer = AVPlayer(url: fileURL)
let avPlayerController = AVPlayerViewController()
avPlayerController.player = avPlayer
avPlayerController.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
avPlayerController.showsPlaybackControls = false
avPlayerController.player?.play()
self.addChild(avPlayerController)
self.view.addSubview(avPlayerController.view)
avPlayerController.didMove(toParent: self)
}
If you are not doing that then the AVPlayerViewController is probably getting released early.
Another minor issue but don't use the size of the UIScreen but the frame of the view controllers view instead (or even better do something like use auto layout).
I want to play background video on login screen on swift 3.0. But when I run program, video do not working as full screen. It is workingHow can I fix this ? Here is the storyboard picture.
enter code here
import UIKit
import AVFoundation
class ViewController: UIViewController {
var Player: AVPlayer!
var PlayerLayer: AVPlayerLayer!
var frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let URL:NSURL = NSURL(string: "https://firebasestorage.googleapis.com/v0/b/pattyapp-34c16.appspot.com/o/dog1.mp4?alt=media&token=98ab3c41-c645-4535-a70b-41511b5df602")!
Player = AVPlayer.init(url: URL as URL)
PlayerLayer = AVPlayerLayer(player: Player)
PlayerLayer.videoGravity = AVLayerVideoGravityResizeAspect
PlayerLayer.frame.size = frame.size
Player.actionAtItemEnd = AVPlayerActionAtItemEnd.none
Player.isMuted = true
Player.play()
view.layer.insertSublayer(PlayerLayer, at: 0)
NotificationCenter.default.addObserver(self, selector: #selector(playerItemReachEnd(notification:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: Player.currentItem)
}
func playerItemReachEnd(notification: NSNotification) {
Player.seek(to: kCMTimeZero)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Play video into background you can use the following list of 3rd party library to resolve your problem.
VideoSplashKit
HAPlayerView
Video You are trying to play has dimensions different from layer size. I'd recommend You to try
PlayerLayer.videoGravity = AVLayerVideoGravityResize
or
PlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
Hi all i am trying to play a video from s3 using Avplayer. Now if i play the video, the video starts playback after the whole video is buffered. so I added player.automaticallyWaitsToMinimizeStalling = false, but now the video automatically pauses
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
var player: AVPlayer!
var item : AVPlayerItem!
override func viewDidLoad() {
super.viewDidLoad()
item = AVPlayerItem(url: URL(string: "https://cent-churchconnect.s3-ap-southeast-2.amazonaws.com/cent-churchconnect/testAdmin/eb8cc8b5-80e0-468a-a2c9-979cf1b5ac76_toystory.mp4")!)
player = AVPlayer(playerItem: item)
let controller = AVPlayerViewController()
present(controller, animated: true) { _ in }
controller.player = player
addChildViewController(controller)
view.addSubview(controller.view)
controller.view.frame = CGRect(x: 0, y: 50, width: self.view.frame.size.width, height: 300)
controller.player = player
controller.showsPlaybackControls = true
if #available(iOS 10.0, *) {
player.automaticallyWaitsToMinimizeStalling = false
player.play()
} else {
// Fallback on earlier versions
}
}
}
I had the same issue below steps worked for me,
Try to use method func playImmediately(atRate:) and make sure the property player.automaticallyWaitsToMinimizeStalling = false is set properly.
Use method func playImmediately(atRate:) instead of func play()
I used the cocoa pod https://github.com/piemonte/Player.
You can use the delegate methods to control the playback.
I have a local .mp4 video that I would like to add as a background video. I've created a function:
func playVideo() {
let path = NSBundle.mainBundle().pathForResource("dronefootagecompressed", ofType:"mp4")
let url = NSURL.fileURLWithPath(path!)
self.moviePlayer = MPMoviePlayerController(contentURL: url)
if let player = self.moviePlayer {
player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
player.view.sizeToFit()
player.scalingMode = MPMovieScalingMode.Fill
player.fullscreen = true
player.controlStyle = MPMovieControlStyle.None
player.movieSourceType = MPMovieSourceType.File
player.repeatMode = MPMovieRepeatMode.One
player.play()
self.view.addSubview(player.view)
}
}
which is then called in viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
playVideo()
}
The video is showing up, but it seems like it's covering everything else (text labels, titles, everything), or so I assume it is. Can I make the video be in the background (if that even is the issue)?
Thanks.
EDIT:
When I call playVideo() in viewDidAppear, the video shows up for about 2 seconds before going to a black background. The buttons are still visible. Is the video not loading properly?
i think putting it in viewDidAppear() method will solve the thing
I'm trying to make a little intro video for an app before you land on the main view. Code as follows:
import UIKit
import MediaPlayer
class ViewController: UIViewController {
var moviePlayer: MPMoviePlayerController?
//var player: MPMoviePlayerController?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
playVideo()
self.view.removeFromSuperview()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func playVideo() {
let path = NSBundle.mainBundle().pathForResource("paint-me_intro", ofType:"mp4")
let url = NSURL.fileURLWithPath(path!)
moviePlayer = MPMoviePlayerController(contentURL: url)
if let player = moviePlayer {
player.view.frame = self.view.bounds
player.controlStyle = .None
player.prepareToPlay()
player.scalingMode = .AspectFit
self.view.addSubview(player.view)
}
}
}
All I want it to do is after the video finishes playing, it needs to go away. That's all. Any help would be greatly appreciated before I smash my face against the wall.
MPMoviePlayerController uses notifications for message passing, unlike the delegate/protocol pattern of so many other classes. Regardless, to answer your question. Add an observer for the appropriate notification in your view did load, and point to a function which removes the view.
Adding observer
NSNotificationCenter.defaultCenter().addObserver(self, selector: "movieFinished", name:
MPMoviePlayerPlaybackDidFinishNotification, object: nil)
And the function to remove it.
func movieFinished() {
moviePlayer!.view.removeFromSuperview()
NSNotificationCenter.defaultCenter().removeObserver(self, name: MPMoviePlayerPlaybackDidFinishNotification, object: nil)
}