How can I play a video using AVPlayer? - swift

Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)
I would like to play a video from internet using AVPlayer.
But, a error occurred "super.init(frame: frame)" in AVPlayer.swift of below source list.
Thread 1:EXC_BAD_ACCESS (code=2, address=0x16fc07fe0)
How can I play a video using AVPlayer?
If there is wrong point except point of error, let me know it, too.
AVPlayerView.swift
import Foundation
import UIKit
final class AVPlayerView : UIView {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override public class var layerClass: Swift.AnyClass {
get {
return AVPlayerView.self
}
}
}
ViewController.swift
import UIKit
import AVFoundation
import CoreMedia
class ViewController: UIViewController {
var playerItem : AVPlayerItem!
var videoPlayer : AVPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let url:NSURL = NSURL(string: "https://aaa.com/test.m3u8")!
let avAsset = AVURLAsset(url: url as URL, options: nil)
playerItem = AVPlayerItem(asset: avAsset)
videoPlayer = AVPlayer(playerItem: playerItem)
print(self.view.bounds)
let videoPlayerView = AVPlayerView(frame: self.view.bounds)
let layer = videoPlayerView.layer as! AVPlayerLayer
layer.videoGravity = AVLayerVideoGravityResizeAspect
layer.player = videoPlayer
self.view.layer.addSublayer(layer)
videoPlayer.play()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Here is code to play video:
let videoURL = NSURL(string: "PUT_YOUR_PROPER_URL")
let playerAV = AVPlayer(url: videoURL! as URL)
let playerLayerAV = AVPlayerLayer(player: playerAV)
playerLayerAV.frame = self.view.bounds
self.view.layer.addSublayer(playerLayerAV)
playerAV.play()
AVPlayer support below extension:
public.mpeg
public.mpeg-2-video
public.avi
public.aifc-audio
public.aac-audio
public.mpeg-4
public.au-audio
public.aiff-audio
public.mp2
public.3gpp2
public.ac3-audio
public.mp3
public.mpeg-2-transport-stream
public.3gpp
public.mpeg-4-audio
Make sure you can use supported video in AVPlayer.

Related

Swift 5.7 Error: [plugin] AddInstanceForFactory: No factory registered for id

Everything is work fine, but why I get this error.
This is all my code.
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var player: AVAudioPlayer!
#IBAction func keyPressed(_ sender: UIButton) {
playSound()
}
func playSound() {
let url = Bundle.main.url(forResource: "C", withExtension: "wav")
player = try! AVAudioPlayer(contentsOf: url!)
player.play()
}
}
The results are the same as I expect.

Implementing UIView in SwiftUI

