I am trying to play a remote mp4 file which is there on the web using AVPlayer on TVOS. When i try to play the video i can hear the audio but there is no video and whole screen is blank. I have read many articles about that which say that i should turn off ATS (I did that. However my url is HTTPS) and i set the frame also in viewDidLayoutSubviews, but still unable to make it work. Here is my code, if some could help me in solving this issue then it will be a great help since i am scratching my head here and there since yesterday.
I am not writing the exact Url for some privacy issues.
import Foundation
import UIKit
import AVKit
class PlayViewController : UIViewController {
var moviePlayer : AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
print("In PlayViewController View Did Load")
let movieUrl = NSURL.init(string: "Some Amazon Url.mp4")!
moviePlayer = AVPlayer.init(URL: movieUrl)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let avPlayerLayer = AVPlayerLayer.init(layer: moviePlayer!)
avPlayerLayer.frame = CGRectMake(0.0, 0.0, 1024.0, 768.0)
self.view.layer.addSublayer(avPlayerLayer)
moviePlayer?.play()
}
}
The URL is somehow indicating HTTP(S) streaming, right?
Well, I also made my experience while trying to play a video stream from a set-top-box like a DVB receiver through its Web-Interface. It did not work (at least when I tried with tvOS 9.0). According to Apple documentation the video streams have to comply to the HTTP Streaming protocol they describe. It requires, that HTTP streams are split into small chunks of video snippets of a few seconds length. See https://developer.apple.com/library/tvos/referencelibrary/GettingStarted/AboutHTTPLiveStreaming/about/about.html
At the end I gave up and switched to use VLCKit from videolan.org. After some back and forth this works fine in my App (vuplusTV).
Related
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.
I have successfully implemented valid and working AVFoundation video recording functionality into my application. That said, any playing audio e.g. Apple Music or a YouTube video playing in the background is interrupted / immediately paused whenever the video recording begins.
My question is: How could I allow the globally-playing audio to continue to play without interruption when recording video?
I was able to do this by adapting the answer here to Swift.
I was doing this to prevent a silent tutorial video in my app from interrupting any currently playing audio. Setting the AVAudioSession category to "ambient" using the setCategory(_:mode:options:) method seems to be the key here.
Apple seems to suggest using this method within the application didFinishLaunchingWithOptions method, but I think their example is targeted towards audio apps. So depending on your needs, you may want to put it there.
Here's the adapted code, I placed it within the view controller that is showing the video:
import AVFoundation
...
override func viewDidLoad() {
super.viewDidLoad()
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.ambient, mode: .default, options: .mixWithOthers)
} catch {
print(error.localizedDescription)
}
}
This question has the same problem, but the solutions didn't work.
The AVPlayer sometimes plays a blank video: there is sound but no video.
While blank videos were played, we printed the frame and status of the player. The frame was non-zero and was correctly set. The status was also readyToPlay. The play function is also invoked on the main thread.
In other words, the frame for the player layer is valid, and the player is also ready to play. Yet no video appears, even though sound does.
The issue seems to be a timing one. If we wait 5-10 seconds before playing the video, the video works fine each time.
This issue appears on iOS 10, not iOS 8 or 9.
This thread on the Apple forums suggests it might be a bug related to
AVVideoCompositionCoreAnimationTool, which we also use.
Any solutions?
This happens more often on iPhone 7 devices than iPhone 5s devices.
Code:
fileprivate func playVideo(_ videoURL: String, prompt: String) {
// Show <playerView>
playerView.isHidden = false
// Use new video in player
playerItem = AVPlayerItem(url: URL(fileURLWithPath: videoURL))
print("STATUS: \(player.status == AVPlayerStatus.readyToPlay). FRAME: \(playerLayer.frame). MAIN THREAD: \(Thread.isMainThread)")
player.replaceCurrentItem(with: playerItem)
// Start playing video
player.seek(to: kCMTimeZero)
player.actionAtItemEnd = .none
player.play()
}
I think you need to play with a AVPlayerViewController or AVPlayerLayer.
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
//set player layer frame and attach it to our view
playerLayer.frame = self.containerView.bounds;
[self.containerView.layer addSublayer:playerLayer];
//play the video
[player play];
From Apple doc:
AVPlayer and AVPlayerItem are nonvisual objects meaning that on their
own are unable to present an asset’s video on screen. You have two
primary approaches you can use to present your video content on
screen:
AVKit: The best way to present your video content is by using the
AVKit framework’s AVPlayerViewController class in iOS and tvOS or the
AVPlayerView class in macOS. These classes present the video content,
along with playback controls and other media features giving you a
full-featured playback experience.
AVPlayerLayer: If you are building a custom interface for your player,
you use a Core Animation CALayer subclass provided by AVFoundation
called AVPlayerLayer. The player layer can be set as a view’s backing
layer or can be added directly to the layer hierarchy. Unlike
AVPlayerView and AVPlayerViewController, a player layer doesn’t
present any playback controls, but simply presents the visual content
on screen. It is up to you to build the playback transport controls to
play, pause, and seek through the media.
In case anyone encounters this issue, the problem seems related to an iOS bug. The problem doesn't occur on iOS 8/9 devices, only on new iOS 10 devices. Starting with iOS 10.2, the problem vanishes.
Unfortunately, still no programmatic solution for 10.0.x or 10.1.x.
This question already has answers here:
How to embed a Youtube video into my app?
(7 answers)
Closed 7 years ago.
Okay so I'm looking to play film trailers in my app. The user will press a button, and then it plays the video. I have added the import AVKit and import AVFoundation lines to my file. This is the code I have so far for making the video play:
#IBAction func playTrailerPressed(sender: AnyObject) {
let videoURL = NSURL(string: "https://youtu.be/d88APYIGkjk")
let player = AVPlayer(URL: videoURL!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.presentViewController(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
This seems to launch an AVPlayerViewController, but doesn't play the video from YouTube. Instead, I get the below:
I have tried both the sharing and embedding link from YouTube, but neither work. If I use a link which has the video file name at the end, it plays it fine, for example: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"- So I know the code works.
Does anyone know if this is possible to use this way with a YouTube video? (I have also tried trailers from IMDb and Apple, but it's the same).
Thanks for your help!
AVPlayer only plays movie files, and YouTube videos aren't directly exposed as movie files at their URL. It looks like the preferred way to handle YouTube videos is to embed a web view into your app. See this page for information from Google on how to do that.
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: