MPMoviePlayerViewController play from NSData (MP4) - ios

NSString *p = [app getFilePathFor:name];
// Printing description of p:
// /Users/Jackson/Library/Application Support/iPhone Simulator/5.0/Applications/7FE97EDD-D080-4E5E-8EDD-3D9FFA8F6CF5/Documents/6681a4d7-8630-4a12-90c6-f95d72650a42
NSData *data = [NSData dataWithContentsOfFile:p];
// Printing description of data:
// <01401dc2 a15ebc27 e473ee79 316568ff 19dc7000 df3f7c5c dc206870 01a1c00e 00010000 00000000 00e10288 00000003 01060020 08c80038 00080000 88edffbf 02000119 0000050e 00000000 00000000 02000007 0000050f 00000000 00000000>
NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
// Printing description of str:
// #¡^¼'äsîy1ehÿÜp
path = [NSURL fileURLWithPath:str];
// Printing description of path:
// %01#%1D%C3%82%C2%A1%5E%C2%BC'%C3%A4s%C3%AEy1eh%C3%BF%19%C3%9Cp%00%C3%9F%3F%7C%5C%C3%9C%20hp%01%C2%A1%C3%80%0E%00%01%00%00%00%00%00%00%00%C3%A1%02%C2%88%00%00%00%03%01%06%00%20%08%C3%88%008%00%08%00%00%C2%88%C3%AD%C3%BF%C2%BF%02%00%01%19%00%00%05%0E%00%00%00%00%00%00%00%00%02%00%00%07%00%00%05%0F%00%00%00%00%00%00%00%00 -- file://localhost/
Then I send the path to the MPMoviePlayerViewController like so:
MPMoviePlayerViewController * playerController = [[MPMoviePlayerViewController alloc] initWithContentURL:path];
[self presentMoviePlayerViewControllerAnimated:(MPMoviePlayerViewController *)playerController];
playerController.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[playerController.moviePlayer play];
playerController=nil;
At this point, the Movie Player shows, then immediate hides once the "show" animation is complete. In the log I get this:
An instance 0x87ca7b0 of class AVPlayerItem was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x87dfc30> (
<NSKeyValueObservance 0x933c280: Observer: 0x93367d0, Key path: nonForcedSubtitleDisplayEnabled, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x933c630>
<NSKeyValueObservance 0x933c360: Observer: 0x93356b0, Key path: presentationSize, Options: <New: NO, Old: NO, Prior: NO> Context: 0x0, Property: 0x87b53b0>
I have no idea where to go next.. help?
** EDIT **
the MP4 I'm trying to play is coming from this buckbunny test clip. When I load the clip straight in form the URL it works. But if I download it and save it via NSData and try to reopen the NSData this no longer works.
** EDIT 2 **
#Till: "You are initializing a URL with a string that is garbledegock; // str=#"#¡^¼'äsîy1ehÿÜp" path = [NSURL fileURLWithPath:str]; What are you expecting here?"
So now that I've tried:
path = [NSURL fileURLWithPath:[app getFilePathFor:name]];
// Printing description of path:
// file://localhost/Users/Jackson/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/CB1CA8D0-B5EC-4B5F-8C7F-0EF449508BA7/Documents/9d425856-14b0-4ad3-835a-970affacb05f
I'm still getting the EXACT same error.

Why are you converting to nsdata from the saved clip file?
You should just load the path for the clip in your app documents directory.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:name];
NSURL *fileURL = [NSURL fileURLWithPath:filePath isDirectory:NO];
yourMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL: fileURL];

I think it's due to the fact that you are setting it to nil while it's playing. Actually, it appears that it happens so quickly that the MPMoviePlayerViewController is still loading the material when you set it to nil.

Related

iOS9 - Sharing to Instagram (w/ hooks) not working

