HLS && .m3u8in iOS 10 - ios

I am trying to get a .m3u8 video stream to play within my app. I am programming in Swift for iOS 9 and 10.
Here is what I got so far:
import UIKit
import AVKit
import AVFoundation
import DynamicBlurView
class VideoPlayerViewController: AVPlayerViewController {
var urlString: String!
let blurView = DynamicBlurView()
override func viewDidLoad() {
super.viewDidLoad()
streamVideo()
}
func streamVideo() {
blurView.frame = view.frame
UIView.showProgressView(on: view, blurView: blurView)
let url = URL(string: urlString!)
let item = AVPlayerItem(url: url!)
player = AVPlayer(playerItem: item)
UIView.hideProgressView(on: view, blurView: blurView)
player?.play()
}
}
This should be simple, but I am getting errors and crashes all over the place.
This is the error I am getting:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could
not be completed" UserInfo={NSLocalizedDescription=The operation could
not be completed, NSUnderlyingError=0x7b5b6810 {Error
Domain=NSOSStatusErrorDomain Code=-12782 "(null)"},
NSLocalizedFailureReason=An unknown error occurred (-12782)}
Please help me!
EDIT:
Tried this suggestion with no luck. the app still crashes. The crash brings me to the AppDelegate if that info helps anyone.
import UIKit
import AVKit
import AVFoundation
import DynamicBlurView
class VideoPlayerViewController: AVPlayerViewController {
var urlString: String!
let blurView = DynamicBlurView()
override func viewDidLoad() {
super.viewDidLoad()
streamVideo()
}
func streamVideo() {
blurView.frame = view.frame
UIView.showProgressView(on: view, blurView: blurView)
let sampleURL = "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8"
guard let url = URL(string: sampleURL) else { return }
let playerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: playerItem)
player?.play()
UIView.hideProgressView(on: view, blurView: blurView)
}
}

You should make sure your URL provides a valid HLS source.
import UIKit
import AVKit
import AVFoundation
class myAVPlayerViewController: AVPlayerViewController {
override func viewDidLoad() {
super.viewDidLoad()
// custom HLS
// http://localhost:3000/assets/videos/iframe_index.m3u8
// apple HLS example
// https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8
guard let url = URL(string: "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8") else { return }
let playerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: playerItem)
player?.play()
}
}
Also, remember to set the NSAllowsArbitraryLoads key to YES under NSAppTransportSecurity dictionary in your Info.plist.

Related

How to play audio in simulator?

import UIKit
import SwiftUI
import AVKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func keyPressed(_ sender: UIButton) {
playSound(soundName: sender.currentTitle!)
}
func playSound(soundName: String) {
let url = Bundle.main.url(forResource: soundName, withExtension: "wav")
let player = AVPlayer.init(url: url!)
player.play()
print(url!)
}
}
file:///Users/user/Library/Developer/CoreSimulator/Devices/C3333006-1A90-4B12-A9F6-E04B3603334C/data/Containers/Bundle/Application/265FB456-9524-44DY-B669-D67ACB7F444C/Xylophone.app/D.wav
I'm trying to play sound, which are already in the package folder, but failed to do so in simulator, can't play any sound even if unmute and increase sound volume of the simulator and my Mac.
I use this code and it works:
let jingleURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "jingle", ofType: ".mp3")!)
let jingleAVPlayer = AVPlayer.init(url: jingleURL)
jingleAVPlayer.play()
The filename is jingle.mp3 and is added in Xcode.
I hope this helps you out ;)

AvPlayer is unable to play sound in device

