Get metadata from mp3 file with URL (swift) - ios

I'm new in swift and i would like to get data from a mp3 file located on a server, ( i used an URL, exemple : http://myserver.eu/file.mp3 ).
i used some tuto, like http://geekyviney.blogspot.com/2015/02/extracting-data-like-thumbnail-images.html ( it's working with a local file and i'm trying to make it work with a file from an url)
i got a exception :
Thread 1: EXC_BAD_INSTRUCTION(code=EXC_I1386_INVOP, subcode=0x0
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
I suppose that pathForResource is only for local file ? thanks for your help
var filePath = NSBundle.mainBundle().pathForResource("http://servername.eu/filename", ofType: "mp3")
var fileUrl = NSURL(fileURLWithPath: filePath!)
var asset = AVAsset.assetWithURL(fileUrl) as AVAsset

You're right, pathForResource is used to access files locally in the application bundle.
To load data from URLs with http scheme use this syntax
let urlString = "http://servername/filename"
let serverURL = NSURL(string: urlString)!
if let asset = AVAsset.assetWithURL(serverURL) as? AVAsset {
// do something with the asset
}

Swift 3 version:
let urlString = "http://servername/filename"
if let serverURL = URL(string: urlString) {
let asset = AVAsset(url: serverURL)
// do something with the asset
}
Ow and don't forget to add the correct import
import AVFoundation

Related

How to access the Video files, which are present in iOS Files App using AVPlayer in iOS swift?

I am trying to access the access the video files which are present in the iOS Files App. Trying to play videos using AVPlayer
I am able to access the videos but after some time when I try to access the same video I am getting the error from the AVPlayer.
let filemgr = FileManager.default
let docsDirURL = try! filemgr.url(for: .documentDirectory,
in: .userDomainMask, appropriateFor: nil, create: true)
let lastComp = docsDirURL.lastPathComponent
let pathy = "\(docsDirURL)"
if let urls = lap.videoURLs {
self.lap = lap
for url in urls {
let urlComps = "\(url)".components(separatedBy: "/")
var urlpath = ""
for (index, element) in urlComps.enumerated() {
if index > 9{
urlpath += element + "/"
}
}
print(urlpath)
var pathz = pathy.replacingOccurrences(of: lastComp, with: urlpath)
pathz = String(pathz.dropLast(2))
print(pathz)
let finalURL = NSURL(string: pathz)
// let playerItem = AVPlayerItem(url: url as URL)
let playerItem = AVPlayerItem(url: finalURL! as URL)
playerItem.addObserver(self, forKeyPath: "status", options: .new,
context: &itemStatusContext)
self.playerItems.append(playerItem)
if self.queuePlayer == nil {
self.queuePlayer = AVPlayer(playerItem: playerItem)
}
}
}
I expect to play videos normally as before but I can only access it for some time like one minute and then after I received an error.
Optional(Error Domain=NSURLErrorDomain Code=-1100 "The requested URL was not found on this server." UserInfo={NSLocalizedDescription=The requested URL was not found on this server., NSUnderlyingError=0x283368f90 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}) and URLS: [<AVPlayerItem: 0x283c1d4a0, asset = <AVURLAsset: 0x2878f41c0, URL = file:///var/mobile/Containers/Data/Application/0CE62F51-77E0-4630-A3C4-1CE615ACCD26/tmp/uk.co.racelogic.Circuit-Tools-for-iOS-Inbox/VBOX0005_0001.mp4>>, <AVPlayerItem: 0x283c1d850, asset = <AVURLAsset: 0x2878f5520, URL = file:///var/mobile/Containers/Data/Application/0CE62F51-77E0-4630-A3C4-1CE615ACCD26/tmp/uk.co.racelogic.Circuit-Tools-for-iOS-Inbox/VBOX0005_0002.mp4>>]
So as stated in error "No such file or directory" a file is absent. Regarding full path it stored inside temporary folder. Probably you imported these files via UIDocumentPickerViewController or similar component. You must copy provided file immediately (synchronously) in same code block where you get the URL to some local storage to avoid this situation.

Using AVAudioPlayer with Dynamic URL in Swift 3 causing Thread Errors

I am new to Swift and making an audio app using AVAudioPlayer. I am using a remote URL mp3 file for the audio, and this works when it's static.
For my use case, I want to pull a URL for an mp3 file from a JSON array and then pass it into the AVAudioPlayer to run.
If I move the AVAudioPlayer block into the ViewDidLoad and make the mp3 file a static URL, it will run fine.
Then, when I move this code into my block that extracts an mp3 url from JSON, I can print the URL successfully. But when I pass it into my audio player, problems arise. Here's the code.
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://www.example.com/example.json")
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
let json: Any?
do{
json = try JSONSerialization.jsonObject(with: data, options: [])
}
catch{
return
}
guard let data_list = json as? [[String:Any]] else {
return
}
if let foo = data_list.first(where: {$0["episode"] as? String == "Example Preview"}) {
self.audiotest = (foo["audio"] as? String)!
print(self.audiotest) // this prints
// where i'm passing it into the audio player
if let audioUrl = URL(string: self.audiotest) {
// then lets create your document folder url
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// lets create your destination file url
let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)
//let url = Bundle.main.url(forResource: destinationUrl, withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: destinationUrl)
} catch let error {
print(error.localizedDescription)
}
} // end player
// ....
Specifically, I get an error Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value when clicking a play button IBAction that is connected to the audio player. Finally, that action function looks like this:
#IBAction func playPod(_ sender: Any) {
audioPlayer.play()
}
Do you know where I'm going wrong? I'm confused as to why I can't print the URL and also get a response that the URL is nil in the same block, but maybe that's an asynchronous thing.
The problem is that you didn't save the mp3 file to documents and trying to play it
this line
audioPlayer = try AVAudioPlayer(contentsOf: destinationUrl)
assumes that there is a saved mp3 file in that path , but acutally there is no files you appended the audio extension on the fly
besides for steaming audio from a remote server, use AVPlayer instead of AVAudioPLayer.
AVPlayer Documentation
Also try this with urls parsed from json
var urlStr = (foo["audio"] as? String)!
self.audiotest = urlStr.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

