Issue getting URL from String for use with AVPlayer - ios

I have constructed a string that is the directory path and file name of file i would like to play in AVPlayer. But I'm struggling to convert this to a URL.
let dataPath = ("\(packDirectory)/").appending((cachedFilePath as NSString).lastPathComponent)
print(dataPath)
audioFileURL = dataPath
self.audioPlayerItem = AVPlayerItem(url: NSURL.fileURL(withPath: audioFileURL) as URL)
print(self.audioPlayerItem)
print(dataPath) returns:
/Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/788085B9-242E-46E7-9644-6A3BF9D515DB/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%20Name%20of%20the%20Wind%2029-92.mp3
print(self.audioPlayerItem) returns: - the url part:
URL = file:///Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/788085B9-242E-46E7-9644-6A3BF9D515DB/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%2520Name%2520of%2520the%2520Wind%252029-92.mp3
I don't really understand this stuff but i can see 2 issues with this.
1) file:// : i have purposely removed this from my "dataPath" as when using file manager it cant find anything with this prefix. i have used this code for that:
userDirectory.removeSubrange(userDirectory.startIndex..<userDirectory.index(userDirectory.startIndex, offsetBy: 7))
let packDirectory = userDirectory.appending("Next-\(self.selectedPack!)")
2) the encoding in the .lastComponent has been changed from %20 to %2520
Very confused !
---- EDIT ----
let urlItem = AVPlayerItem(url: URL(fileURLWithPath: audioFileURL))
if let urlAsset = urlItem.asset as? AVURLAsset {
self.audioPlayerItem = AVPlayerItem(url: NSURL(string: urlAsset.url.path) as! URL)
print(urlAsset.url.path)
}
print(self.audioPlayerItem!)
print(urlAsset.url.path) returns :
/Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/BAD0194A-8CDD-44CE-BF99-B9FF35E23BCA/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%20Name%20of%20the%20Wind%2029-92.mp3
print(self.audioPlayerItem!) returns:
<AVPlayerItem: 0x7bf81b60, asset = <AVURLAsset: 0x7bf87c70, URL = /Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Applicati ... 9-92.mp3>>
self.audioPlayerItem = AVPlayerItem(url: URL(fileURLWithPath: urlAsset.url.path))
prints:
file:///Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/7C212656-8E1C-44C8-9951-4444FB5EF853/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%2520Name%2520of%2520the%2520Wind%252029-92.mp3
even using something like:
let asset = AVAsset(url: URL(string: urlAsset.url.path)!) as AVAsset
results in losing some of the url:
<AVPlayerItem: 0x79716ed0, asset = <AVURLAsset: 0x797185d0, URL = /Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Applicati ... 9-92.mp3>>
And nothing plays. So basically i think it won't play with the file:// prefix but when i plug in the string without it something cuts the path at the i in applications???

