How to find the photo gallery path URL in iOS - ios

I'm making an iOS app where the user will be able to record a video and as soon as he finish such record, he can send that video to a server.
So far so good!
But to find the recorded video is being a headache! How can I find the proper URL for the recorded video?
During my tests, I have saved a video in the Supporting Files folder and my code is the following
NSString *url = [[NSBundle mainBundle] pathForResource:#"trailer_iphone" ofType:#".m4v"];
NSData *data = [NSData dataWithContentsOfFile:url];
So what could I do to replace that URL for the one in the photo gallery?
In the Apple Developer web site is showing that we can use the AVAsset in order to access the photo gallery. so I copied into my code and I'm trying to figure this out!
//Copied from Apple website
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
// For this example, we're only interested in the first item.
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:0]
options:0
usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
// Do something interesting with the AV asset.
//My last code
//NSString *url = [[NSBundle mainBundle] pathForResource:#"trailer_iphone" ofType:#".m4v"];
NSData *data = [NSData dataWithContentsOfURL:url];

Use UISaveVideoAtPathToSavedPhotosAlbum Official Documentation

For recording a video and send this recorded video file to server you can use AVFoundation framework as follow: AVFoundation Video Recording
AVCaptureMovieFileOutput *movieFileOutput;
AVCaptureMovieFileOutput implements the complete file recording interface declared by AVCaptureFileOutput for writing media data to QuickTime movie files.
for starting a recoding you have to call below code with passing output file path as parameter with delegate.
//Define output file path.
NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:["recordVideo" stringByAppendingPathExtension:#"mov"]];
//Start recording
[movieFileOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:filePath] recordingDelegate:self];
And after a some time if you want to stop recording then call
//Stop a recording
[movieFileOutput stopRecording];
after a stop recording delegate methode of AVCaptureFileOutputRecordingDelegate is call so, there you can get recorded file path.
#pragma mark - AVCaptureFileOutputRecordingDelegate Methods.
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(#"Did finish recording, error %# | path %# | connections %#", error, [outputFileURL absoluteString], connections);
//call upload video APi
[self VideoUploadApi];
}

Related

iOS: Get Audio from AVAudioRecorder

Disclaimer New to AVAudioRecorder
What I'm doing I'm working on an app that uses the iPhone microphone to record sound. After the sound is recorded, I need to convert the sound (should be AVAsset, right?) into NSData to send to our backend.
What's the issue The issue is I am not sure how to "get" the audio that is supposed to be recorded with the AVAudioRecorder. AVAudioRecorder has a delegate method called - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag. I would have expected the actually AVAsset that contains the audio to be passed from this delegate method, but it does not. What it does give me is the aRecorder object that has a .url property on it. When I NSLog the url from the passed aRecorder, it shows up. In fact I can NSLog the length of the file in the code below:
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{
DLog (#"audioRecorderDidFinishRecording:successfully: %#",aRecorder);
AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:aRecorder.url options:nil];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
NSLog(#"asset length = %f", audioDurationSeconds); //Logs 7.051 seconds, so I know it's "there".
self.audioURL = aRecorder.url;
}
Problem When I pass self.audioURL to the next viewController's self.mediaURL and try to grab the file from the AssetLibrary (similarly to how I did before), the asset is not returned from the AssetLibrary (even though when I po self.mediaURL it indeed logs the correct url:
if (self.mediaURL) {
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:self.mediaURL resultBlock:^(ALAsset *asset) {
if (asset) {
// This block does NOT get called...
ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc((long)rep.size);
NSUInteger buffered =[rep getBytes:buffer fromOffset:0.0 length:(long)rep.size error:nil];
NSMutableData *body = [[NSMutableData alloc] init];
body = [NSMutableData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
[dataToSendToServer setObject:body forKey:#"audioData"];
}
} failureBlock:^(NSError *error) {
NSLog(#"FAILED TO ACCESS AUDIO FROM URL: %#!", self.mediaURL);
}];
}
else {
NSLog(#"NO AUDIO DATA!");
}
}
Because I am new to AVAudioRecorder, perhaps I am just not designing this flow correctly. Could anyone help me out in getting the actual audio data.
Thanks!
AVAudioRecorder records to a file, not to the Asset Library.
So you can simply read the data from that file.

Move Photos to other folder ios

How to move photos from one folder to another folder in iphone?
I have fetched all photos from camera roll. Now, i want some of them to move to some specific folder in iphone. Is it possible to do?
Yes you can, sort of. As in you can access the user media library and you can copy them to you apps sandbox environment. Since iOS has no public filesystem you will not be able to copy/move them directly to some directory.
The images in the user media librarycan accessed with the AssetsLibrary.
You can add new groups to the user media library and add picture to this group. But you can not move, delete or replace existing images in the user media library.
You can Move All files to Under Documents folder or Caches Folder.
You Can Create Folder Programatically in iPhone Photos.
Please check the below Link for Reference:
iphone: copy or move file from document directory folder
here is some (untested) code for copying the thumbnail & full size version of a photo called 'name' from the shared camera roll to the documents directory in your app's sandbox:
NSString *newNameThumb = #"newThumbName.png";
NSString *newName = #"newFullsizeName.png";
NSString *name = #"nameOfSharedPhotoToMove.png";
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just photos.
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
// Chooses the photo at the last index
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
if([representation.filename isEqualToString:name]){
UIImage *latestPhoto = [UIImage imageWithCGImage:[alAsset thumbnail]];
NSData *imageData = UIImagePNGRepresentation(latestPhoto);
UIImage *latestFullPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
NSData *imageFullData = UIImagePNGRepresentation(latestFullPhoto);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* newThumbPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:newNameThumb];
[imageData writeToFile:newThumbPath atomically:YES];
NSString* newFullPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:newName];
[imageFullData writeToFile:newFullPath atomically:YES];
*stop = YES; *innerStop = YES;
});
}
}
}];
} failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(#"No photos found or permission denied");
}];
Try this:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSURL *oldDir = [NSURL fileURLWithPath:#"/tmp/mynewdir"];
NSURL *newDir = [NSURL fileURLWithPath:#"/tmp/mynewdir2"];
[filemgr moveItemAtURL: oldDir toURL: newDir error: nil];
Hope this helps.. :)

ALAssetLibrary for audio

I am trying to load all the files(audio, video and images) in my application using ALAssetLibrary by this piece of code:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate everything.
[group setAssetsFilter:[ALAssetsFilter allAssets]];
// Accessing all the assets.
for (int i = 0;i<[group numberOfAssets] ; i++) {
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:i] options:0 usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
NSLog(#"%#",url);
AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
//Doing some stuff with assets
}
}];
}
}
failureBlock: ^(NSError *error) {
NSLog(#"No groups");
}];
However, this only loads video and images, not the audio files. How can I do that?
Regarding Apple.Developer ALAsset documentaion ,An ALAsset object represents a photo or a video managed by the Photo application.
Assets can have multiple representations, for example a photo which was captured in RAW and JPG. Different representations of the same asset may have different dimensions.
So i think ,ALAssetsLibrary will not retrieve what you need :)

