this is my swift class
import Foundation
import AVFoundation
class MusicPlayer{
static let shared = MusicPlayer()
var audioPlayer: AVAudioPlayer?
func startBackgroundMusic(backgroundMusicFileName: String) {
if let bundle = Bundle.main.path(forResource: backgroundMusicFileName, ofType: "mp3") {
let backgroundMusic = NSURL(fileURLWithPath: bundle)
do {
audioPlayer = try AVAudioPlayer(contentsOf:backgroundMusic as URL)
guard let audioPlayer = audioPlayer else { return }
audioPlayer.numberOfLoops = -1
audioPlayer.volume = 1.0
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch {
print(error)
}
}
}
func stopBackgroundMusic() {
guard let audioPlayer = audioPlayer else { return }
audioPlayer.stop()
}
}
And, here is my code for the Controller class
func downloadUsingAlamofire() {
let audioUrl = URL(string:"https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3")
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
Alamofire.download(
audioUrl!,
method: .get,
parameters: nil,
encoding: URLEncoding.default,
headers: nil,
to: destination).downloadProgress(closure: { (progress) in
}).response(completionHandler: { (DefaultDownloadResponse) in
let imageURL = fetchPathinDirectory(filepath:audioUrl!.lastPathComponent)
MusicPlayer.shared.startBackgroundMusic(backgroundMusicFileName: imageURL.path)
})
}
As explain in comment ;
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
That means the file is downloaded in documents directory of your app. But when you read the file :
if let bundle = Bundle.main.path(forResource: backgroundMusicFileName, ofType: "mp3") {
let backgroundMusic = NSURL(fileURLWithPath: bundle)
You read for file in application bundle which is where your application and its ressources (storyboard, xib, …) are installed.
You must read the file from documents directory. Something like :
var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let downloadedFileUrl = documentsURL.appendingPathComponent(backgroundMusicFileName)
Related
I try to save given video locally after then I need those saved videos for playing video in my app. I can't handle the saving video. Here is my saving try :
func saveVideoDocumentDirectory(url : URL){
let fileManager = FileManager.default
let paths = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent(".MOV")
do{
let videoData = try Data(contentsOf: url)
fileManager.createFile(atPath: paths as String, contents: videoData, attributes: nil)
}catch{
//
}
}
here is the get file try
func getVideo(){
let fileManager = FileManager.default
let videoPAth = (self.getDirectoryPath() as NSString).appendingPathComponent(".MOV")
if fileManager.fileExists(atPath: videoPAth){
print(videoPAth)
play(url: URL(string: videoPAth)!)
}else{
print("No Video")
}
}
here is my play video func :
func play(url : URL)
{
let player = AVPlayer(url: url)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
present(playerViewController, animated: true)
{
playerViewController.player!.play()
}
}
Instead of Filemanager.createFile(), try using write instead.
let videoData = try Data(contentsOf: url)
try videoData.write(to: paths, options: .atomic)
Also, I recommend creating a folder first (from this answer).
extension URL {
static func createFolder(folderName: String) -> URL? {
let fileManager = FileManager.default
// Get document directory for device, this should succeed
if let documentDirectory = fileManager.urls(for: .documentDirectory,
in: .userDomainMask).first {
// Construct a URL with desired folder name
let folderURL = documentDirectory.appendingPathComponent(folderName)
// If folder URL does not exist, create it
if !fileManager.fileExists(atPath: folderURL.path) {
do {
// Attempt to create folder
try fileManager.createDirectory(atPath: folderURL.path,
withIntermediateDirectories: true,
attributes: nil)
} catch {
// Creation failed. Print error & return nil
print(error.localizedDescription)
return nil
}
}
// Folder either exists, or was created. Return URL
return folderURL
}
// Will only be called if document directory not found
return nil
}
}
Then, you can save like this:
guard let folderURL = URL.createFolder(folderName: "StoredVideos") else {
print("Can't create url")
return
}
let permanentFileURL = folderURL.appendingPathComponent(nameOfYourFile).appendingPathExtension("MOV")
let videoData = try Data(contentsOf: url)
try videoData.write(to: permanentFileURL, options: .atomic)
This will save you the hassle of NSSearchPathForDirectoriesInDomains.
I was trying to read a file xyz.m4a and trying to play it. But I have an error
2018-04-24 18:11:20.010927+0530 Demo[10807:690526] NSURLConnection finished with error - code -1002
2018-04-24 18:11:20.327008+0530 Demo[10807:688427] CFURLCopyResourcePropertyForKey failed because it was passed an URL which has no scheme
Error: The file “xyz.m4a” couldn’t be opened.
Here is my code:
func audioMethod() {
let fileName = "xyz.m4a",
audioFile = getDocumentsURL().appendingPathComponent(fileName)
if !FileManager.default.fileExists(atPath: audioFile.path) {
print("We have no file !!!!!")
}
do {
let audioData = try Data(contentsOf: audioFile)
if audioPlayer == nil {
audioPlayer = try AVAudioPlayer.init(data: audioData, fileTypeHint: "m4a")
}
audioPlayer?.play()
} catch let error {
print("Error: " + error.localizedDescription)
}
}
func getDocumentsURL() -> URL {
let urlStr = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let url = URL(string: urlStr!)
return url!
}
If I pass that URL direct in AVAudioPlayer as AVAudioPlayer.init(contentsOf: audioFile) then it works fine.
I have tried everything. But nothing works. Please let me know what is wrong with my code.
if let path = Bundle.main.path(forResource: "videoplayback", ofType: "mp4"){
let video = AVPlayer(url: URL(fileURLWithPath:path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
present(videoPlayer,animated: true,completion: {
video.play()
})
}
Add that Video in File Explorer
Then try with above code
I am using ARKit for my application and I try to dynamically load .scn files from my web-server(URL)
Here is a part of my code
let urlString = "https://da5645f1.ngrok.io/mug.scn"
let url = URL.init(string: urlString)
let request = URLRequest(url: url!)
let session = URLSession.shared
let downloadTask = session.downloadTask(with: request,
completionHandler: { (location:URL?, response:URLResponse?, error:Error?)
-> Void in
print("location:\(String(describing: location))")
let locationPath = location!.path
let documents:String = NSHomeDirectory() + "/Documents/mug.scn"
ls = NSHomeDirectory() + "/Documents"
let fileManager = FileManager.default
if (fileManager.fileExists(atPath: documents)){
try! fileManager.removeItem(atPath: documents)
}
try! fileManager.moveItem(atPath: locationPath, toPath: documents)
print("new location:\(documents)")
let node = SCNNode()
let scene = SCNScene(named:"mug.scn", inDirectory: ls)
let nodess = scene?.rootNode.childNode(withName: "Mug", recursively: true)
node.addChildNode(nodess!)
let nodeArray = scene!.rootNode.childNodes
for childNode in nodeArray {
node.addChildNode(childNode as SCNNode)
}
self.addChildNode(node)
self.modelLoaded = true
})
downloadTask.resume()
Nslog:
location:Optional(file:///private/var/mobile/Containers/Data/Application/A1B996D7-ABE9-4000-91DB-2370076198D5/tmp/CFNetworkDownload_duDlwf.tmp)
new location:/var/mobile/Containers/Data/Application/A1B996D7-ABE9-4000-91DB-2370076198D5/Documents/mug.scn
.scn file downloading with the above mentioned(new location) file path.. but when i try to use this downloaded file in SCNScene
let scene = SCNScene(named:"mug.scn", inDirectory: ls)
always scene value is nil.
error
Thread 4: Fatal error: Unexpectedly found nil while unwrapping an Optional value
how to resolve this issues. Thank you
About init?(named: String), the documentation says:
Loads a scene from a file with the specified name in the app’s main bundle
since you don't have such file inside the main bundle (is coming from a download), you may try with the following constructor:
init(url: URL, options: [SCNSceneSource.LoadingOption : Any]? = nil)
so your code might be:
do {
let documents = "yourValidPath"
let scene = try SCNScene(url: URL(fileURLWithPath: documents), options: nil)
} catch {}
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let pathToObject = documentDirectory + "ship.scn"
let fileUrl = URL(fileURLWithPath: pathToObject)
guard let cshipScene = try? SCNScene(url: fileUrl, options: nil) else { return }
let shipNode = SCNNode()
let shipSceneChildNodes = shipScene.rootNode.childNodes
for childNode in shipSceneChildNodes {
shipNode.addChildNode(childNode)
}
node.addChildNode(shipNode)
I have started to learn ios development and am stuck in one place. My code to play mp3 file is
var bombSoundEffect: AVAudioPlayer!
let path = Bundle.main.path(forResource: "faded", ofType:"mp3")!
let url = NSURL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: (url as NSURL) as URL)
bombSoundEffect.play()
} catch {
print("couldn't load file :(")
}
if bombSoundEffect != nil {
bombSoundEffect.stop()
bombSoundEffect = nil
}
However, when I click on the button, my file doesn't play. The song is playing perfectly normally.
Try with the follow code:
var bombSoundEffect: AVAudioPlayer?
func playAudio() {
let url = Bundle.main.url(forResource: "faded", withExtension: "mp3")!
do {
bombSoundEffect = try AVAudioPlayer(contentsOf: url)
guard let bombSound = bombSoundEffect else { return }
bombSound.prepareToPlay()
bombSound.play()
} catch let error {
print(error.localizedDescription)
}
}
There's lots wrong with your code, but it's a sunny day, so try something like this…
func playSound() {
guard let url = Bundle.main.url(forResource: "faded", withExtension: "mp3") else { return }
let bombSoundEffect = try? AVAudioPlayer(contentsOf: url)
bombSoundEffect?.play()
}
I'm using this code for user to download a video to a temporary DIrectory:
#IBAction func startDownload(_ sender: UIButton) {
let videoImageUrl = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"
DispatchQueue.global(qos: .default).async {
let url = NSURL(string: videoImageUrl);
let urlData = NSData(contentsOf: url! as URL);
if(urlData != nil)
{
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0];
let filePath="\(documentsPath)/tempFile.mp4";
DispatchQueue.main.async {
urlData?.write(toFile: filePath, atomically: true);
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: NSURL(fileURLWithPath: filePath) as URL)
}) { completed, error in
if completed {
print("Video is saved!")
}
}
}
}
}
}
Otherwise, when clicking on the button download, the App get frozen after sometime.
I'd like ideally the file to be save 'temporary' into the App, not to appear int he photolibrary of the Mobile.
How is this possible ?
Then, IS there a way to call back the file from that temporary directory ?
How this can be achieve in the process ?
Thanks a lot guys !
---- EDIT ---
#IBAction func startDownload(_ sender: UIButton) {
let urlString = "\(posts[selectedIndexPath].link)"
DispatchQueue.global(qos: .default).async(execute: {
//All stuff here
print("downloadVideo");
let url=NSURL(string: urlString);
let urlData=NSData(contentsOf: url! as URL);
if((urlData) != nil)
{
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let fileName = urlString as NSString;
let filePath="\(documentsPath)/\(fileName.lastPathComponent)";
DispatchQueue.main.async(execute: { () -> Void in
print(filePath)
urlData?.write(toFile: filePath, atomically: true);
print("video Saved to document directory of app");
})
}
})
}
#IBAction func playDownload(_ sender: UIButton) {
let urlString = "\(posts[selectedIndexPath].link)"
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let fileName = urlString as NSString;
let filePath="\(documentsPath)/\(fileName.lastPathComponent)";
let fileURL = NSURL.init(fileURLWithPath: filePath)
let request = NSURLRequest.init(url: fileURL as URL)
print(fireURL)
print("video called from document directory of app");
// creating webView to play video, you can use player as per requirement
let webView = UIWebView.init(frame: CGRect.init(x: 0, y: 0, width: 320, height: 320))
webView.loadRequest(request as URLRequest)
self.view.addSubview(webView)
}
in the console this is what I get:
/var/mobile/Containers/Data/Application/0A2D4FC0-F001-4711-916C-86C34CC5B71A/Documents/Cabin_Mono_4K_60fps.mp4?alt=media&token=32faeba5-3d9b-4090-9340-3e28986db5fa
video Saved to document directory of app
file:///var/mobile/Containers/Data/Application/0A2D4FC0-F001-4711-916C-86C34CC5B71A/DocumentsCabin_Mono_4K_60fps.mp4%3Falt=media&token=32faeba5-3d9b-4090-9340-3e28986db5fa
Below method will save video to documents directory(specific for app) :
func downloadVideo()
{
let urlString = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"
DispatchQueue.global(qos: .default).async(execute: {
//All stuff here
print("downloadVideo");
let url=NSURL(string: urlString);
let urlData=NSData(contentsOf: url! as URL);
if((urlData) != nil)
{
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let fileName = urlString as NSString;
let filePath="\(documentsPath)/\(fileName.lastPathComponent)";
let fileExists = FileManager().fileExists(atPath: filePath)
if(fileExists){
// File is already downloaded
}
else{
//download
DispatchQueue.main.async(execute: { () -> Void in
print(filePath)
urlData?.write(toFile: filePath, atomically: true);
print("videoSaved");
})
}
}
})
}
Wherever you want to get video, you can read it from same document directory as below:
func GetVideo() {
let urlString = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let fileName = urlString as NSString;
let filePath="\(documentsPath)/\(fileName.lastPathComponent)";
let fileURL = NSURL.init(fileURLWithPath: filePath)
let request = NSURLRequest.init(url: fileURL as URL)
// creating webView to play video, you can use player as per requirement
let webView = UIWebView.init(frame: CGRect.init(x: 0, y: 0, width: 320, height: 320))
webView.loadRequest(request as URLRequest)
self.view.addSubview(webView)
}