I have an .mp4 video(url) which was protected by Windows authentication. I would like to play using MPMoviePlayerController.
I've implemented some code, and I'm sure I'm close!
So, I'm trying to "unlock" the mp4 url using NSURLConnection. It works, but when I try to access the same url with initWithContentURL, it doesn't work. (it cannot "see" that I've entered the info previously.
So, the question was; how do I onlock a folder/url permanently, OR how can I provide MPMoviePlayerController a NSURLConnection instead of NSURL.
1- So, here's the steps I've taken:
- (void)viewDidLoad{
[super viewDidLoad];
//[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"]]];
[self tryConnection];
}
2--> I'm trying to access the protected URL(this was working)
- (void) tryConnection{
NSURLRequest* request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.abcd.com/_develop/video/01.mp4"]];
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
//[request release];
//[connection release];
}
3- this was called properly
- (BOOL)connection:(NSURLConnection*)conn canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace*)protectionSpace {
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM])
return YES;
// Explicitly reject ServerTrust. This is occasionally sent by IIS.
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
return NO;
return NO;
}
4- this was called properly
- (void)connection:(NSURLConnection*)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge{
NSLog(#"didReceiveAuthenticationChallenge");
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM])
[[challenge sender] useCredential:[NSURLCredential
credentialWithUser:#"1234"
password:#"5678"
persistence:NSURLCredentialPersistenceNone] forAuthenticationChallenge:challenge];
}
4- this was called properly. From here, that's great because i know that the url was Unlock. So... how to play it with MPMoviePlayer?
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;{
NSLog(#"received response via nsurlconnection");
[self moviePlayerGO];
}
4- Stay black... :(
-(void)moviePlayerGO{
NSURL *movieURL = [NSURL URLWithString:#"http://www.abcd.com/_develop/video/01.mp4"];
//NSURL *movieURL = [NSURL URLWithString:#"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
moviePlayer.shouldAutoplay = YES;
[[moviePlayer view] setFrame: CGRectMake(0.0, 0.0, 350.0, 250.0)]; // 2X the native resolution
[self.view addSubview: [moviePlayer view]];
}
Related
My code looks like this:
_player = [AVPlayer playerWithURL:destination];
_playerVC = [AVPlayerViewController new];
_playerVC.player = _player;
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:_playerVC animated:YES completion:^{
[_player play];
}];
});
_player represents AVPlayer and _playerVC represents AVPlayerViewController. I have strong global references to these objects.
Using terminal, I played the file located at the destination (open -a quicktime\ player destinationURLAbsoluteString) and saw the file is properly loaded since it was playing.
It is a m4v file. I have played a m4a file and it properly gave me audio. I have also substituted the url I have for destination to some remote url and that worked for video. This leads me to believe it has something to do with my video. What's weird is that my AVPlayerViewController does show a black screen with all the normal controls, and even shows the video is 2 minutes and 23 seconds. Upon opening the video file manually, I can see that it is also 2 minutes and 23 seconds.
I can forward through the video properly by dragging the white dot indicative of the video's position, but I never hear anything, nor do I see anything but the black screen and controls.
TL;DR
NSLog(#"Destination: %#",destination);
prints: file:///Users/MyLogin/Library/Developer/CoreSimulator/Devices/694F4C94-F785-4931-A312-4C3E7DE8673A/data/Containers/Data/Application/76C923BE-5B25-41F7-9145-63414657FDF6/Documents/mzvf_5914002519860647075.640x352.h264lc.D2.p.m4v
All in all, it looks like I'm properly retrieving the video, but for some reason my player controller is completely black and void of audio. Any help is much appreciated.
Source Code:
.m file:
#import "ViewController.h"
#import "View2ViewController.h"
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property NSDictionary *requestedSong;
#property (strong) AVPlayer *player; //Declare Globally
#property (strong) AVPlayerViewController *playerVC;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 200, 50)];
button.center = self.view.center;
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"Query Songs" forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonClicked) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:button];
UIButton *button2 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 200, 50)];
button2.center = CGPointMake(button.center.x, button.center.y + 200);
button2.backgroundColor = [UIColor blueColor];
[button2 setTitle:#"Listen to the first song" forState:UIControlStateNormal];
[button2 addTarget:self action:#selector(button2Clicked) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:button2];
}
-(void)button2Clicked{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
NSURL *url = [NSURL URLWithString:[_requestedSong objectForKey:#"previewUrl"]];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]initWithURL:url];
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:req];
[task resume];
}
-(void)buttonClicked{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
NSURL *url = [NSURL URLWithString:#"https://itunes.apple.com/search?media=movie&entity=movie&term=Mad"];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]initWithURL:url];
NSURLSessionDataTask *task = [session dataTaskWithRequest:req];
[task resume];
}
-(NSURL*)localFilePathForURL:(NSURL *) previewUrl{
//get the directory to use
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) objectAtIndex:0];
//create the full path
NSString *fullPath = [documentsPath stringByAppendingPathComponent:previewUrl.lastPathComponent];
//append the filename and append to document path url
return [NSURL fileURLWithPath:fullPath];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{
NSURL* originalURL = downloadTask.originalRequest.URL;
NSURL *destination = [self localFilePathForURL:originalURL];
NSLog(#"Destination: %#",destination);
NSFileManager *defaultFileManager = [NSFileManager defaultManager];
if([defaultFileManager fileExistsAtPath:destination.absoluteString]){
[defaultFileManager removeItemAtURL:destination error:nil];
}
NSError *error;
#try {
[defaultFileManager copyItemAtURL:location toURL:destination error:&error];
} #catch (NSException *exception) {
NSLog(#"copy caught with exception: %#",exception);
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
_player = [AVPlayer playerWithURL:destination];
_playerVC = [AVPlayerViewController new];
_playerVC.player = _player;
[self presentViewController:_playerVC animated:YES completion:^{
[_player play];
}];
});
NSLog(#"Hello");
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data{
NSError *error2;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:1 error:&error2];
_requestedSong = [[dict valueForKey:#"results"] objectAtIndex:0];
NSLog(#"Searched: %#",[_requestedSong objectForKey:#"trackName"]);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
completionHandler(NSURLSessionResponseAllow);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
.h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
#end
UPDATE:
Upon using the actual URL endpoint for mad max instead of downloading the video, it also displays a blank video. This must mean there's something weird about the format of the video or how it interacts with the AVPlayer.
You should setup observer for AVPlayer status to call play only when it will be ready to play.
How to do it - check answers here: AVPlayer And Local Files
check the following
if ((_playerVC.player.rate != 0) && (_playerVC.player.error == nil)) {
// player is playing
} else {
// Something wrong
}
also you can observe the rate property of the player. More info here
I have been working on an App that has a simple UIWebView in it that displays a Sharepoint site. I originally thought the NTLM authentication would be an issue but as it turns out that is really straight forward. However, ever since iOS8 my app has been spamming "Stream is sending an event before being opened" over and over again in my log to the point that the page really never can load.
I originally thought it was something I was doing so I created a small app (below) to remove any weirdness my other app may have had but unfortunately I get the same issue. I guess my main issue is I don't know where to even start to look to find an answer to this one. The Internet has some mention of this but no clear resolution like [webView dontDoThat]. :D
I am playing around with adding the connection to the run loop manually, you will see this in the code. I have tried every way I know how to create the connection but this is the most recent try.
I start out handing the SSL challenge because my cert is not valid for the domain, then I get the NTLM challenge and send in the hard coded username and pass as a test. It partially loads the site but finally gives up loading all the resources in what I assume is this error. Theories welcome.
//
// ViewController.m
//
// Created by Greg Frame on 10/2/14.
//
#import "ViewController.h"
#define APPURL #"https://mysharepoint.com"
#define USERNAME #"usernamehere"
#define PASSWORD #"passwordhere"
#interface ViewController ()
#end
#implementation ViewController
BOOL _Authenticated = NO;
BOOL _SSLAuthenticated = NO;
NSURLConnection *_Connection;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.webView.delegate = self;
NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
[self.webView loadRequest:requestURL];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark UIWebViewDelegate
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(webView.loading){ //if url requests come through while its loading, its probably embedded content
return YES;
}
BOOL result = YES;
if (!_Authenticated || !_SSLAuthenticated) {
//I have tried a ton of different ways to create the NSURLConnection this is the latest
_Connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[_Connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[_Connection start];
result = NO;
}
return result;
}
#pragma mark NSURLConnection Delegate
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
if( [challenge previousFailureCount] == 0 ) {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSLog(#"SSL Challenge");
NSURL* baseURL = [NSURL URLWithString:APPURL];
if ([challenge.protectionSpace.host isEqualToString:baseURL.host]) {
NSLog(#"trusting connection to host %#", challenge.protectionSpace.host);
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
} else
NSLog(#"Not trusting connection to host %#", challenge.protectionSpace.host);
} else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM]) {
NSLog(#"NTLM Challenge");
_SSLAuthenticated = YES; //cant get here otherwise
//persistence:NSURLCredentialPersistenceForSession
NSURLCredential *cred = [NSURLCredential credentialWithUser:USERNAME password:PASSWORD persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
} else {
NSLog(#"Unsupported Challenge");
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
} else {
NSLog(#"Failed authentication");
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)pResponse;
NSLog(#"Received response %ld", (long)[httpResponse statusCode]);
if( !_SSLAuthenticated && [httpResponse statusCode] == 200) {
NSLog(#"SSL GOOD");
_SSLAuthenticated = YES;
[_Connection cancel];
_Connection = nil;
NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
[self.webView loadRequest:requestURL];
return;
}
if( !_Authenticated && [httpResponse statusCode] == 200) {
NSLog(#"NTLM GOOD");
_Authenticated = YES;
[_Connection cancel];
[_Connection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
[self.webView loadRequest:requestURL];
return;
}
NSLog(#"Connection Cancelled");
[_Connection cancel];
}
#end
Disclaimer: Parts and pieces were copied from others so I don't claim to have manually typed every line. Thanks to you all who had code that I put in this example.
Any help appreciated!
- Greg Frame
Some log entries:
2014-10-06 15:12:31.110 sptest2[21405:2051411] SSL Challenge
2014-10-06 15:12:31.110 sptest2[21405:2051411] trusting connection to host xxxxx.xxxxx.com
2014-10-06 15:12:31.426 sptest2[21405:2051411] NTLM Challenge
2014-10-06 15:12:31.899 sptest2[21405:2051690] Stream 0x7c8d9070 is sending an event before being opened
2014-10-06 15:12:32.429 sptest2[21405:2051411] Received response 200
2014-10-06 15:12:32.429 sptest2[21405:2051411] NTLM GOOD
2014-10-06 15:12:33.184 sptest2[21405:2051723] Stream 0x7ca95210 is sending an event before being opened
2014-10-06 15:12:34.293 sptest2[21405:2051723] Stream 0x7bed9740 is sending an event before being opened
2014-10-06 15:12:34.465 sptest2[21405:2051723] Stream 0x7bee1120 is sending an event before being opened
2014-10-06 15:12:34.523 sptest2[21405:2051723] Stream 0x7caba9a0 is sending an event before being opened
2014-10-06 15:12:34.532 sptest2[21405:2051723] Stream 0x7f87e040 is sending an event before being opened
...
Hi in my application I'm playing the video using URL. I'm passing the video URL form my server now the problem its taking to much time to play the video. So i want to show progress bar until its load the video .
So i have used the MBProgressHUD for progress bar its showing the progress bar but the video is not playing please tell where I'm doing wrong.
My code.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString * currentVideo = [videoarray1 objectAtIndex:indexPath.row];
NSString *strurl=[self urlencode:currentVideo];
NSURL *url=[NSURL URLWithString:strurl];
NSURLRequest *req=[NSURLRequest requestWithURL:url];
NSURLConnection *con=[NSURLConnection connectionWithRequest:req delegate:self];
if (con) {
datas=[[NSMutableData alloc]init];
}
spinner = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
spinner.mode = MBProgressHUDModeCustomView;
[spinner setLabelText:#"Loading file....."];
[spinner setLabelFont:[UIFont systemFontOfSize:15]];
[spinner show:YES];
}
-(NSString *)urlencode:(NSString *)str
{
NSString *encodeString=(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)str, NULL, (CFStringRef)#"", kCFStringEncodingUTF8));
return encodeString;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(#"%lld",[response expectedContentLength]);
self.length = [response expectedContentLength];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data1{
[datas appendData:data1];
float progress = (float)[datas length]/(float)self.length;
NSLog(#"%f",progress);
float check=progress*100;
if (check==100) {
[spinner hide:YES];
[spinner removeFromSuperViewOnHide];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSData *data = datas;
NSLog(#"%#",data);
NSString* myurl;
myurl = [[NSString alloc] initWithData:datas encoding:NSASCIIStringEncoding];
NSLog(#"%#",myurl);
_movieplayer = [[MPMoviePlayerController alloc]initWithContentURL: [NSURL URLWithString:myurl]];
[[_movieplayer view] setFrame: CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[self.view addSubview: [_movieplayer view]];
[_movieplayer setShouldAutoplay:YES];
[_movieplayer prepareToPlay];
[_movieplayer play];
}
I have used the above code its not playing the video please tell where I'm doing wrong in the above code how to achieve this one.
Thanks.
1.create new view control
2.pass your videoarray1 value to nextvieww control i mean your video url
3.add following code nextview control
- (void)viewDidLoad
{
[super viewDidLoad];
self.indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.indicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
self.indicator.center = self.view.center;
[self.view addSubview:self.indicator];
[self.indicator startAnimating];
_movieplayer = [[MPMoviePlayerController alloc]initWithContentURL: [NSURL URLWithString:[self urlencode:self.strPlayUrl]]];
[[_movieplayer view] setFrame: CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[self.view addSubview: [_movieplayer view]];
[_movieplayer setShouldAutoplay:YES];
[_movieplayer prepareToPlay];
//this is the line we need to do
[self.view insertSubview:self.movieplayer.view belowSubview:self.indicator];
[self.movieplayer play];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(#"VIEW DID LOAD");
// Register to receive a notification that the movie is now in memory and ready to play
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieLoadStateDidChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
}
-(void)movieLoadStateDidChange:(id)sender
{
NSLog(#"STATE CHANGED");
if(MPMovieLoadStatePlaythroughOK ) {
NSLog(#"State is Playable OK");
NSLog(#"Enough data has been buffered for playback to continue uninterrupted..");
self.indicator.hidden = YES;
[ self.indicator stopAnimating];
}
}
-(NSString *)urlencode:(NSString *)str
{
NSString *encodeString=(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)str, NULL, (CFStringRef)#"", kCFStringEncodingUTF8));
return encodeString;
}
hi I'm trying to view the videos from my server for that i have stored the video url in mysql database
using the json and php code I'm passing the url to the iOS but now I'm getting some problem here
previously using this same format fetching the images from my server but now i want to view the videos this is the first time im working on the videos not to able to get it
this is the code which i used to fetch the url form database and liking to the ios nsurl format
tabecell.m file code:
#import "vediopoliticalCell.h"
#import "vedios.h"
#implementation vediopoliticalCell
//#synthesize movieplayer,titile;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void)setDataSource:(vedios *)inVideosObj
{
self.titile.text = inVideosObj.title;
NSURL *url =[NSURL URLWithString:inVideosObj.video];
NSURLRequest *request =[NSURLRequest requestWithURL:url];
connection =[[NSURLConnection alloc] initWithRequest:request delegate:self];
self.responseData = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
{
[self.responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
MPMoviePlayerController *play = [[MPMoviePlayerController alloc]initWithContentURL:self.responseData];
}
In this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
MPMoviePlayerController *play = [[MPMoviePlayerController alloc]initWithContentURL:self.responseData];
}
im getting a waring called:
Incompatible pointer types sending 'NSMutableData ' to parameter of type Nsurl
previously for the image i using this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
UIImage *image = [UIImage imageWithData:self.responseData];
self.thumbImageView.image = image;
}
now i dont know how to use for the videos please can anyone help me with this
thanks in advance
self.responseData is NSMutableData but MPMoviePlayerController needs url to load the video.
So, first you have to get url-string from data.
NSString *url =[NSString stringWithUTF8String:[responseData bytes]]
MPMoviePlayerController *play = [[MPMoviePlayerController alloc]initWithContentURL:[NSURL urlWithString:url]];
//Now present the MPMoviePlayerController
Try this
In setDataSource: method
-(void)setDataSource:(vedios *)inVideosObj
{
self.titile.text = inVideosObj.title;
NSURL *url =[NSURL URLWithString:inVideosObj.video];
MPMoviePlayerViewController *videoDeatilView = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
//now you can present this videoDeatilView and
//[videoDeatilView.moviePlayer play]; will play the video
}
i am having problems with playing movie from URL that has basic http authentification.
Here is code:
NSURLCredential *credential = [[NSURLCredential alloc]
initWithUser:#"user"
password:#"password"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:#"moze.dyndns.org"
port:80
protocol:#"http"
realm:nil
authenticationMethod:NSURLAuthenticationMethodHTTPBasic];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
NSURL *videoURL = [NSURL URLWithString:#"http://moze.dyndns.org/test/test.mov"];
moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[moviePlayerController.view setFrame:self.view.bounds];
[self.view addSubview:moviePlayerController.view];
MPMoviePlayerController *mp = [moviePlayerController moviePlayer];
mp.controlStyle = MPMovieControlStyleDefault;
[mp prepareToPlay];
[[moviePlayerController moviePlayer] play];
I am getting error "The operation couldn't be completed. (MediaPlayerErrorDomain error -1013.)", errorLog in NULL, just like accessLog too.
I am using a apache server with AuthType Basic, credentials are right, tested them on web browser. There are no problems with playback if authentification is disabled.
Please help, I can't find what is wrong.
I couldn't get MPMoviePlayerController to do the authentication challenge properly, even thought the Apple docs say otherwise. The VERY hacky solution I came up with was to use Apple's CustomHTTPProtocol to intercept the response and provide the authentication challenge response. I believe the original purpose for this protocol was to handle authentication for UIWebViews.
Link to CustomHTTPProtocol:
https://developer.apple.com/library/ios/samplecode/CustomHTTPProtocol/Listings/Read_Me_About_CustomHTTPProtocol_txt.html
My interface declaration:
#interface SampleViewController() <CustomHTTPProtocolDelegate>
Instantiation of MPMoviePlayerController within my SampleViewController:
NSString *fullURLString = #"http://www.samplesite.com/samplemovie.mp4";
NSURL *fullURL = [NSURL URLWithString:fullURLString];
[CustomHTTPProtocol setDelegate:self];
[CustomHTTPProtocol start];
NSURLCredential *credential = [[NSURLCredential alloc]
initWithUser:#"username"
password:#"password"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:fullURL.host
port:80
protocol:fullURL.scheme
realm:#"your-realm"
authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:fullURL];
[self.moviePlayer prepareToPlay];
[self.moviePlayer setShouldAutoplay:NO];
[self.moviePlayer setControlStyle:MPMovieControlStyleEmbedded];
[self.moviePlayer.view setFrame:self.sampleView.bounds];
[self.moviePlayer.backgroundView setBackgroundColor:[UIColor colorWithWhite:0.9 alpha:1.0]];
[self.moviePlayer.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self.sampleView addSubview:self.moviePlayer.view];
Also in my SampleViewController, I have a couple delegate methods. For basic authentication, it's pretty simple:
- (BOOL)customHTTPProtocol:(CustomHTTPProtocol *)protocol canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
BOOL canAuth = ([[protectionSpace authenticationMethod] isEqual:NSURLAuthenticationMethodHTTPBasic] &&
[[protectionSpace realm] isEqualToString:#"your-realm"]);
return canAuth;
}
- (void)customHTTPProtocol:(CustomHTTPProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:#"username"
password:#"password"
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}
After you call start, all http and https requests go through the CustomHTTPProtocol module
I didn't include CustomHTTPProtocol since Apple provides the source and it's really long. I made some changes to make it work with ARC but it's mostly the same code.
Hopefully this works for you.