I am trying to implement a video player in SwiftUI via a UIView following this tutorial: https://medium.com/flawless-app-stories/avplayer-swiftui-b87af6d0553
Unfortunately the video is not displaying, I have AVFoundation imported so I am not sure of the issue. Has anyone found a solution to this?
Here are the classes I created:
class PlayerUIView: UIView {
private let playerLayer = AVPlayerLayer()
init(frame: CGRect, urlString: String) {
super.init(frame: frame)
guard let url = URL(string: urlString) else {
return
}
let player = AVPlayer(url: url)
player.play()
playerLayer.player = player
layer.addSublayer(playerLayer)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func layoutSubviews() {
super.layoutSubviews()
playerLayer.frame = bounds
}
}
struct VideoPlayerUIView: UIViewRepresentable {
var frame: CGRect
var urlString: String
func makeUIView(context: Context) -> some UIView {
return PlayerUIView(frame: self.frame, urlString: self.urlString)
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
Here I how I am using the implementation in SwiftUI:
var body: some View {
Text("Videos")
VideoPlayerUIView(frame: CGRect(x: 0, y: 0, width: 400, height: 300), urlString: urlString)
}
This was the output (no video)
enter image description here
You did everything right here.
The only thing that is causing error is how you are process the URL.
Try initialising the player like this instead
let player = AVPlayer(url: Bundle.main.url(forResource: urlString, withExtension: "mp4")!)
Change the extension according to the format you are using. Remember, here I am force wrapping the optional. So, if you give a wrong urlString or have a video extension other than mp4, the app will crash

How can I update what video is playing on AVPlayerLayer in SwiftUI?

I have a #State variable in my main ContentView called url that is the source to an mp4 file. How can I modify either PlayerView or VideoView (both below) so that when something causes url to change in ContentView, the VideoView updates itself to play the new video at url?
I feel like I am on the right track by adding a Coordinator in VideoView, but this is something I saw in Apple's tutorials, and I don't really understand how to use it.
PlayerView.swift
import UIKit
import AVKit
class PlayerView: UIView {
private let playerLayer = AVPlayerLayer()
private var playerLooper: AVPlayerLooper?
init(frame: CGRect, url: URL) {
super.init(frame: frame)
// Obtain asset and create an item from it
let asset = AVAsset(url: url)
let item = AVPlayerItem(asset: asset)
// Create the video player using the URL passed in.
let player = AVQueuePlayer()
// Add the player to our Player Layer
playerLayer.player = player
playerLayer.videoGravity = .resizeAspect // Resizes content to fill whole video layer.
playerLayer.backgroundColor = UIColor.black.cgColor
layer.addSublayer(playerLayer)
// Create new player looper
playerLooper = AVPlayerLooper(player: player, templateItem: item)
// Start the movie
player.volume = 0
player.play()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func layoutSubviews() {
super.layoutSubviews()
playerLayer.frame = bounds
}
}
VideoView
(wrapper)
import SwiftUI
import AVKit
struct VideoView: UIViewRepresentable {
#Binding var videoURL: URL
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> UIView {
return PlayerView(frame: .zero, url: videoURL)
}
func updateUIView(_ playerView: UIView, context: Context) {
}
class Coordinator: NSObject {
var parent: VideoView
init(_ videoView: VideoView) {
self.parent = videoView
}
}
}

Play video from url without extension swift

I want to play video from url returns from service, url doesn't have extension, so it doesn't work. what should I do?
xcode9 swift 4
import AVKit
import AVFoundation
import MediaPlayer
import AudioToolbox
class ViewController: UIViewController {
#IBOutlet weak var player_View: UIView!
let videoURL = URL(string: "http://45.58.42.105:82/Handlers/ImageHandler.ashx?fileReference=67f0dce7-a5f5-4894-a8fd-5996f135626c");
var playerVC = AVPlayerViewController()
var playerView = AVPlayer()
var urlStr = "";
override func viewDidLoad() {
super.viewDidLoad()
self.playVideo();
}
func playVideo() {
self.playerView = AVPlayer(url: videoURL!)
self.playerVC.player = playerView
self.player_View.addSubview(self.playerVC.view)
playerVC.view.frame = self.player_View.frame
playerView.play()
}
}

How to Systematically Play Multiple Sounds using a UIButton? [duplicate]

I'm very beginner of programming and start studying Swift to make a piano app for fun.
I have a trouble to play a sound when press a button.
I've searched some website but I'm too beginner to understand...
http://www.tmroyal.com/playing-sounds-in-swift-avaudioplayer.html
http://www.rockhoppertech.com/blog/swift-avfoundation/
Could you please tell me how can I play my "C.m4a" sound when press a "PainoC" button?
Here is my "view controller.swift".
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func PianoC(sender: AnyObject) {
}
}
I hope it will help you.
import UIKit
import AVFoundation
class ViewController: UIViewController {
// make sure to add this sound to your project
var pianoSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("C", ofType: "m4a"))
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
audioPlayer = AVAudioPlayer(contentsOfURL: pianoSound, error: nil)
audioPlayer.prepareToPlay()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func PianoC(sender: AnyObject) {
audioPlayer.play()
}
}
Latest Swift 4.2 :
let pianoSound = URL(fileURLWithPath: Bundle.main.path(forResource: "btn_click_sound", ofType: "mp3")!)
var audioPlayer = AVAudioPlayer()
#IBAction func PianoC(sender: AnyObject) {
do {
audioPlayer = try AVAudioPlayer(contentsOf: pianoSound)
audioPlayer.play()
} catch {
// couldn't load file :(
}
}
Swift 3
the syntax is now as follows:
first add import AVFoundation on top of the code to have access to AVFoundation Framework.
import UIKit
import AVFoundation
class ViewController: UIViewController {
//this is your audio playback instance
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
// address of the music file.
let music = Bundle.main.path(forResource: "Music", ofType: "mp3")
// copy this syntax, it tells the compiler what to do when action is received
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: music! ))
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try AVAudioSession.sharedInstance().setActive(true)
}
catch{
print(error)
}
}
//this runs the do try statement
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func play(_ sender: AnyObject) {
audioPlayer.play()
}
#IBAction func stop(_ sender: AnyObject) {
audioPlayer.stop()
}
}
SWIFT 5
import AVFoundation
class Test {
var player: AVAudioPlayer!
func playAudio() {
let url = Bundle.main.url(forResource: "Sound", withExtension: "mp3")
player = try! AVAudioPlayer(contentsOf: url!)
player.play()
}
}
In Swift 4:
import AVFoundation
class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {
let popSound = Bundle.main.url(forResource: "Pop", withExtension: "mp3")
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
do {
audioPlayer = try AVAudioPlayer(contentsOf: popSound!)
audioPlayer.play()
} catch {
print("couldn't load sound file")
}
}
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer = AVAudioPlayer()
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.
}
#IBAction func button1Action(sender: AnyObject) {
let CatSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Meow-sounds", ofType: "mp3")!)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: CatSound)
audioPlayer.prepareToPlay()
} catch {
print("Problem in getting File")
}
audioPlayer.play()
}
}
In Swift 4
This worked for me try it out.
import UIKit
import AVFoundation
class ViewController: UIViewController, AVAudioPlayerDelegate{
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func notePressed(_ sender: UIButton) {
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "note1", ofType: "wav")!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
}catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
}
In Swift 3:
import UIKit
import AVFoundation
class QuestionView: UIViewController {
var btnButton = UIButton()
var player = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
btnButton.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
btnButton.backgroundColor = UIColor.blue
btnButton.addTarget(self, action: #selector(ButtonSound), for: .touchUpInside)
}
func ButtonSound() {
do {
// make sure to add this sound to your project
let audioPath = Bundle.main.path(forResource: "Click", ofType: "mp3")
try player = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath!) as URL)
} catch {
print("Error !")
}
player.play()
}
}
If you just want a click effect, the code below will work.
The bird file must be in xcode.
self.run(SKAction.playSoundFileNamed("Bird.mp3", waitForCompletion:false))