I'm developing a live video player and I want to use the new Picture in Picture option. I based the player on an AVPlayerViewController and this is my code.
class PlayerViewController: AVPlayerViewController {
var link = NSURL ()
override func viewDidLoad() {
super.viewDidLoad()
setVideoPlayer()
do {
try AVAudioSession.sharedInstance().setActive(true)
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
}
catch {
print("Audio session setCategory failed")
}
}
}
typealias VideoPlayer = PlayerViewController
extension VideoPlayer {
func setVideoPlayer() {
player = AVPlayer(URL: (link))
player!.play()
}
}
I don't understand why PictureInPicture works well on iPad Air 2 simulator but in the real device the PiP button stays disabled although visible, and the user can't click on it.
Make sure to set audio session in AppDelegate.swift func application(application:, didFinishLaunchingWithOptions launchOptions:) find below the sample code .
let audioSssn = AVAudioSession.sharedInstance();
do {
try audioSssn.setCategory(AVAudioSessionCategoryPlayback)
}
catch {
print("Audio session setCategory failed")
}
Related
I was following this tutorial on YouTub: https://www.youtube.com/watch?v=qC6DzF_ACpQ&t=714s , and at 12.18 when he clicks the button, it plays audio. I followed all the exact same steps as he did in the video and it is not working for me.
I am pretty new to coding in swift so I did not try anything else other than restarting the whole project again, but it did not work.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func aTapped(_ sender: Any) {
let url = Bundle.main.url(forResource: "a", withExtension: "mp3")
// Make sure that weve got the url, otherwise abord
guard url != nil else{
return
}
do{
audioPlayer = try AVAudioPlayer(contentsOf: url!)
audioPlayer?.play()
}
catch{
print("error")
}
}
I just want the audio to play when I click the button assigned to the code, but when I click the button, no audio plays at all.
Please Help.
I am currently working on a method that will play a mp4 file when called. However, while the mp4 file is being played I want user interactions to be disabled. This is so that the user cannot tap the screen while the mp4 is playing and start the same AVAudioSession over again. My code thus far is this
import Foundation; import UIKit; import AVFoundation
var player: AVAudioPlayer?
class Card: NSObject
{
var image: UIImage
var soundUrl: String
init(image: UIImage, soundUrl: String, isActive:Bool = true) {
self.image = image
self.soundUrl = soundUrl
}
func playSound()
{
guard let url = Bundle.main.url(forResource: self.soundUrl, withExtension: "m4a") else { return }
do
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url)
guard let player = player else { return }
player.prepareToPlay()
player.play()
print("play")
} catch let error {
print(error.localizedDescription)
}
}
}
You're missing any references to the UI elements you want to disable. You're just going to set button.isEnabled = false on the them, and set them back when the player is done. You'll know the player is done by setting your object as its delegate and then implementing func audioPlayerDidFinishPlaying(_:successfully) to turn things back on.
As a note, there is never a reason to call prepareToPlay() immediately before calling play(). play() prepares itself.
player.delegate = self
extension Card: AVAudioPlayerDelegate {
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
// re-enable UI
}
}
You can call self.view.isUserInteractionEnabled = false after playing the audio.
After that, use self.view.isUserInteractionEnabled = true on audioPlayerDidFinishPlaying(_:successfully)
To disable all incoming touches on the device, you can call UIApplication.shared.beginIgnoringInteractionEvents() and call UIApplication.shared.endIgnoringInteractionEvents() to reenable touches. This is typically called during animations but this is what you asked for.
I need to build an application that plays an audio live streaming URL for a radio station.
The URL is available but i can't find a good way to implement it in my application.
I've tried this way but the player won't provide any sound, although i am sure it is loading the URL (it plays the stream when trying on a simulator but on a real device it does not)
This is my code:
var player : AVPlayer!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let url = "http://listen.shoutcast.com/radiodeltalebanon"
player = AVPlayer(url: URL(string: url)!)
player.volume = 1.0
player.rate = 1.0
player.play()
}
The indicator beside the 4G or the Wifi icon in the status bar is showing while in app and if i turn the volume of my phone up, the Volume is up and not the Ringer.
This means that it is actually playing but no sound is available.
Can anyone help me please ?
Thanks.
Turned out that i missed this :
override func viewDidLoad() {
super.viewDidLoad()
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
print("AVAudioSession Category Playback OK")
do {
try AVAudioSession.sharedInstance().setActive(true)
print("AVAudioSession is Active")
} catch let error as NSError {
print(error.localizedDescription)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
For Swift 4.2:
override func viewDidLoad() {
super.viewDidLoad()
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
}
I'm creating my first app. I have an app with music playing in the background with the following code:
var backgroundMusicPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
//background Music
func playBackgroundMusic(filename: String) {
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
guard let newURL = url else {
print("Could not find file: \(filename)")
return
}
do {
backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: newURL)
backgroundMusicPlayer.numberOfLoops = -1
backgroundMusicPlayer.prepareToPlay()
backgroundMusicPlayer.play()
} catch let error as NSError {
print(error.description)
}
}
playBackgroundMusic("Starship.wav")
}
So what should I do in order to stop/mute the background music when I switch to another ViewController? Should I do this my FirstViewController or SecondViewController?
Obviously, I don't want the sound to be off in the SecondViewController as I have other stuff that will be playing there.
To mute sound I simply mute the volume.
backgroundMusicPlayer.volume = 0
and set it to normal if I want sound
backgroundMusicPlayer.volume = 1
If you just want to pause music you can call
backgroundMusicPlayer.pause()
To resume you call
backgroundMusicPlayer.resume()
If you want to stop music and reset it to the beginning you say this
backgroundMusicPlayer.stop()
backgroundMusicPlayer.currentTime = 0
backgroundMusicPlayer.prepareToPlay()
Did you also consider putting your music into a singleton class so its easier to play music in your different viewControllers.
Not sure this is what you are looking for as your question is a bit vague.
Forgive me if this question has been asked already, but I've looked everywhere and all I can find is old questions from iOS 5.0 and people have the opposite problem.
My problem is I have created a video I would like to use in my application, and I recently added audio to it. The video plays fine with no problems, but the audio does not play. If I play the video in any video player in my computer, the sound is there so I cant figure out what the problem is.
Here is my code:
var movieViewController: MPMoviePlayerViewController?
func playVideoUsingViewController() {
if let
path = NSBundle.mainBundle().pathForResource("wakyIntro", ofType: "mp4"),
url = NSURL(fileURLWithPath: path),
movieViewController = MPMoviePlayerViewController(contentURL: url) {
self.movieViewController = movieViewController
movieViewController.moviePlayer.fullscreen = true
movieViewController.moviePlayer.controlStyle = .None
movieViewController.moviePlayer.scalingMode = .AspectFill
movieViewController.view.userInteractionEnabled = false
self.showViewController(movieViewController, sender: self)
println("Movie loaded")
} else {
println("Video failed")
}
}
Then I just call it from my ViewController:
func mainMenuViewControllerDidPressPlay(mainMenuViewController: MainMenuViewController) {
game?.runAction(pressButton)
if !videoPlayed{
playVideoUsingViewController()
} else if !gameStarted {
gameStarted = true
game?.bird.startAnimation(game!)
game?.bird.startPhysics()
}
self.hideViewController(mainMenuViewController)
}
Any ideas or suggestions would be greatly appreciated!
This is a solution in swift based on #user2709666's response
var session: AVAudioSession = AVAudioSession.sharedInstance()
session.setCategory("AVAudioSessionCategoryPlayback", withOptions: AVAudioSessionCategoryOptions.DefaultToSpeaker, error: nil)
Call this before playing the video.
Edit for Swift 2.2 :
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
} catch let error as NSError {
print(error)
}
Make a session of AVAudioSession.
Following is the code:
var session = AVAudioSession.SharedInstance();
session.SetCategory(new NSString("AVAudioSessionCategoryPlayback"), AVAudioSessionCategoryOptions.DefaultToSpeaker, out error);
if (error != null)
{
Console.WriteLine(error);
}
and add this before your video player. I am sure this will work for you, I got the same issue before.