I'm currently updating one of my apps to be iOS9 compatible, and I'm having trouble with the share to Instagram function. I'm using the Instagram hooks as stated on their developer site: (https://instagram.com/developer/mobile-sharing/iphone-hooks/)
The image I wish to share is being generated successfully, with the .igo suffix, and the functionality is still working as intended on iOS8. It just seems to have broken with the new version of iOS.
Here's the code for sharing to Instagram, using the UIDocumentInteractionController:
NSURL *instagramURL = [NSURL URLWithString:#"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
//convert image into .png format.
NSData *imageData = UIImagePNGRepresentation(image);
//create instance of NSFileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
//create an array and store result of our search for the documents directory in it
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//create NSString object, that holds our exact path to the documents directory
NSString *documentsDirectory = [paths objectAtIndex:0];
//add our image to the path
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"insta.igo"]];
//finally save the path (image)
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
CGRect rect = CGRectMake(0 ,0 , 0, 0);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndImageContext();
NSString *fileNameToSave = [NSString stringWithFormat:#"Documents/insta.igo"];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:fileNameToSave];
NSLog(#"jpg path %#",jpgPath);
NSString *newJpgPath = [NSString stringWithFormat:#"file://%#",jpgPath];
NSLog(#"with File path %#",newJpgPath);
NSURL *igImageHookFile = [[NSURL alloc]initFileURLWithPath:newJpgPath];
NSLog(#"url Path %#",igImageHookFile);
self.documentController = [UIDocumentInteractionController interactionControllerWithURL:igImageHookFile];
[self.documentController setDelegate:self];
[self.documentController setUTI:#"com.instagram.exclusivegram"];
[self.documentController presentOpenInMenuFromRect:rect inView:self.view animated:YES];
} else {
NSLog (#"Instagram not found");
}
It's probably worth mentioning I've already configured the URL schemes in the info.plist as required with the iOS9 changes.
The UIDocumentInteractionController does appear, and has the option 'Copy to Instagram'. Pressing this option just leads to the controller being dismissed, with no log messages or breakpoints being called on the controller's delegate (set to self; the view controller).
If anyone has, or has had trouble with this, it would be great to hear your thoughts, or better yet, how it was solved.
Update
It's also worth mentioning, on an iOS8 device, the Document Interaction Controller shows an 'Open in Instagram' button. The iOS9 device shows a 'Copy to Instagram' button.
After changing this line of code:
NSURL *igImageHookFile = [[NSURL alloc] initFileURLWithPath:newJpgPath];
to this:
NSURL *igImageHookFile = [NSURL URLWithString:newJpgPath];
The Instagram-share function for iOS 9 is now working. It seems that the previous line of code, converting the NSString to an NSURL would place "--://file" at the end of the URL path, which doesn't seem to register well with iOS 9. Simply converting the NSString to NSURL without initialising as a file URL seems to work.
You have to add a new key to your Info.plist file; it's an iOS 9 change for URL schemes. Check out the first answer for this question: iOS 9 not opening Instagram app with URL SCHEME. And just FYI, iOS 9 changes the "Open in Instagram" title for the UIDocumentInteractionController to "Copy to Instagram." Not sure why.

NSDocumentDirectory files disappear in ios

I want to save a mp4 video in my folder but when I open again the app, this file is nil. But when I save the file, I can open it, so it seems that it disappears from the folder.
Save:
NSData *videoData = [NSData dataWithContentsOfURL:exportUrl];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tempPath = [documentsDirectory stringByAppendingFormat:#"/%#",videoName];
self.path_video_to_save = tempPath;
BOOL success = [videoData writeToFile:tempPath atomically:YES];
if (success)
NSLog(#"saved");
else
NSLog(#"not saved!!!!!!!!!!!!!!");
I get the success in true so it's ok and I can play my video well.
NSString *path_video = [dict objectForKey:#"path"]; //dictionary where I save the path, the same before and after closing app
NSData *videoData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:path_video]];
if (videoData == nil){
NSLog(#"DATA NULL");
}
else
NSLog(#"DATA OK");
NSLog(#"PATH:%#", path_video);
self.player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:path_video]];
and at this point it work fine.
But when I close and open again the app and I get the path, my app crash and I have the log "DATA NULL" I don't understand why when I close my app the file disappear... what's up?
thanks
This is because in iOS 8 + the name of the Application folder is renamed each time you launch it.
Check it in /Users/"your username"/Library/Developer/CoreSimulator/Devices/"device name"/data/Containers/Data/Application/"application name" (Test in simulator).
So, you have to save the path without the document directory. And when you are trying to retrieve the path you have to add the document directory before the path you saved previously.
Like let your custom folder name is "Save_Video" and file name is "video_01.mp4".
Your file saving path will be "Application document directory"/Save_Video/video_01.mp4
Then you have to store only "Save_Video/video_01.mp4"(in Database/ NSUserDefaults) and when you are retrieving the file the path should be
"Application document directory"/Save_Video/video_01.mp4

AVAudioPlayer suddenly no longer plays entire audio source

I am using an AVAudioPlayer to play audio in my app, and it worked for a while. Suddenly, it just stopped working and I cannot figure out why. I created the AVAudioPlayer at the class level in the .h file. This is the code I use to init the player
-(void)initAudio
{
NSURL *song = [[NSBundle mainBundle] URLForResource:#"Prelude" withExtension:#"m4a"];
NSError *error = nil;
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:song error:&error];
[_audioPlayer prepareToPlay];
}
I call this method in the initWithSize function. error is nil, and I have verified that the player object contains the actual audio file. The audio file plays back fine in my OS environment and I have tried adding it to the build phase compile sources just to be safe, even though beforehand it worked fine without it explicitly there. When I trigger the play event, it will play the first snippet of the audio and then nothing. I log the current time of the player and it is 0. Everything else about the app is continuing on and functions without issue. I do not interfere with the avaudioplayer object in any way except to play/pause/preparetoplay.
I am completely stumped as it worked fine and then suddenly no longer works. I have tried to clean the project, I have even dumped the derivedData.
Any ideas?
I think your player has an error when you try to play the song.
You need to check the error first.
In my opinion, it seems like OSStatus error -43.
When you update an app, file path can be changed.
For example,
old path : /var/mobile/Applications/F28E0C2C-4AE2-4C9D-906F-414AE1669D90/Documents/AAA.mp3
new path: var/mobile/Applications/6086783B-A410-42C3-9BAE-7BA755D0E528/Documents/AAA.mp3
Try this code instead:
NSError *error;
NSURL *song = [[NSBundle mainBundle] URLForResource:#"Prelude" withExtension:#"m4a"];
_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:song error:&error];
if(error){
NSLog(#"[error localizedDescription] %#", [error localizedDescription]);
NSString *fileName = [[song absoluteString] lastPathComponent]; //this code is just example. get your fileName like "AAA.m4a"
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", docDirPath , fileName];
_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:filePath] error:&error];
}
_audioPlayer.delegate = self;
[_audioPlayer prepareToPlay];
[_audioPlayer play];
}
I hope this will help you.
Cheers

MPMoviePlayerController video not playing

I used MPMoviePlayerController in my application.
I got the right URL but MPMoviePlayer does not play video it shows only black screen.
My code is as below:
[video setImage:[UIImage imageNamed:#"video_active.png"] forState:UIControlStateNormal];
NSString *filename=[NSString stringWithFormat:#"%#.mp4",[appdel.TempVideoUrl valueForKey:tag]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:filename];
NSURL *movieURL = [NSURL fileURLWithPath:filePath] ;
theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
theMovie.view.frame = CGRectMake(106, 18, 216, 235);
[uploadview addSubview:theMovie.view];
// Play the movie.
[theMovie pause];
I got the URL like this:
file://localhost/var/mobile/Applications/6E1D4CB7-A08D-438B-9FE7-E2FD9B7B5EEC/Documents/136_1355227629.mp4
Add [theMovie prepareToPlay]; before calling [theMovie play];.
prepareToPlay
Prepares a movie player for playback. (required)
- (void)prepareToPlay
Discussion
If a movie player is not already prepared to play when you call the
play method, that method automatically calls this method. However, to
minimize playback delay, call this method before you call play.
Calling this method may interrupt the movie player’s audio session.
For information on interruptions and how to resond to them, see Audio
Session Programming Guide. Availability
Available in iOS 3.2 and later.
Declared In MPMediaPlayback.h
Also you can use isPreparedToPlay for checking whether a movie player is ready to play.
Please refer this link for more.

MPMoviePlayerController doesn't play from Documents folder

Desperated.
Hello everybody!
I am having some issues with MPMoviePlayerController.
I've made it working with videos from NSBundle. But that's not what I need. I need to play it from Documents directory, because that is the place I store the recorded videos, wich URLs are stored in CoreData. but lets leave this aside, and simplify the code to its minimum needed. This code actually WORKS if using the contentURL, wich leads to NSBundle. After it, what I do to get to the docs place.
What I do:
NSURL *contentURL = [[NSBundle mainBundle] URLForResource:#"Oct_08_2012_10_00_51" withExtension:#"mp4"]; // this works
NSString* docPath = [NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString * docaPathFull = [NSString stringWithFormat:#"%#%#", docPath, #"/Oct_08_2012_10_00_51.mp4"];
NSURL * docUrl= [NSURL URLWithString: docaPathFull];
BOOL ex = [[NSFileManager defaultManager] fileExistsAtPath:docaPathFull];
NSLog(#"file exists: %d, path using docPath: %#",ex, docaPathFull);
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:docUrl];
player.shouldAutoplay = YES;
player.controlStyle = MPMovieControlStyleEmbedded;
[player.view setFrame: self.thumbButton.bounds];
[player prepareToPlay];
[self.view addSubview: player.view];
[player play];
What we have:
2012-10-08 13:14:43.532 Voto[11968:907] file exists: 1, path using docPath: /var/mobile/Applications/07B8574A-A3BA-4B23-BB3F-995B33A01B95/Documents/Oct_08_2012_10_00_51.mp4
2012-10-08 13:14:43.907 Voto[11968:907] content URL: file://localhost/var/mobile/Applications/07B8574A-A3BA-4B23-BB3F-995B33A01B95/Voto.app/Oct_08_2012_10_00_51.mp4
2012-10-08 13:14:44.265 Voto[11968:907] doc URL: /var/mobile/Applications/07B8574A-A3BA-4B23-BB3F-995B33A01B95/Documents/Oct_08_2012_10_00_51.mp4
2012-10-08 13:14:45.343 Voto[11968:907] [MPAVController] Autoplay: Disabling autoplay for pause
2012-10-08 13:14:45.344 Voto[11968:907] [MPAVController] Autoplay: Disabling autoplay
2012-10-08 13:14:46.518 Voto[11968:907] [MPAVController] Autoplay: Skipping autoplay, disabled (for current item: 1, on player: 0)
2012-10-08 13:14:46.540 Voto[11968:907] [MPAVController] Autoplay: Enabling autoplay
2012-10-08 13:14:46.554 Voto[11968:907] [MPAVController] Autoplay: Likely to keep up or full buffer: 0
2012-10-08 13:14:46.555 Voto[11968:907] [MPAVController] Autoplay: Skipping autoplay, not enough buffered to keep up.
2012-10-08 13:14:46.557 Voto[11968:907] [MPAVController] Autoplay: Enabling autoplay
2012-10-08 13:14:46.567 Voto[11968:907] [MPCloudAssetDownloadController] Prioritization requested for media item ID: 0
2012-10-08 13:14:46.871 Voto[11968:907] [MPAVController] Autoplay: Enabling autoplay
So, the file exists...
Questions i've looked through:
MPMoviePlayer load and play movie saved in app documents
MPMoviePlayerController does not work with movie in documents folder
MPMoviePlayerViewController play movie from Documents directory - objective-c
I also checked ut with class reference, nothing specific about playing from Documents.
My projects settings:
using latest iOS 6,
Deployment target 5.0
Testing on both iOS6 iPhone simulator and an iPad with iOS 6.
If i forgot to add something, please remind me, I will do it immediately.
Please, help! :)
Well you'r not building the file URL the correct way, you should do it like this:
NSString *docPath = [NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *docaPathFull = [docPath stringByAppendingPathComponent:#"/Oct_08_2012_10_00_51.mp4"];
NSURL *docUrl= [NSURL fileURLWithPath:docaPathFull];
You should add directories and file to a path with the stringByAppendingPathComponent method of NSString;
Also when creating the file URL use fileURLWithPath: on NSURL, this willl create a correct NSURL for the giving path.
The most common mistake that everyone do is all use
NSURL *fileURL = [NSURL URLWithString:mVidPath];
^^^^^^^^^^^^^
instead of
NSURL *fileURL = [NSURL fileURLWithPath:mVidPath];
^^^^^^^^^^^^^^^
-(IBAction)playVideo
{
NSURL *vedioURL;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSLog(#"files array %#", filePathsArray);
NSString *fullpath;
for ( NSString *apath in filePathsArray )
{
fullpath = [documentsDirectory stringByAppendingPathComponent:apath];
vedioURL =[NSURL fileURLWithPath:fullpath];
}
NSLog(#"vurl %#",vedioURL);
MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:vedioURL];
[player.view setFrame: self.view.bounds];
[player.moviePlayer prepareToPlay];
[self.view addSubview:player.view];
player.moviePlayer.controlStyle = MPMovieControlStyleDefault;
player.moviePlayer.shouldAutoplay = YES;
[player.moviePlayer setFullscreen:YES animated:YES];
[player.moviePlayer play];
[self presentMoviePlayerViewControllerAnimated: player];
}
Don't forget to add MediaPlayer.framework and
#import < MediaPlayer/MediaPlayer.h>
in your respective code.
Good Luck!!!

Resources