playing mp3 from nsbundle

SETUP
I put a mp3 into my bundle just for testing, i will have them download into the documents directory. But for now i am going to work off the bundle.
I have found a couple tutorials, but not anything for what i need. The below is definitely a mix of a couple solutions and probably not the best approach.
Problem
How do i pull a song out of my bundle and play within the app?
//Create an instance of MPMusicPlayerController
MPMusicPlayerController* myPlayer = [MPMusicPlayerController applicationMusicPlayer];
//Read the song off the bundle.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"LittleMoments" ofType:#"mp3"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
if (myData) {
//This wont work for me because i don't want to query songs from the iPod,
i want to play songs out of the Bundle.
//Create a query that will return all songs by The Beatles grouped by album
MPMediaQuery* query = [MPMediaQuery songsQuery];
[query addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:#"The Beatles" forProperty:MPMediaItemPropertyArtist comparisonType:MPMediaPredicateComparisonEqualTo]];
[query setGroupingType:MPMediaGroupingAlbum];
//Pass the query to the player
[myPlayer setQueueWithQuery:query];
/////**** how can i get nsdata into MyPlayer?*****//////
//Start playing and set a label text to the name and image to the cover art of the song that is playing
[myPlayer play];
}
Try playing the file with AVAudioPlayer
AVAudioPlayer *audioPlayer = [(AVAudioPlayer*)[AVAudioPlayer alloc] initWithData:myData error:nil];
audioPlayer.delegate = self;
[audioPlayer play];

How can I keep track of media created/chosen by UIImagePickerController?

I'm building an iOS app that allows the user to upload videos from UIImagePickerController, either by recording or choosing them from the Camera Roll, as well as also play the chosen video. My question is, how would I go about keeping a reference to the videos that have been chosen this way? I want to do this so that if the video is still present on the device, I can use the local file rather than streaming the uploaded file.
When
imagePickerController:didFinishPickingMediaWithInfo:
returns, the URL in:
[info objectForKey:UIImagePickerControllerMediaURL];
Is in the format of: "file://localhost/private/var/mobile/Applications/ /tmp//trim.z2vLjx.MOV"
I'm lead to believe that the "/tmp/" directory is temporary, and therefore not suitable to save the URL for that location.
I can get all of the videos on the device through ALAssetsLibrary, but because I don't have a way of distinguishing them, this doesn't help me. I've been attempting to use:
[result valueForProperty:ALAssetPropertyDate];
To distinguish the videos, but I need a way of getting the creation date from UIImagePickerController for this to be useful.
I've finally managed to find a solution:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if(CFStringCompare((CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo)
{
//Dismiss the media picker view
[picker dismissModalViewControllerAnimated:YES];
//Get the URL of the chosen content, then get the data from that URL
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *webData = [NSData dataWithContentsOfURL:videoURL];
//Gets the path for the URL, to allow it to be saved to the camera roll
NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (moviePath))
{
ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
//The key UIImagePickerControllerReferenceURL allows you to get an ALAsset, which then allows you to get metadata (such as the date the media was created)
[lib assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) {
NSLog(#"created: %#", [asset valueForProperty:ALAssetPropertyDate]);
} failureBlock:^(NSError *error) {
NSLog(#"error: %#", error);
}];
}
}
As per usual, the solution was found by reading the documentation a little more thoroughly. Hopefully this'll help someone else out at some point.
You can easily keep a record of the videos you have on the device. Either by keeping a data base (which I think would be too much) or just a file with a list of your videos. In that list, you could have the URL of the assets.

Resources