Get video in Phpicker in swiftui, but can't play by Videoplayer - swift

I'm trying to load a video from Phpicker and preview it by Video player, but I don't know why it doesn't work.
So I did some research, and most of the solutions put videos in the project file and use Bundle.main.url(forResource:, withExtension:) to play video.
Here's my picker to pick a video. I'm trying to get the video file URL and make a copy using FileManager.default.copyItem(at:, to:) then use URL in Avplayer.
(Pick a video from the photo library)
DispatchQueue.main.async {
guard let videoURL = videoURL as? URL else { return }
debugPrint("video url: \(videoURL.absoluteString)")
let fileID = UUID().uuidString
let fileName = "\(fileID).mp4"
debugPrint("file name: \(fileName)")
let newURL = URL(fileURLWithPath: NSTemporaryDirectory() + fileName)
debugPrint("new url: \(newURL.absoluteString)")
try? FileManager.default.copyItem(at: videoURL, to: newURL)
self.parent.video = newURL
}
(User new URL to play video)
if let url = providerRoomSummitViewModel.roomIntroVideoURL {
VStack {
VideoPlayer(player: AVPlayer(url: URL))
}
}

Related

Playing songs downloaded into the cache directory

Downloading an mp3 and saving it into the Library/caches folder works, But accessing it later doesn't.
Checking if the song really exists, i opened up Finder and went to the simulator folders. and my folder looks like this:
My song is located at: Library/Caches/Digger/Flower.mp3
Trying to access this using AVPlayer:
let folderName = "Digger"
let fileName = "Flower.mp3"
let url = FileManager.default
.urls(for: .cachesDirectory, in: .userDomainMask)[0]
.appendingPathComponent(folderName).appendingPathComponent(fileName)
var urlString = url.absoluteString
print("MyPath: \(urlString)")
urlString.removeSubrange(urlString.range(of: "file://")!)
let player = AVPlayer(url: URL(string: urlString)!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
player.play()
}
But it doesn't work.
Simulator screenshot upon runtime:
Your URL handling is incorrect.
Replace these lines:
var urlString = url.absoluteString
print("MyPath: \(urlString)")
urlString.removeSubrange(urlString.range(of: "file://")!)
let player = AVPlayer(url: URL(string: urlString)!)
with:
let player = AVPlayer(url: url)
url already is the URL that you need. No need to try to convert it in any way.
For reference, use url.path to convert a file URL into a path string. And if you need to create a URL from a path string, use URL(fileURLWithPath:), not URL(string:). Only use URL(string:) with a string that has a URL scheme such as file://, https://, etc.

how to download pdf file in iOS?

