I am trying to play remote video with MPMoviePlayerViewController like this.
NSURL *url = [NSURL URLWithString: #"http://km.support.apple.com/library/APPLE/APPLECARE_ALLGEOS/HT1211/sample_iTunes.mov"];
self.mp = [[MPMoviePlayerViewController alloc]
initWithContentURL:url];
[self.navigationController presentMoviePlayerViewControllerAnimated:self.mp];
I can play above url. However, I can't play my own video file url like this. It is running on local server and it is pointing to file location.
http://127.0.0.1:8000/media/through_your_eyes/file0.mov
Is it client or server side problem? Shall I point to file location on server side or how shall I prepare?
It is server side problem
From your end you are doing well.
When you trying to play video - getting error like this
_itemFailedToPlayToEnd: {
kind = 1;
new = 2;
old = 0;
}
This shows that MPMoviePlayerViewController not able to play video from this url.
Reasons:
Your url is not proper - print NSURL object check its proper and escape character are there (If required)
Permission - It is not permitted to play this video from device. Firewall stop access this video from device. Check that you are permitted to access the url
Video format - Some times video conversion changes the formate of the video. You can see the correct format of the video how ever if conversion is made it is not able to play by the device. Please copy this url paste it in Simulator Safari app and check it is able to play.
Related
I'm trying to use AVAssetDownloadTask to download and play FairPlay-encrypted audio content offline. I kept getting an error like this in urlSession:task:didCompleteWithError::
Error Domain=AVFoundationErrorDomain Code=-11863 "Operation Stopped" UserInfo={NSLocalizedFailureReason=This content is no longer available., NSLocalizedDescription=Operation Stopped}
My flow was:
Create an AVURLAsset using a URL like https://my.cdn.com/playlist.m3u8
Set its resource loader's delegate
Give it to a player in the form of an AVPlayerItem
Using the methods in AVAssetResourceLoaderDelegate, look for a URL beginning the scheme skd, download the CKC, get the persist-able form, and hand it back to the resource loader request
All of this worked, and was done in the same way as in Apple's HLSCatalog sample code. But downloading would still give me the above error, even though plugging the same playlist and key URLs into the sample code would download fine.
What I finally figured out was that AVAssetDownloadTask will only download an AVURLAsset instance that has already been streamed and given its decryption keys (via the AVAssetResourceLoaderDelegate) and that is not associated with a player. I can't just make a new AVURLAsset using the same URL as what is already playing and download it. So it seems that in order to download arbitrary FairPlay content, I have to:
Make an AVURLAsset
Make an AVPlayer and set its volume to 0
Give it the asset and play it
Wait until it requests its keys from the resource loader and starts playing
Give it to a download task and deassociate it with the player
But this seems horrible. It can't be true.
So, my question: How do I download a FairPlay-encrypted AVURLAsset without having streamed that specific instance of it before?
Turns out you set preloadsEligibleContentKeys to true on the asset's resource loader. Then you can download:
AVURLAsset *asset = [AVURLAsset assetWithURL:self.currDownload.url];
[asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()];
asset.resourceLoader.preloadsEligibleContentKeys = YES;
AVAssetDownloadTask *task = [self.downloadSession assetDownloadTaskWithURLAsset:asset assetTitle:self.currDownload.title assetArtworkData:nil options:#{AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: #(265000)}];
task.taskDescription = self.currDownload.title;
[task resume];
The app I am working on using MPMoviePlayerController to play video at remote urls. When I reuse the player to play more than one video and the url doesn't point to a video, the controller doesn't send any notification back. I've tried MPMoviePlayerPlaybackDidFinishNotification, MPMoviePlayerPlaybackStateDidChangeNotification and MPMoviePlayerLoadStateDidChangeNotification. None of them was sent.
I also tried to do a custom time out function and calls the player's stop function like below. But, nothing happens. MPMoviePlayerController just seems dead there and doing nothing.
[self performSelector:#selector(checkTimeout) withObject:theMovie afterDelay:15];
-(void) checkTimeout {
[self.moviePlayer stop];
}
Does anyone know how to handle invalid url with MPMoviePlayerController?
I found a kind of solution myself.
It seems MPMoviePlayerController has problem playing more than one urls. If the 2nd url doesn't point to a video or invalid, the player doesn't do anything. So, I ended up creating a new instance of the MPMoviePlayerController for every url and listening to MPMoviePlayerPlaybackDidFinishNotification.
If you did not receive notification on invalid urls, then you should run a timer of duration max(initialplaybacktime, 0) and once you do not receive MPMoviePlayerReadyForDisplayDidChange notification within this time, generate an error that video is not available.
AVPlayer does not play a .aif file recorded with AVAudioRecorder. My current process is:
AVAudioSession.sharedInstance's category is set to AVAudioSessionCategoryPlayAndRecord
AVAudioRecorder is instantiated with a NSURL in the app's documents directory and settings of format of kAudioFormatAppleIMA4, bit rate of 32000, 1 channel, and sample rate of 16000.0.
Audio is recorded, then stopped. The file is saved and I can find it in the app's documents directory and verify the audio is properly recorded.
An instance of AVPlayer is instantiated with the file's NSURL. An observer is added to this object to register changes to its status. When the AVPlayer is ReadyToPlay, I call the play function.
However, despite control flow reaching the point of AVPlayerStatus.ReadyToPlay and calling play, no sound is produced. I'm checking errors and verifying the existence and attributes of the file at the NSURL. I've also tried following the process of this SO post by instantiating an AVAsset, AVPlayerItem, and AVPlayer. No luck.
Any thoughts on why AVPlayer isn't playing audio for this newly recorded local file?
edit: The app is built for iOS 9 with Xcode 7 beta 5. The app is able to play audio files streamed with AVPlayer.
The issue was not caused by AVAudioRecorder or AVPlayer. My recording URL is a NSURL I'll call fileURL. I passed this NSURL to a different view controller but AVPlayer wouldn't play when instantiated with fileURL.
I got a hint to what was going wrong when
fileURL.checkResourceIsReachableAndReturnError(&error)
failed with the error "The file does not exist." Instead, I instantiated a new NSURL with the path of the newly recorded file using:
let url = NSURL(fileURLWithPath: path)
With this url, I was able to instantiate and play an instance of AVPlayer.
I am currently making an app that is capable of streaming a music file. The problem is, our client wants it that while we are streaming an audio file, the streamed bytes will also be saved in the local storage. Which means that the streamed audio file will also be saved on the device's storage. For example I have this m4a file streamed, when the user stops streaming the audio file, the streamed music file will be saved in the device's local storage for future use.
Is this possible? If it is, what library should I use?
Thanks.
Yes it is possible use AVFoundation framework for this and play your audio.
First drag AVFoundation framework from built phase section then import like this #import <AVFoundation/AVFoundation.h>
Then declare AVAudioPlayer in .h file of your view controller instance like this
AVAudioPlayer *myAudioPlayer;
In view controller.m put this code
NSURL *fileURL = // your url.
myAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
myAudioPlayer.numberOfLoops = -1; //infinite loop
[myAudioPlayer play];
Via this way you are able to play audio in your iOS device.hope it will help your for playing audio
I am not sure what the issue is but when i try to play MP4 videos hosted on akamai server, the MPMoviePlayerViewController fails to play it. I added notifications for monitoring playback state and it quickly switches from playing to stopped. If i print the error then i get the following:
MPMoviePlayerPlaybackDidFinishReasonUserInfoKey = 1;
error = "Error Domain=MediaPlayerErrorDomain Code=-11850 \"Operation Stopped\" UserInfo=0x1e5a6750 {NSLocalizedDescription=Operation Stopped}";
Above message is not very helpful in understanding what the actual issue might be. It is important to note that i am able to play the same URL in Safari and my app is able to play youtube videos without any issues.
The issue was pretty trivial - I was passing in an incorrect streaming URL :(. Thanks.