My code perfectly works fine in the simulator and it streams the url without any issue. But when plugged to the actual device it doesnt play the audio. My code as bellow
var playerItem: AVPlayerItem?
var player: AVPlayer?
func initPlayer() {
let url:URL = URL(string:"https://storage.googleapis.com/purelightdatabucket/samples%2F60-Energy%20UPLIFT.mp3")!
self.playerItem = AVPlayerItem(url: url)
self.player=AVPlayer(playerItem: self.playerItem!)
let playerLayer=AVPlayerLayer(player: self.player!)
playerLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 50) // actually this player layer is not visible
self.view.layer.addSublayer(playerLayer)
}
Put this code in didFinishLaunchingWithOptions
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
you can use this too :
You need to add AVKit & AVFoundation to your frameworks path and import them :
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
var player = AVPlayer()
override func viewDidLoad() {
super.viewDidLoad()
let playerItem = AVPlayerItem(url: URL(string: "https://storage.googleapis.com/purelightdatabucket/samples%2F60-Energy%20UPLIFT.mp3")!)
player = AVPlayer(playerItem: playerItem)
player.play()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

AVPlayer playback with Swift 2.0

I'm having issues with playing back a video. All I want is for the video to playback after the launch image has been displayed. I followed this (https://www.youtube.com/watch?v=iYATp9--VIM) tutorial but when I simulated I received a blank screen.
Here is the code:
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet var videoView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.setupView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupView() {
let path = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("streetview", ofType: "mov")!)
let player = AVPlayer(URL:path)
let newLayer = AVPlayerLayer(player: player)
newLayer.frame = self.videoView.frame
self.videoView.layer.addSublayer(newLayer)
newLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
player.play()
}
}
Please help me if you can!
If you're just getting a blank black screen, it would generally point to an issue with the source of the video. I'd check that you're spelling the name of your file correctly and that it definitely is a .mov file.
I use this code to launch the AVPlayer and play my video. It plays a video from a URL from the internet. I have it inside my button function so it happens when the user presses the play button I have:
let videoURL = NSURL(string: "YOUR URL") {
let player = AVPlayer(URL: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.presentViewController(playerViewController, animated: true) {
playerViewController.player!.play()
}
I can confirm this works for me in Swift 2.0

Implementing video view in the Storyboard

I want to build simple video app thats views a video form youtube links thats users add.
I didn't find "VideoView" I mean If image view is for image what is UIView for videos.
There is no object in the original library that performs video viewing function. But you can import the MediaPlayer framework in your project and add it programmatically.
Here is a Swift example
import MediaPlayer
class Step1ViewController: UIViewController {
var moviePlayer: MPMoviePlayerController?
override func viewDidLoad() {
super.viewDidLoad()
playVideo()
}
func playVideo() {
let videoView = UIView(frame: CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.bounds.width, self.view.bounds.height))
let pathToEx1 = NSBundle.mainBundle().pathForResource("myVideoFile", ofType: "mp4")
let pathURL = NSURL.fileURLWithPath(pathToEx1!)
moviePlayer = MPMoviePlayerController(contentURL: pathURL)
if let player = moviePlayer {
player.view.frame = videoView.bounds
player.prepareToPlay()
player.scalingMode = .AspectFill
videoView.addSubview(player.view)
}
self.view.addSubview(videoView)
}
}
As for further customisations and app notifications it has a bunch of in-build possibilities. So check it out.
To play video apple has provided MPMovieViewController
see this https://developer.apple.com/library/prerelease/ios/documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/index.html
and this
http://www.brianjcoleman.com/tutorial-play-video-swift/
In youtube Video case we got embedded links are used so for that you will get help from this https://github.com/gilesvangruisen/Swift-YouTube-Player
import AVFoundation
import AVKit
class ViewController: UIViewController {
var player = AVPlayer()
var playerController = AVPlayerViewController()
func playVideo() {
let videoURL = NSURL(string: videoUrl)
player = AVPlayer(url: videoURL! as URL)
let playerController = AVPlayerViewController()
playerController.player = player
self.addChildViewController(playerController)
// Add your view Frame
playerController.view.frame = self.view.frame
// Add subview in your view
self.view.addSubview(playerController.view)
player.play()
}
func stopVideo() {
player.pause()
}
}
In Xcode 10 (with a bit less code):
In the interface builder (Storyboard), add "AVKit Player View Controller"
Create a View Controller that derives from AVPlayerViewController:
import UIKit
import AVKit
class VideoPlayerViewController: AVPlayerViewController {
override func viewDidLoad() {
super.viewDidLoad()
let videoURL = Bundle.main.url(forResource: "video", withExtension: "mp4")!
self.player = AVPlayer(url: videoURL)
}
override func viewDidAppear(_ animated: Bool) {
self.player?.play()
}
}
Don't forget to connect this custom class in the storyboard's identity inspector :)
Note: this example uses video URL pointing to a bundle's resource.