I am converting base64 to pdf file in local.
func saveBase64StringToPDF(_ base64String: String)
{
guard
var documentsURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last,
let convertedData = Data(base64Encoded: base64String)
else {
//handle error when getting documents URL
return
}
documentsURL.appendPathComponent("yourFileName.pdf")
do {
try convertedData.write(to: documentsURL)
} catch {
//handle write error here
}
print(documentsURL)
}
From above method I am getting a path pdf file
file:///Users/captivatesoft/Library/Developer/CoreSimulator/Devices/63D1814B-1010-4694-883E-D2EE75C386DD/data/Containers/Data/Application/1F39B567-F470-4B7E-9A9C-4723ADFDC428/Documents/yourFileName.pdf
Is there any way to download this pdf file or to show pdf in safari?
var pdfURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
pdfURL = pdfURL.appendingPathComponent( "example.pdf") as URL
let data = try! Data(contentsOf: pdfURL)
let webView = WKWebView(frame: CGRect(x:20,y:20,width:view.frame.size.width-40, height:view.frame.size.height-40))
webView.load(data, mimeType: "application/pdf", characterEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
view.addSubview(webView)
To open the PDF in Safari you could just do
UIApplication.shared.openURL(URL(string: <the link for the PDF>))
Now to download a PDF or anything from a URL, you could just do
let pdfData = try? Data(contentsOf: URL(string: <the link for the PDF>))
NOTE: try Data(contentsOf: url) will block the thread, so you might want to do it on a different thread like this :
DispatchQueue.global.async { [weak self] in
if let pdfData = try? Data(contentsOf: url) {
// Now you can do anything with the data
}
}
First, you can not download pdf file in iOS, it means you cannot save pdf file in iBook or Album.
You can fetch pdf file data from file URL then you can do follows:
Open in Safari browser from the app.
You can show pdf file in WKWebView within the app.
You can use "QuickLook" framework to show the pdf file.
Using WebView:
if let url = URL(string:string) {
webView.load(URLRequest(url: url))
}

Can not play sound file Swift4

I'm trying play simple .wav file in my application.
Here is the code:
func alarmSound() {
var player: AVAudioPlayer?
guard let path = Bundle.main.path(forResource: "emergency021", ofType: "wav") else {
print("Can't find audio file")
return
}
let url = URL(fileURLWithPath: path)
do {
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
if let prepare = player?.prepareToPlay() {
print("Player prepared: \(prepare)")
}
player?.volume = 1.0
player?.play()
} catch {
print("Playing sound error: \(error)")
}
}
Everything ok, file in the bundle, url is ok, player prepared, but.. there is no any sound. I have tried .mp3 file - same result.
Any ideas, why?
Issue was declaring player: AVAudioPlayer locally in function body, when I moved it up to ViewController all works.

Swift / iOS 10 : How to download a VIDEO and store within the app

I'm new to SWIFT/Programming &
I couldn't find an answer on my question, that's why I'm gonna give it a try here:
HOW Do I download a video (mp4) from an URL and store it within the app**
HOW Do I display the video then in a container**
I've already found this topic:
Swift - Downloading video with downloadTaskWithURL
But in my case, I wouldn't want the video to be safed in the camera-roll. Just within the app.
Thanks for any kind of help/hint !
You can use URLSession's dataTask or downloadTask to download any file from url(if it's downloadble)
Here's the way to use dataTask for downloading:
let videoUrl = "Some video url"
let docsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = docsUrl.appendingPathComponent("MyFileSaveName.mp4")
if(FileManager().fileExists(atPath: destinationUrl.path)){
print("\n\nfile already exists\n\n")
}
else{
//DispatchQueue.global(qos: .background).async {
var request = URLRequest(url: URL(string: videoUrl)!)
request.httpMethod = "GET"
_ = session.dataTask(with: request, completionHandler: { (data, response, error) in
if(error != nil){
print("\n\nsome error occured\n\n")
return
}
if let response = response as? HTTPURLResponse{
if response.statusCode == 200{
DispatchQueue.main.async {
if let data = data{
if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic){
print("\n\nurl data written\n\n")
}
else{
print("\n\nerror again\n\n")
}
}//end if let data
}//end dispatch main
}//end if let response.status
}
}).resume()
//}//end dispatch global
}//end outer else
Now to play the saved file:
class MyViewController: UIViewController {
override func viewDidLoad() {
let baseUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let assetUrl = baseUrl.appendingPathComponent("MyFileSaveName.mp4")
let url = assetUrl
print(url)
let avAssest = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: avAssest)
let player = AVPlayer(playerItem: playerItem)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true, completion: {
player.play()
})
}
}
However, most sites do not provide a direct dwonloadable link for video. You can get that link by playing the video in a UIWebView and register this following observer to get that link:
NotificationCenter.default.addObserver(self, selector: #selector(videoPlayedInWebView), name: NSNotification.Name(rawValue: "AVPlayerItemBecameCurrentNotification"), object: nil)
#objc func videoPlayedInWebView(aNotification: NSNotification) {
if let playerItem: AVPlayerItem = aNotification.object as? AVPlayerItem{
let asset: AVURLAsset = playerItem.asset as! AVURLAsset
var downloadebaleVideoUrl = asset.url
print(downloadebaleVideoUrl)
}
}
Here "downloadebaleVideoUrl" is the link that will be generated once the video plays in the webview.
If you have any questions, feel free to ask.
Note: This is will work only for sites that have mp4 files. 'HLS' streams won't be downloaded with this method. For that you can refer to this following answer:
https://stackoverflow.com/a/54493233/10758374
Edit: this works only with UIWebView and it won't work with WKWebView.
You need to create a local url, that will be a path in your app's file system and write the video's data into it.
func writeToFile(urlString: String) {
guard let videoUrl = URL(string: urlString) else {
return
}
do {
let videoData = try Data(contentsOf: videoUrl)
let fm = FileManager.default
guard let docUrl = fm.urls(for: .documentDirectory, in: .userDomainMask).first else {
print("Unable to reach the documents folder")
return false
}
let localUrl = docUrl.appendingPathComponent("test.mp4")
try videoData.write(to: localUrl)
} catch {
print("could not save data")
}
}
Keep in mind to always call this function in the background thread.

AVPlayer Not Playing Videos

I'm trying to play video from my parse server I'm getting empty video player And when i print the url i get the correct video url
let thevideo:PFFile! = (self.selectedmsg["file"] as! PFFile)
let url:NSURL = NSURL(string: thevideo.url!)!
let player = AVPlayer(URL: url)
let playercontroller = AVPlayerViewController()
playercontroller.player = player
self.presentViewController(playercontroller, animated: true) {
player.play()
}
Any help? to play videos from my parse.