Embedding videos in iOS app - ios

I'm fairly new to iOS development, but I'm confident with the basics (basic interface, user interaction, logic). What I want to do now is create an app that streams/downloads a video from a personal recording website (so login required by user), and then allows basic editing (trimming) and sharing to different social media, like twitter, facebook, youtube, etc... I have absolutely no experience with this.
My research so far has pointed me towards webViews and use of AVKit import, and they seem appropriate, but I was hoping for more concrete advice.
What do I look into? Where can I start?

Its pretty easy to give a URL to AVPlayer and have it stream a video into the layer. I usually add the layer into a view and use autolayout on that view to resize it (although you can also subclass UIView and override layerClass and make the videoLayer the view's backing layer if you want). This code will stream from a remote URL or if you download the file to the documents directory and get a URL to it you can play a local file also.
let playerLayer = AVPlayerLayer()
let player = AVPlayer(playerItem: AVPlayerItem(asset: AVAsset(url: url), automaticallyLoadedAssetKeys: ["playable"]))
playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
playerLayer.frame = videoView.bounds
videoView.isHidden = false
videoView.layer.addSublayer(playerLayer)
playerLayer.player?.play()

Related

AVPlayer on Swift app shows a black screen but plays audio when playing video

New to Swift! I am trying to have the app play a video from my Resources upon pressing a button. I have this method in my ViewController:
if let path = Bundle.main.path(forResource: "Cypress", ofType: "mov") {
let player = AVPlayer(url: URL(fileURLWithPath: path))
// Create a new AVPlayerViewController and pass it a reference to the player.
let controller = AVPlayerViewController()
controller.player = player
// Modally present the player and call the player's play() method when complete.
self.present(controller, animated: true) {
player.play()
}
}
However, when the video begins to play, it is a black screen but the audio is playing properly. Are there any quick fixes to this? I am using Xcode version 12.2. Any advice would be greatly appreciated thanks :)
The problem is with the video file itself / the encoding.
Deceptively, the Quicktime ".mov" format is not a video codec, but rather audio/video container format that can contain video and audio (and some other things) in any number of compression codecs (h.264, mpeg2, ProRes, MJPEG, AAC, mp3, etc.) … Your files don't work because they include video compressed with a codec which iOS does not support.
From #alexkent in this SO answer on another post.
I don't think a .mov is necessarily not going to work for you, but you'd have to make sure it was encoded in a way that is iOS-compatible. So as you mentioned in the comments, using .mp4 ensures the video is encoded in an iOS-compatible fashion.

Popping back to subview speeds up video

I have a UIView with a video as its background. When I present another subview, and then pop back to the one with the video, this happens:
Video [11 seconds] (kept it a video since a GIF wouldn't have the same framerate, and the problem would be less clear.)
As you can see, the video speeds up, and then slows down when it reaches a certain point. What I'd like to accomplish is for the video to always keep playing at it's normal speed, and thus eliminate the speedup happening.
This is the code used for the showing of the video:
self.player = AVPlayer(url: URL(fileURLWithPath: path))
let playerLayer = AVPlayerLayer(player: self.player)
self.layer.addSublayer(playerLayer)
playerLayer.frame = self.bounds
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
Does AVPlayer perhaps have an option to disable this, or is there a way around it?
Thanks.
I would assume this is happening because the video keeps playing while the other view controller is presented on the screen.
What I would try to solve this is to pause the video in viewWillDisappear and then play it again in viewWillAppear.

Play video in UITableViewCell or UICollectionViewCell iOS

There is so much stuff in Stackoverflow about playing videos in cell, that every person may feel confused, especially that most of question are not solved and it looks like that every developer gives up.
So I wanted to create new question where there will be up-to-date answers.
Objective:
Play video in UITableViewCell or UICollectionViewCell when user taps cell (yes, this is simplified version, this is not about autplay).
Solution:
I think everyone agrees that we should use AVPlayer instead of deprecated MPMoviePlayerController.
Cell should have layer where AVPlayer can be assigned, so in my code while creating cell I added this code:
VideoCell.swift
let layer = AVPlayerLayer()
layer.backgroundColor = UIColor.clear.cgColor
layer.videoGravity = AVLayerVideoGravityResizeAspectFill
Now when cell is tapped I'm using this code:
ViewController.swift
cell.playerLayer.player = player
player.replaceCurrentItem(with: AVPlayerItem(asset: asset))
player.play()
Where player is global instance of AVPlayer and asset is AVAsset initialized with video URL.
It would work fine, but AVPlayer needs time to download info and buffer some part of video, and what user gets is delay. So we can think about one solution, which is downloading video first and playing it locally when users taps in cell.
Question:
Is it really good approach to downloading every video in data source and then playing it locally? When should we remove it from device? Facebook and Instagram looks like they download only part of the video first, is there any who can share own experience?
Objective-C code will be appreciated too.

Set cache size for AVPlayer

Is it possible to simply set the size of the cache for an AVPlayer? I've an app where the user will often go back and forth in the video and I'd like to make sure that there's enough caching happening. I've found that code that shows how to manually handle the network requests using an AVAssetResourceLoaderDelegate and that's pretty involved. Ideally I'm looking for something like
let player = AVPlayer(url: url)
player.urlSession = myConfiguredURLSession

AVFoundation and video

I am trying to use AVFoundation, AVPlayer and AVPlayerViewController to show a video. Does anyone know of any good tutorials out there that does NOT use MPMoviePlayer?
Please let m eknow!
thank you!
AVPlayerViewController
AVPlayerViewController is the AVKit ViewController that hides away most of the complexity involved with dealing directly with AVFoundation. Its very simple and intuitive, if you check the AVPlayerViewController Class Reference you will notice that it does not hold that many properties, if you want to initialise one and attribute a video to it, you have three options ( that I can recall ).
Initialise it in code and set the frame of it;
Subclass it and call it when you wanna use it;
Use Storyboards / nibs to allocate a AVKit Player View Controller.
Either way its up to you and this is a common pattern among iOS developers, so it shouldn't strike as a surprise to you unless you are a complete beginner. Please note that for any of these ways of creating an AVPlayerViewController, you have to initialise the AVPlayer object with an AVPlayerItem or an URL carrying the video you want to display.
Subclassing AVPlayerViewController-Swift
Obs. This is the swift example, but the Objective-C one follows the same pattern, the only change is the syntax of each language.
class AVKitPlayerViewController: AVPlayerViewController {
override func viewDidLoad() {
super.viewDidLoad()
// get the video URL
let videoURL = NSBundle.mainBundle().URLForResource("Test", withExtension: ".mov")
// Initialise with URL
player = AVPlayer(URL: videoURL!)
// Initialise with AVPlayerItem
let playerItem = AVPlayerItem(URL: videoURL!)
player = AVPlayer(playerItem: playerItem)
// If you want custom controls showsPlaybackControls should be false
// Then you must create your own buttons
//showsPlaybackControls = false
}
}
AVFoundation
AVFoundation is a very large and interesting framework, you can do a lot of advanced and interesting stuff with it. I would encourage you to go read the docs and checkout these WWDC-2015 sample code:
AVFoundationPiPPlayer: Picture-in-Picture Playback with AVKit
AVFoundationQueuePlayer-iOS: Using a Mixture of Local File Based Assets and HTTP Live Streaming Assets with AVFoundation
AVFoundationSimplePlayer-iOS: Using AVFoundation to Play Media
AVFoundation Programming Guide
AVFoundation Programming Guide
I hope this helps you. Happy Coding. :smile:

Resources