I'm selecting the audio file from the folder and getting the URL in this delegate function
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
print("url", url)
self.filePickedBlock?(url)
}
Url looks like this
file:///private/var/mobile/Containers/Data/Application/8012C1BB-43E3-4E0C-9167-B7B5A49824A1/tmp/com.ios.PrankYourFriends-Inbox/AUDIO1.m4a
I am saving this URL as a string in Realm Database and fetching it when I want to play.
Issue I am Facing
When I play this Audio immediately after selecting then it's playing fine. But if I go to any other ViewController and Came back again and press the play button it's not playing the audio.
I am playing Audio like this:
self.avPlayer = AVPlayer.init(url: filePath)
self.avPlayer?.play()
Kindly let me know what I am doing wrong.
Its in tmp folder
/tmp/com.ios.PrankYourFriends-Inbox/AUDIO1.m4a
Copy it to say documents/library then use it any time
Related
At first I want to mention that I'm using MobilePlayer library but it's just a skin above AVPlayer.
When I tap to play video it only plays sound and I do not see any video. I've checked view bounds but the problem is not there. At the beginning of the video it indicates loading progress but later I hear only the sound without any video.
My code looks like:
let bundle = Bundle.main
let config = MobilePlayerConfig(fileURL: bundle.url(
forResource: "Skin",
withExtension: "json")!)
let videoURL = NSURL(string: channelURL!)
self.playerVC = MobilePlayerViewController(contentURL: videoURL! as URL, config: config)
self.playerVC.activityItems = [videoURL! as URL]
self.present(self.playerVC, animated: true)
I also want to mention that I see the video when I run on the simulator but on the real device there is no video at all. What can be a problem?
If you need any part of the code just ask me please
I'm trying to get my audio file duration to display on my app but my code always return 0. I hope there is a method that notifies me when the AVplayer has data from the file and then I can call my code after that to get the data. Any suggestions?
func loadAudioUrl() {
guard let url = URL(string: sampleShortAudioUrl) else {return}
audioPlayer = AVPlayer(url: url)
audioPlayer?.play()
if let duration = audioPlayer?.currentItem?.duration{
print(duration)
}
}
You can get duration, but you need to wait because content is loading. Your code assumes that it is loaded instantly.
You need to use AVPlayerItem with AVPlayer.
When AVPlayerItem status is ready to play, you can ask for duration. Complete code example is right from Apple here:
AVPlayerItem
You can't get duration from a remote audio url , you must store it's duration remotely in your database and grap it while listening or downloading . . .
I would like to play a video file in my ViewController which is loaded in every page of my PageViewController. As you will be able to see I use a plugin called Carlos to cache the videos (which initially need to be downloaded from a server) so that they do not have to be downloaded every time the user hits a new page. However, I can't figure a way out how to play this downloaded file (NSData). Thus, I would really like to know how I can get the URL of the downloaded file so that I can play it using AVPlayer.
Code (still using URL from server)
let omniCache = videoCache.cache
let request = omniCache.get(URL(string: video!)!)
request
.onSuccess { videoFile in
print("The file..." )
print(videoFile)
//How can I get the local URL here instead of my server url
if let videoURL = URL(string: self.video!){
if self.player == nil {
let playerItemToBePlayed = AVPlayerItem(url: videoURL as URL)
self.player = AVPlayer(playerItem: playerItemToBePlayed)
let playerLayer = AVPlayerLayer(player: self.player)
playerLayer.frame = self.view.frame
self.controlsContainerView.layer.insertSublayer(playerLayer, at: 0)
}
}
}
.onFailure { error in
print("An error occurred :( \(error)")
}
Look at this code of yours:
videoFile in
print("The file..." )
print(videoFile)
if let videoURL = URL(string: self.video!){
So in the first line you print videoFile, which turns out to be the data of the file. But then you ignore it! You never mention videoFile again. Why do you ignore it? That is the data, you already have the data. Now play it!
If the data is a file, get its file URL and play it. If it is in memory — it definitely should not be, because a video held entirely in memory would crash your program — save it, and get that file URL and play it.
[I have to ask, however, why you are interposing this cache plug-in between yourself and such a simple task. Why don't you just download the remote video to disk, yourself?]
Since iOS 10, Apple has provided the support for downloading HLS (m3u8) video for offline viewing.
My question is: Is it necessary that we can only download HLS when it is being played ? Or we can just download when user press download button and show progress.
Does anyone has implemented this in Objective C version? Actually my previous App is made in Objective C. Now I want to add support for downloading HLS rather than MP4 (previously I was downloading MP4 for offline view).
I am really desperate to this. Please share thoughts or any code if implemented.
I used the apple code guid to download HLS content with the following code:
var configuration: URLSessionConfiguration?
var downloadSession: AVAssetDownloadURLSession?
var downloadIdentifier = "\(Bundle.main.bundleIdentifier!).background"
func setupAssetDownload(videoUrl: String) {
// Create new background session configuration.
configuration = URLSessionConfiguration.background(withIdentifier: downloadIdentifier)
// Create a new AVAssetDownloadURLSession with background configuration, delegate, and queue
downloadSession = AVAssetDownloadURLSession(configuration: configuration!,
assetDownloadDelegate: self,
delegateQueue: OperationQueue.main)
if let url = URL(string: videoUrl){
let asset = AVURLAsset(url: url)
// Create new AVAssetDownloadTask for the desired asset
let downloadTask = downloadSession?.makeAssetDownloadTask(asset: asset,
assetTitle: "Some Title",
assetArtworkData: nil,
options: nil)
// Start task and begin download
downloadTask?.resume()
}
}//end method
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
// Do not move the asset from the download location
UserDefaults.standard.set(location.relativePath, forKey: "testVideoPath")
}
if you don't understand what's going on, read up about it here:
https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/MediaPlaybackGuide/Contents/Resources/en.lproj/HTTPLiveStreaming/HTTPLiveStreaming.html
now you can use the stored HSL content to play the video in AVPlayer with the following code:
//get the saved link from the user defaults
let savedLink = UserDefaults.standard.string(forKey: "testVideoPath")
let baseUrl = URL(fileURLWithPath: NSHomeDirectory()) //app's home directory
let assetUrl = baseUrl.appendingPathComponent(savedLink!) //append the saved link to home path
now use the path to play video in AVPlayer
let avAssest = AVAsset(url: assetUrl)
let playerItem = AVPlayerItem(asset: avAssest)
let player = AVPlayer(playerItem: playerItem) // video path coming from above function
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true, completion: {
player.play()
})
The only way you can do this is to set up an HTTP server to serve the files locally after you've downloaded them.
The Live playlist uses a sliding-window. You need to periodically reload it after target-duration time and download only the new segments as they appear in the list (they will be removed at a later time).
Here are some related answers: Can IOS devices stream m3u8 segmented video from the local file system using html5 video and phonegap/cordova?
You can easily download an HLS stream with AVAssetDownloadURLSession makeAssetDownloadTask. Have a look at the AssetPersistenceManager in Apples Sample code: https://developer.apple.com/library/content/samplecode/HLSCatalog/Introduction/Intro.html
It should be fairly straight forward to use the Objective C version of the api.
Yes, you can download video stream served over HLS and watch it later.
There is a very straight forward sample app (HLSCatalog) from apple on this. The code is fairly simple. you can find it here - https://developer.apple.com/services-account/download?path=/Developer_Tools/FairPlay_Streaming_Server_SDK_v3.1/FairPlay_Streaming_Server_SDK_v3.1.zip
You can find more about offline HLS streaming here.
I am trying to play a song from a link using the avkit, but nothin is being played. I used an online mp3 file to link converter to generate a link. If anyone has a better method to convert an mp3 file to a link I am all ears. Apart from that the real problem I'm having is why I can't hear anything. I have a feeling it's the link and it is not supported. Keep in mind that playedSong is being called in the viewDidLoad. Link to the song I am trying to play
var urlPath = "http://picosong.com/ANQY"
func playedSong(){
let url: NSURL = NSURL(string: urlPath)!
player = AVPlayer(URL: url)
player.play()
player.rate = 1.0
if(player.rate == 1.0){
print(url)//prints correct url
print("playing")//prints
}else{
print("not playing")
}
}