Remote mp3 file taking a lot of time to play in swift ios

i'm in trouble. i want to play a remote mp3 file in my app. but mp3 file taking a lot of time (approx 5-6 minute) to play. why ?
Anyone can suggest what should i do ?
import UIKit
import AVFoundation
class TestViewController: UIViewController, AVAudioPlayerDelegate {
var player:AVAudioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func play(sender: AnyObject) {
let url = "http://www.example.com/song.mp3"
let fileURL = NSURL(string: url.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()))
let soundData = NSData.dataWithContentsOfURL(fileURL, options: nil, error: nil)
var error: NSError?
self.player = AVAudioPlayer(data: soundData, error: &error)
if player == nil
{
if let e = error
{
println(e.localizedDescription)
}
}
player.volume = 1.0
player.delegate = self
player.prepareToPlay()
player.play()
}
}
Thanks in advance.
Use AVPlayer instead of AVAudioPlayer for streaming audio. It can be as simple as this --
let urlString = "http://www.example.com/song.mp3"
let url = NSURL(string: urlString)
var avPlayer = AVPlayer(URL: url)
avPlayer.play()
You can also set an observer on the AVPlayer.status property to manage its changing status. Check out:
https://stackoverflow.com/a/13156942/2484290 (objective c)
And of course the AVPlayer docs are here:
https://developer.apple.com/LIBRARY/ios/documentation/AVFoundation/Reference/AVPlayer_Class/index.html#//apple_ref/occ/cl/AVPlayer
Try using my example where you can work with the cache and the remote file.
player.automaticallyWaitsToMinimizeStalling = false // by default true, so It is important to solve your problem in a mp3 file remotely
This feature is available iOS 10.0+
var player: AVPlayer!
enum AudioType: String {
case remote
case cache
}
#IBAction func remotePressed(_ sender: Any) {
playAudio(type: .remote, fileURL: "http://www.example.com/song.mp3")
}
#IBAction func cachePressed(_ sender: Any) {
if let fileURL = Bundle.main.path(forResource: "jordan", ofType: "mp3") {
playAudio(type: .cache, fileURL: fileURL)
}
}
private func playAudio(type: AudioType, fileURL: String) {
let url = type == .cache ? URL.init(fileURLWithPath: fileURL) : URL.init(string: fileURL)
let playerItem: AVPlayerItem = AVPlayerItem(url: url!)
player = AVPlayer(playerItem: playerItem)
player.automaticallyWaitsToMinimizeStalling = false//It's important
player.play()
}
Its may be late.
Yes. what #lemon lime pomelo has said. you should use AVPlayer instead of AVAudioPlayer.
Also you can use MediaPlayer.
import UIKit
import MediaPlayer
#IBAction func playSong(sender: AnyObject) {
print("Song")
self.playAudio("yourAudioURL.mp3")
}
func playAudio(URL:String){
let movieurl:NSURL? = NSURL(string: "\(URL)")
if movieurl != nil {
self.movie = MPMoviePlayerViewController(contentURL: movieurl!)
}
if self.movie != nil {
self.presentViewController(self.movie!, animated: true, completion: nil)
self.movie?.moviePlayer.play()
}
}
It is slow because your program downloads all the song before starting playing

Resources