You can read about absoluteString and path of URL documentation.
For getting self.audioPlayerItem's URL with lacking of file:/// you can access asset of self.audioPlayerItem and get path of asset.url
let asset = self.audioPlayerItem?.currentItem?.asset
if asset == nil {
return nil
}
if let urlAsset = asset as? AVURLAsset {
return urlAsset.url.path
}
Edited: if you use local file, init URL with URL.init(fileURLWithPath: ) instead of URL.init(string: ). If you use URL.init(string: ), string will be full path (contains file:///), not path.
That's ok, the decoding result is the same. Try to read reference A html space is showing as %2520 instead of %20
P/S: that snippet is just pseudo, please follow the idea from that snippet.

Related

File name that saved in document directory have space character

I want to download video file and save it in the document directory but when i try show that downloaded video, i can't create URL of that file.
i'm using this code for create path for save file. my file name have spacing : (mobileslider video.mp4), and i want to save this video with own name but i can't create url path that contain space. how can solve this problem?
if let url = URL(string:videoURL){
showVideoFromNib(nibURL:url)
}
when i try to remove space from videoURL, showVideoFromNib method called but don't show the video. and when use orginal url, showVideoFromNib method didn't call.
Edit 1:
i change destination path from :
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
to :
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let pathComponent = "pack\(self.packID)-\(selectRow + 1).mp4"
let directoryURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let folderPath: URL = directoryURL.appendingPathComponent("Downloads", isDirectory: true)
let fileURL: URL = folderPath.appendingPathComponent(pathComponent)
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
now i can create URL and my show video method call but video don't show.
this is my new sample path:
/Users/MyUser/Library/Developer/CoreSimulator/Devices/2C2B6A39-5426-4E2C-B25A-CF64817AF26F/data/Containers/Data/Application/5A1BB109-D452-4F03-8820-EE1120E07C3D/Documents/Downloads/pack7-2.mp4
this file exist in this path but video player don't show this.
I solve problem. i'm using
let path = destinationUrl.absoluteString
instead of
let path = destinationUrl.path

URL with added Anchor Tag Swift 4 Xcode 9

I try to add an anchor tag to local html file using this code:
let myAnchor ="#G"
let htmlPath = Bundle.main.path(forResource: "test", ofType: "html", inDirectory: "localWebsite", forLocalization:"")
let request = URLRequest(url: URL(fileURLWithPath: htmlPath! + myAnchor))
webview.load(request)
the answer is path/test.html%23G
so how I can convert to test.html#G ?
I don't know exactly what you want to achieve but you are speaking about encoding resp. decoding in your case. Your string is HTML encoded and you probably want to decode it. There are several answers for that already on this platform. One that would fit your needs is here: https://stackoverflow.com/a/39344394/1195661
You can construct an anchor tag relative to the filepath URL like this:
let baseURL = URL(fileURLWithPath: htmlPath)
if let url = URL(string: myAnchor, relativeTo: baseURL) {
print(url.absoluteURL)
// do your things
}

How to resolve: FileManager.fileExists returns incorrect false [duplicate]

How is it possible?
let exists = NSFileManager.defaultManager().fileExistsAtPath(path.absoluteString)
print("exists: \(exists)") //false
This is path.absoluteString
//file:///Users/kuna/Library/Developer/CoreSimulator/Devices/92BD140D-5C14-43C4-80D6-904BB9594ED6/data/Containers/Data/Application/5B818832-BB19-4047-A7F8-1487F36868D6/Documents/wishlists/68/147/128/IMG_0006.PNG
And you can see it is there where it should be:
What is going on?
(The code in this answer has been updated for Swift 3 and later.)
Apparently your path variable is a NSURL (describing a file path). To get the path as
a string, use the path property, not absoluteString:
let exists = FileManager.default.fileExists(atPath: path.path)
absoluteString returns the URL in a string format, including
the file: scheme etc.
Example:
let url = URL(fileURLWithPath: "/path/to/foo.txt")
// This is what you did:
print(url.absoluteString)
// Output: file:///path/to/foo.txt
// This is what you want:
print(url.path)
// Output: /path/to/foo.txt
If you want to check if a path exist,you should check path
let url = NSURL(string: "balabala")
let path = url?.path
//Check path

FileManager fileExists() always returns false (iOS 10, swift 3) [duplicate]

How is it possible?
let exists = NSFileManager.defaultManager().fileExistsAtPath(path.absoluteString)
print("exists: \(exists)") //false
This is path.absoluteString
//file:///Users/kuna/Library/Developer/CoreSimulator/Devices/92BD140D-5C14-43C4-80D6-904BB9594ED6/data/Containers/Data/Application/5B818832-BB19-4047-A7F8-1487F36868D6/Documents/wishlists/68/147/128/IMG_0006.PNG
And you can see it is there where it should be:
What is going on?
(The code in this answer has been updated for Swift 3 and later.)
Apparently your path variable is a NSURL (describing a file path). To get the path as
a string, use the path property, not absoluteString:
let exists = FileManager.default.fileExists(atPath: path.path)
absoluteString returns the URL in a string format, including
the file: scheme etc.
Example:
let url = URL(fileURLWithPath: "/path/to/foo.txt")
// This is what you did:
print(url.absoluteString)
// Output: file:///path/to/foo.txt
// This is what you want:
print(url.path)
// Output: /path/to/foo.txt
If you want to check if a path exist,you should check path
let url = NSURL(string: "balabala")
let path = url?.path
//Check path

AVAsset has 0 tracks even though video exists and plays fine from the Camera Roll: troubleshooting steps?

Our app lets users record and save videos to their Camera Roll. However, we can't seem to play back the videos in an AVPlayer even though the saved videos play back fine from the Camera Roll.
For some reason, a valid video file reports back as having 0 tracks.
Code:
func playPreview(videoUrl: NSURL) {
let asset = AVAsset.assetWithURL(videoUrl) as? AVAsset
println("\(asset!.tracks.count) tracks found for \(videoUrl)")
let playerItem = AVPlayerItem(asset: asset)
player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = CGRectMake(0, 0, 320, 320)
view.layer.addSublayer(playerLayer)
player.seekToTime(kCMTimeZero)
player.play()
}
The videoUrl we're testing is:
file:///var/mobile/Containers/Data/Application/F532DF34-371C-437E-A121-04C532349720/Documents/editedVideo-7325.mp4
The file exists and is 419498 bytes large as you can see from the code and output below.
Given that the file clearly has content, why are the tracks reporting back as 0? Besides checking the number of tracks, what else can we do to troubleshoot?
func listFiles() {
let allPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docsPath = allPaths[0] as! NSString
if let files = NSFileManager.defaultManager().contentsOfDirectoryAtPath(docsPath as String, error: nil) as? [String] {
println("Found \(files.count) file(s) in \(docsPath):")
for filename in files {
let filePath = docsPath.stringByAppendingFormat("/\(filename)") as String
var attr = NSFileManager.defaultManager().attributesOfItemAtPath(filePath, error: nil)
if let _attr:NSDictionary = attr {
let fileSize = _attr.fileSize()
println("\(filename) # \(fileSize) bytes")
}
}
}
}
Found 11 file(s) in /var/mobile/Containers/Data/Application/5809B294-8A54-4506-A79A-F19E7C877A4A/Documents:
editedVideo-2252.mp4 # 732567 bytes
editedVideo-3582.mp4 # 728485 bytes
editedVideo-5175.mp4 # 413897 bytes
editedVideo-5366.mp4 # 607992 bytes
editedVideo-5459.mp4 # 350652 bytes
editedVideo-622.mp4 # 763026 bytes
**editedVideo-7325.mp4 # 419498 bytes**
editedVideo-7428.mp4 # 858742 bytes
editedVideo-7948.mp4 # 923791 bytes
editedVideo-8612.mp4 # 429463 bytes
editedVideo-9363.mp4 # 511307 bytes
The videoUrl parameter did not point to the right file.
Use this approach when referencing videos locally:
let filename = "yourvideo.mp4"
let allDirs = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDir = allDirs[0] as! NSString
let filePath = documentsDir.stringByAppendingPathComponent(filename)
let fileUrl = NSURL(fileURLWithPath: filePath)
The Documents directory path (e.g., /var/mobile/Containers/Data/Application/8BA180AB-2DD9-4FD8-9312-2BF006914561/Documents/) apparently changes.
You can't expect the same path every time and therefore can't use a fully formed file URL string like we were, even for testing purposes.
The parent directory to the Documents directory -- the alphanumeric string -- is what changes.
The NSURL can mean two different things :
The absolute file path that you mentioned i.e. starting with file://
The URL that you get from ALAsset. You can get it using :
NSURL *asseturl = [asset valueForProperty:ALAssetPropertyAssetURL];
where "asset" is of type ALAsset
This URL can then be used to get AVAsset using :
AVAsset.assetWithURL
Please try the second method.

Resources