Get mp3 as NSData - iphone

I want to play a mp3 from my server with AVAudioPlayer. I am trying to do it by using
initWithData:(NSData *) error:(NSError **)
To do this I need to convert the mp3 to NSData then pass the NSData into my player.
How do I convert the mp3 to NSData.

NSData has an -initWithContentsOfURL: (or +dataWithContentsOfURL:) method you could use.
Or, you could use NSURLConnection to download your MP3 as NSData.
I'd advise the second method, because it can be used asynchronously and doesn't block the main thread, unlike NSData's -initWithContentsOfURL:

When you download it from the server, conveniently, you already have an NSData object. Did you try starting the player with that?

Related

Getting current MP3 filename with AVAudioPlayer

I've got AVAudioPlayer playing some MP3 in background. AVAudioPlayer is singleton instance shared across app. Is it possible to detect current filename of MP3 being played at a time? I can't see any method in delegate, there's duration, currentTime but nor filename or something like this.
Other thing I consider if this method fails is reading MP3 tags and get track name from it - is it possible with AVAudioPlayer?
Thanks in advance!
You can get filename of current playing media in AVAudioPlayer like this:
NSString *mediaFileName = [[youAVAudioPlayer.url absoluteString] lastPathComponent];
Note condition is that: Returns nil if the audio player was not initialized with a URL.
If you initialize the AVAudioPlayer with a url, you can read that property. AVAudioPlayer does not read the tags in the MP3 file, so it will not help with that.
You may find AVAsset interesting as a way to get metadata from an MP3. Quick Tutorial.

ASIHTTPRequest - Uploading files from the camera roll

I currently need to upload large files from an iDevice to a server API. For this I'm attempting to use the ASIHTTPRequest library as it automatically supports uploading large files in queued chunks (before this I simply created an NSData instance with the bytes for the entire file at once and attached this to the POST message, but this causes the application to crash on larger files due to an excessive amount of RAM usage).
The problem is that when you need to upload files and add a file to the HTTP Post message, this is the syntax you need to use:
[theUploadRequest setFile:#"" forKey:#"videoupload"];
setFile requires a file path in a string format. The problem I'm currently having is that it does not seem like you are allowed to simply take the file path from a file which is not in your applications sandbox? Since I need to upload a file which is not in my application, but outside of it in the standard cameraroll.
I tried to make this quick test to see if I could create an NSData object and fill it with data from a file in the cameraroll, providing a path to it like this:
NSData *testData = [NSData dataWithContentsOfURL:theContent.defaultRepresentation.url];
NSLog(#"THE SIZE OF THE TEST DATA: %i", testData.length);
Note that "theContent" is an instance of an ALAsset, and is a file retrieved from the cameraroll. The result of this is simply a length of 0, which I suppose means you can't simply do that.
Is there any way around this? Or would I have to somehow import the video file into the application's sandbox?
So if I understand correctly, you want to upload stuff straight from the camera roll? Based on the docs I'd say the important piece of code you need is:
NSString *filePath = [[info objectForKey:
UIImagePickerControllerMediaURL] path];
The info dictionary is passed to your media picker's delegate:
- (void) imagePickerController: (UIImagePickerController *) picker
didFinishPickingMediaWithInfo: (NSDictionary *) info;
You should then be able to use that filePath in your call to setFile.
Take a look here probably you'll find something useful.
Hope this helps.
EDIT:
For something simpler you can use the bit of code posted in this answer
Implying that you need to copy the file somewhere before uploading it, especially if it is a big one.

iPhone, how does one read an image from the photo library as NSData?

On the iPhone I saved an image to the photo library with modifications (appending data after the image code) using the assest library to save the NSData directly to the photo library. Now I want to read the image back from the photo library as an NSData to read it. If I read it as a UIImage, it changes the data inside the image.
How can I read the photo from the photo library as NSData? I tried looking into the reference URL in 4.1 but no luck.
Edit: I edited to explain why I'm saving it as an NSData. The URL method in the answers works if you just want pure NSData, but does not help in the context that I am asking.
Edit 2: The answer with the getBytes was the answer that did it for me. The code I used was:
int8_t *bytes = malloc([representation size]);
NSUInteger length = [representation getBytes:bytes fromOffset:0 length:[representation size] error:&error];
This was able to get me everything inside the file which gave me the image code PLUS what I added in NSData form.
Edit 3:
Is there a way to do this now in iOS 10 with the PHPhotoLibrary which replaces AssetLibrary? I need the image in NSData being the original RAW image with no modifications.
You should look into the getBytes method of ALAssetRepresentation.
This gives you the original RAW image data of your image and also makes it possible to use a buffer to process the image instead of reading the image into memory all at once.
And of course you can always generate NSData from the getBytes method.
Cheers,
Hendrik
If you already have your ALAsset, you should be able to get an NSData of the default representation using the following:
NSData *data = [NSData dataWithContentsOfURL:[[asset defaultRepresentation] url]];

Progressive download using Matt Gallagher's audio streamer

I'm a completely n00b when talking about audio. I'm using Matt Gallagher's audio streamer on my radio app. How may I use progressive download? Also, ExtAudioFile is a good idea too :)
Edit:
Used this:
length = CFReadStreamRead(stream, bytes, kAQDefaultBufSize);
if(!data)
data =[[NSMutableData alloc] initWithLength:0];
[data appendData:[NSData dataWithBytes:bytes length:kAQDefaultBufSize]];
Now I can save the audio data using writeToFile:atomically: NSData method, but the audio won't play. Also, if I try to load it on a AVAudioPlayer, I get an error.
I'm trying to do something similar. I ended up doing it like this:
length = CFReadStreamRead(stream, bytes, kAQDefaultBufSize);
// Save data
if (saveLocation){
NSFileHandle *mp3 = [NSFileHandle fileHandleForWritingAtPath:saveLocation];
[mp3 seekToEndOfFile];
[mp3 writeData:[NSData dataWithBytes:bytes length:length]];
[mp3 closeFile];
}
Some problems to be aware of. You should make sure that the file at saveLocation exists. I made a new initializer with the mp3 url and saveLocation path, and put the check there. Also, be aware that if the user performs a seek in the mp3 this will not realize that. Basically, it will record exactly what gets played back. It is not smart enough to realize that the playback position moved. However, if you just start the stream, and allow it to finish the whole mp3 (assuming that it has an end) it should save just fine.

ObjC - Post a UIImage by using NSData and NSURLRequest?

I'm trying to post an image to TwitPic.com using their API.
However, I have never posted an image using HTTPPOST or however else before.
Anybody enlighten me to how I can post NSData from a UIImage using their api?
TwitPic is expecting a multi-part form data. There is a great open source library called ASIHTTPRequest.
You can use their APIs and post your image as multi-part/form-data.
See below for the sample.
http://allseeing-i.com/ASIHTTPRequest/How-to-use
Use the UIImagePNGRepresentation function or its JPEG equivalent to turn a UIImage into an NSData:
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIKitFunctionReference/Reference/reference.html#//apple_ref/c/func/UIImagePNGRepresentation
#Jamie:
Try:
[request setData:twitpicImage forKey:#"media"];
If the image view is actually displaying an image that is stored in a file on disk, use:
[request setFile:theImagePath forKey:#"media"];
This way, ASIHTTPRequest will stream the image data from disk, so you don't have to keep an NSData instance in memory.
Ta
Ben
Instead of setPostValue for the image, use setData instead.