Change program from getting music from iTunes to local file using URL - iphone

I am currently trying to make an app stream raw data from mic over mulipeer connectivity.
I have been using this tutorial as a base https://robots.thoughtbot.com/streaming-audio-to-multiple-listeners-via-ios-multipeer-connectivity
Now however I am struggling with changing the URL from itunes library to my local file.
I am no advanced programmer and this is some kind of summer project.
When the program is getting music from itunes library it uses this code:
- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
[self dismissViewControllerAnimated:YES completion:nil];
if (self.outputStreamer) return;
self.song = mediaItemCollection.items[0];
NSMutableDictionary *info = [NSMutableDictionary dictionary];
info[#"title"] = [self.song valueForProperty:MPMediaItemPropertyTitle] ? [self.song valueForProperty:MPMediaItemPropertyTitle] : #"";
info[#"artist"] = [self.song valueForProperty:MPMediaItemPropertyArtist] ? [self.song valueForProperty:MPMediaItemPropertyArtist] : #"";
MPMediaItemArtwork *artwork = [self.song valueForProperty:MPMediaItemPropertyArtwork];
UIImage *image = [artwork imageWithSize:self.albumImage.frame.size];
if (image)
info[#"artwork"] = image;
if (info[#"artwork"])
self.albumImage.image = info[#"artwork"];
else
self.albumImage.image = nil;
self.songTitle.text = info[#"title"];
self.songArtist.text = info[#"artist"];
[self.session sendData:[NSKeyedArchiver archivedDataWithRootObject:[info copy]]];
NSArray *peers = [self.session connectedPeers];
if (peers.count) {
self.outputStreamer = [[TDAudioOutputStreamer alloc] initWithOutputStream:[self.session outputStreamForPeer:peers[0]]];
[self.outputStreamer streamAudioFromURL:[self.song valueForProperty:MPMediaItemPropertyAssetURL]];
[self.outputStreamer start];
But I want it to get music from the recorder:
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:nil];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
I have been struggling with this for a while now and would appreciate any kind of help!

Related

Attach image to message composer in ios 6

How to attach an image to native message composer in ios6? I want to implement the same sharing via message function we can see in default photos app.
Thanks
For Mail:
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
NSData *exportData = UIImageJPEGRepresentation(pic ,1.0);
[mailController addAttachmentData:exportData mimeType:#"image/jpeg" fileName:#"Photo.jpeg"];
[self presentModalViewController:mailController animated:YES];
The only way is through email currently. Unless you want to create a own MMS gateway to allow your app to support MMS..
For Message:
After reading up, instead of using MFMessageComposeViewController,you could UIApplication sharedApplication.
Example:
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.persistent = YES;
NSData *data = UIImageJPEGRepresentation(pic ,1.0);
pasteboard.image = [UIImage imageWithData:data];
NSString *phoneToCall = #"sms: 123-456-7890";
NSString *phoneToCallEncoded = [phoneToCall stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSURL *url = [[NSURL alloc] initWithString:phoneToCallEncoded];
[[UIApplication sharedApplication] openURL:url];
Longpress and click on Paste and message will be pasted...
Hope this helps... pic refers to the UIImage you are passing...
{
NSMutableDictionary * attachment = [[NSMutableDictionary alloc]init];
[attachment setObject: UIImageJPEGRepresentation(imageView.image,0.5) forKey:#"attachmentData"];
[attachment setObject: #"productImage.jpeg" forKey:#"attachmentFileName"];
[attachment setObject: #"jpeg" forKey:#"attachmentFileMimeType"];
NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
[params setObject: #"subject" forKey:#"subject"];
[params setObject: #"matterText" forKey:#"matterText"];
[params setObject: [[NSMutableArray alloc]initWithObjects:attachment, nil] forKey:#"attachments"];
}
#pragma mark - Sharing Via Email Related Methods
-(void)emailInfo:(NSMutableDictionary*)info
{
if (![MFMailComposeViewController canSendMail])
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Email Configuration"
message:#"We cannot send an email right now because your device's email account is not configured. Please configure an email account from your device's Settings, and try again."
delegate:nil
cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
return;
}
MFMailComposeViewController *emailer = [[MFMailComposeViewController alloc] init];
emailer.mailComposeDelegate = self;
NSString * subject = [info objectForKey:#"subject"];
NSString * matterText = [info objectForKey:#"matterText"];
if(subject)
[emailer setSubject:subject];
if(matterText)
[emailer setMessageBody:matterText isHTML:NO];
NSMutableArray * attachments = [info objectForKey:#"attachments"];
if (attachments)
{
for (int i = 0 ; i < attachments.count ; i++)
{
NSMutableDictionary * attachment = [attachments objectAtIndex:i];
NSData * attachmentData = [attachment objectForKey:#"attachmentData"];
NSString * attachmentFileName = [attachment objectForKey:#"attachmentFileName"];
NSString * attachmentFileMimeType = [attachment objectForKey:#"attachmentFileMimeType"];
[emailer addAttachmentData:attachmentData mimeType:attachmentFileMimeType fileName:attachmentFileName];
}
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
emailer.modalPresentationStyle = UIModalPresentationPageSheet;
}
[self.navigationController.topViewController presentViewController:emailer animated:YES completion:nil];
}
I think you cant attach an image in the message composer. It is only possible in mail composer.

How to record a video clip in ipad app and store it in documents folder

I have training app i want that when user click recordVideo button camera should launch to record video, is there any way to do this in ipad app.I have done audio recording already i need to do video recording.
//for video..
#import <MobileCoreServices/MobileCoreServices.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/Mediaplayer.h>
#import <CoreMedia/CoreMedia.h>
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
NSArray *mediaTypes = [NSArray arrayWithObject:(NSString*)kUTTypeMovie];
picker.mediaTypes = mediaTypes ;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo ;
[self presentModalViewController:picker animated:NO];
[picker release];
}
else
{
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#" Camera Facility is not available with this Device" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}
for saving into Document folder & it also save in photo Library
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
//for video
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"video url-%#",videoURL);
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
NSString * videoName = [NSString stringWithFormat:#"student_%d_%d.mp4",stud_id,imgVidID];
videoPath = [documentsDirectory stringByAppendingPathComponent:videoName];
NSLog(#"video path-%#",videoPath);
[videoData writeToFile:videoPath atomically:YES];
NSString *sourcePath = [[info objectForKey:#"UIImagePickerControllerMediaURL"]relativePath];
UISaveVideoAtPathToSavedPhotosAlbum(sourcePath,nil,nil,nil);
}
Try this ::
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
[self dismissViewControllerAnimated:NO completion:nil];
NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
if ([type isEqualToString:(NSString *)kUTTypeVideo] || [type isEqualToString:(NSString *)kUTTypeMovie])
{
videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"found a video");
// Code To give Name to video and store to DocumentDirectory //
videoData = [[NSData dataWithContentsOfURL:videoURL] retain];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc] init] autorelease];
[dateFormat setDateFormat:#"dd-MM-yyyy||HH:mm:SS"];
NSDate *now = [[[NSDate alloc] init] autorelease];
theDate = [dateFormat stringFromDate:now];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"Default Album"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil];
NSString *videopath= [[[NSString alloc] initWithString:[NSString stringWithFormat:#"%#/%#.mov",documentsDirectory,theDate]] autorelease];
BOOL success = [videoData writeToFile:videopath atomically:NO];
NSLog(#"Successs:::: %#", success ? #"YES" : #"NO");
NSLog(#"video path --> %#",videopath);
}
}
Hopefully, It'll help you.
Thanks.
Just try it :
-(void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info
{
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:NO];
NSString *moviePath = [[info objectForKey: UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (moviePath)){
UISaveVideoAtPathToSavedPhotosAlbum (moviePath,self, #selector(video:didFinishSavingWithError:contextInfo:), nil);
}
}
-(void)video:(NSString*)videoPath didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo {
if (error) {
[AJNotificationView showNoticeInView:self.view type:AJNotificationTypeRed title:#"Video Saving Failed" linedBackground:AJLinedBackgroundTypeAnimated hideAfter:1.0];
}
else{
NSURL *videoURl = [NSURL fileURLWithPath:videoPath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURl options:nil];
AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generate.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 60);
CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err];
self.strUploadVideoURL = videoPath;
[imgPhoto setImage:[[[UIImage alloc] initWithCGImage:imgRef] autorelease]];
intWhenPushView = 2;
btnShare.enabled = YES;
btnFacebookShare.enabled = YES;
CGImageRelease(imgRef);
[generate release];
[asset release];
}
}

Change AVMetadataItem

I have some files, -m4a -mp4 -mp3 etc.
I want to change these details
AVMetadataItem
AVMetadataCommonKeyArtwork
AVMetadataCommonKeyArtist
I can do with AVAssetExportSession, But I need to change the directory. Is there a way I can write directly on the file please?
I found this program, but does not work :(
NSError *error;
AVAssetWriter *assetWrtr = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:self.path] fileType:AVFileTypeAppleM4A error:&error];
NSLog(#"%#",error);
NSArray *existingMetadataArray = assetWrtr.metadata;
NSMutableArray *newMetadataArray = nil;
if (existingMetadataArray)
{
newMetadataArray = [existingMetadataArray mutableCopy]; // To prevent overriding of existing metadata
}
else
{
newMetadataArray = [[NSMutableArray alloc] init];
}
AVMutableMetadataItem *item = [[AVMutableMetadataItem alloc] init];
item.keySpace = AVMetadataKeySpaceCommon;
item.key = AVMetadataCommonKeyArtwork;
item.value = UIImagePNGRepresentation([[UIImage alloc] initWithContentsOfFile:[[NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#".image"]]);
[newMetadataArray addObject:item];
assetWrtr.metadata = newMetadataArray;
[assetWrtr startWriting];
[assetWrtr startSessionAtSourceTime:kCMTimeZero];
change UIImagePNGRepresentation to UIImageJPEGRepresentation you need jpeg data not png.

Access device music files from iPhone app programmatically

I want to access music files which are available on the iPhone and get it listed (or) get the file into my iPhone application some delegats and start playing it. Is it possible to do it ? Similar to how we access images from device photo album using UIImagePickerController delegate methods.
Thank you!
You can reference MPMediaPickerController class. It functions same as UIImagePickerController class.
-(void)loadDeviceMusic{
MPMediaQuery *everything = [[MPMediaQuery alloc] init];
[everything addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithBool:NO] forProperty:MPMediaItemPropertyIsCloudItem]];
NSArray *itemsFromGenericQuery = [everything items];
for (MPMediaItem *song in itemsFromGenericQuery) {
NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVAsset *asset = [AVAsset assetWithURL:assetURL];
NSLog(#"SONGS URL=%#",assetURL);
if ([asset hasProtectedContent] == NO) {
MP3ObjectsClass *objMp3=[[MP3ObjectsClass alloc] init];
objMp3.mp3Url=[song valueForProperty:MPMediaItemPropertyAssetURL];
objMp3.mp3Duration=[song valueForProperty: MPMediaItemPropertyPlaybackDuration];
if([song valueForProperty: MPMediaItemPropertyTitle]){
objMp3.mp3Name=[song valueForProperty: MPMediaItemPropertyTitle];
}else{
objMp3.mp3Name=#"Unknown";
}
if([song valueForProperty: MPMediaItemPropertyArtist]){
objMp3.mp3ArtistName=[song valueForProperty: MPMediaItemPropertyArtist];
}else{
objMp3.mp3ArtistName=#"Unknown";
}
if([song valueForProperty: MPMediaItemPropertyAlbumTitle]){
objMp3.mp3AlbumTitle=[song valueForProperty: MPMediaItemPropertyAlbumTitle];
}else{
objMp3.mp3AlbumTitle=#"Unknown";
}
UIImage *mp3Image=[self getAlbumnArtWorkImage:assetURL];
if(mp3Image){
objMp3.mp3Image=mp3Image;
}else{
objMp3.mp3Image=[UIImage imageNamed:#"DefaultImage"];
}
[mp3Array addObject:objMp3];
}
}
}
-(UIImage *)getAlbumnArtWorkImage :(NSURL *)mp3Url{
AVAsset *asset = [AVURLAsset URLAssetWithURL:mp3Url options:nil];
UIImage *img = nil;
for (NSString *format in [asset availableMetadataFormats]) {
for (AVMetadataItem *item in [asset metadataForFormat:format]) {
if ([[item commonKey] isEqualToString:#"artwork"]) {
img = [UIImage imageWithData:[item.value copyWithZone:nil]];
}
}
}
return img;
}
*** MP3ObjectsClass is a NSObject class. Using above function you can access device music files from iPhone.
First import the AVFoundation/AVFoundation.h framework.
#import <AVFoundation/AVFoundation.h>
-(void)pickAudioFiles
{
MPMediaPickerController *soundPicker=[[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
soundPicker.delegate=self;
soundPicker.allowsPickingMultipleItems=NO;
[self presentViewController:soundPicker animated:YES completion:nil];
}
-(void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
MPMediaItem *item = [[mediaItemCollection items] objectAtIndex:0];
NSURL *url = [item valueForProperty:MPMediaItemPropertyAssetURL];
[mediaPicker dismissViewControllerAnimated:YES completion:nil];
AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url];
AVPlayer *player=[[AVPlayer alloc] initWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer=[AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame=CGRectMake(0, 0, 10, 10);
[self.view.layer addSublayer:playerLayer];
}
and play with [player play];
If you want to use AVAudioPlayer then import AudioToolbox/AudioToolbox.h

Error while recording video on iphone using AVFoundation

Im trying to record video using AVFoundation
I can save images but not video. When trying to save a video, I
got an error saying:
[AVCaptureMovieFileOutput startRecordingToOutputFileURL:recordingDelegate:] - no active/enabled connections.'
And here is my code:
session = [[AVCaptureSession alloc] init];
//session is global object.
session.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.imgV.bounds;
[self.imgV.layer addSublayer:captureVideoPreviewLayer];
AVCaptureDevice *device =[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
NSLog(#"start 3");
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
NSLog(#"Error");
}
[session addInput:input];
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[session addOutput:stillImageOutput];
aMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
[session addOutput:aMovieFileOutput];
[session startRunning];
[self performSelector:#selector(startRecording) withObject:nil afterDelay:10.0];
//[aMovieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:self];
//previously i used to do this way but saw people doing it after delay thought it might be taking some time to initialized so tried this way also.
}
- (void) startRecording
{
NSLog(#"startRecording");
NSString *plistPath;
NSString *rootPath;
rootPath= [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
plistPath = [rootPath stringByAppendingPathComponent:#"test.mov"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:plistPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:plistPath]) {
NSLog(#"file exist %s n url %# ",[rootPath UTF8String],fileURL);
}
[aMovieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:self];
}
Also I am trying to test this on Iphone 3G with IOs-4.1.
Also worth noting this can happen if you've set the session preset to 'photo'.
[session setSessionPreset:kCaptureSessionPresetPhoto];
Which should be:
[session setSessionPreset:kCaptureSessionPresetVideo];
You should be adding your outputs between a [AVCaptureSession beginConfiguration] and [AVCaptureSession commitConfiguration] pair.
This error can occur when you pass an object as a delegate using startRecordingToOutputFileURL:recordingDelegate: method, but this object does not have the
captureOutput:didStartRecordingToOutputFileAtURL:fromConnections: AVCaptureFileOutputRecordingDelegate method implemented.
Implement the AVCaptureFileOutputRecordingDelegate protocol. Make sure the path of video file is correct and the video file is not exist, as the movie file output does not overwrite existing resources.