Swift: can't get array of images from url of folder?

Alright, Im fairly new to the url locating process (I always just use explicit names) and everyone is new to MSMessageStickers. However. I need to pull in an array of image urls to use as MSStickers from a folder of images I have copied into my MessagesExtension target in my project here (it is starterPack):
It may the Swift 3 syntax screwing this up or something else, but I CANT find any way to just get the right url of this folder and get all the images inside of it. The following is successful in making stickers out of PNGS with specific names:
for i in (1..<2) {
if let url = Bundle.main.url(forResource: "test\(i)", withExtension: "png") {
do {
//let sticker = try MSSticker(contentsOfFileURL: url, localizedDescription: "")
let sticker = try MSSticker(contentsOfFileURL: url, localizedDescription: "")
//print("SUCCESS", url)
stickers.append(sticker)
} catch {
print(error)
}
}
}
And I have adapted the following to Swift 3 from similar question How to get array of UIImage, from folder, in Swift? :
if let path = NSBundle.mainBundle().resourcePath {
let imagePath = path + "/images"
let url = NSURL(fileURLWithPath: imagePath)
let fileManager = NSFileManager.defaultManager()
let properties = [NSURLLocalizedNameKey,
NSURLCreationDateKey, NSURLLocalizedTypeDescriptionKey]
do {
let imageURLs = try fileManager.contentsOfDirectoryAtURL(url, includingPropertiesForKeys: properties, options:NSDirectoryEnumerationOptions.SkipsHiddenFiles)
print("image URLs: \(imageURLs)")
// Create image from URL
var myImage = UIImage(data: NSData(contentsOfURL: imageURLs[0])!)
} catch let error1 as NSError {
print(error1.description)
}
}
But because the folder is not technically in my project folder but rather in the messagesExtension folder as you can see, I think that is why it cant find it.
I need to bring in and get the url of all the images contained in my stickers folder. What am I doing wrong?

Type 'URL' has no member 'fileURL' - Swift 3

In Swift 2, I had used the following code:
let path = NSBundle.mainBundle().pathForResource("Document", ofType: "pdf")!
let url = NSURL.fileURLWithPath(path)
webView.loadRequest(NSURLRequest(URL: url))
Now, using Xcode 8 and Swift 3, Xcode automatically translated it to:
let path = Bundle.main.pathForResource("Translation", ofType: "pdf")!
let url = URL.fileURL(withPath: path)
webView.loadRequest(URLRequest(url: url))
On the second line, with the declaration of url, Xcode gives me the following error:
Type 'URL' has no member 'fileURL'
How can I fix this error? Thanks!
The URL struct in Swift 3 has an initializer for that
let url = URL(fileURLWithPath: path)
If you do not use path later, you can write something like this:
let url = Bundle.main.urlForResource("Translation", withExtension: "pdf")

Error Uploading Video to Parse

I am receiving an error when I attempt to upload my video to Parse. The error is client side and is that the variable path is found nil. Perhaps I am declaring this wrong or using pathForResource wrong but I appreciate any help that I would be able to get.
func Upload() {
var path = NSBundle.mainBundle().pathForResource("big_buck_bunny_720p_2mb.mp4", ofType: "mp4")
var videodata: NSData?
videodata = NSData.dataWithContentsOfMappedFile(path!) as? NSData
let file = PFFile(name:"capturedVideo", data:videodata!)
file!.saveInBackground()
}

Resources