14

I am not able to retrieve NSData from the url that I get from ALAsset

Below is the code I tried:- I always get NSData as nil.

 NSData *webData = [NSData dataWithContentsOfURL:[asset defaultRepresentation].url];

I also tried something like this

 NSData *webData1 = [NSData dataWithContentsOfURL:[[asset valueForProperty:ALAssetPropertyURLs] valueForKey:[[[asset valueForProperty:ALAssetPropertyURLs] allKeys] objectAtIndex:0]]];

The url that I get from the ALAsset:-

assets-library://asset/asset.MOV?id=1000000116&ext=MOV

I have tried this below link which works but I need to unnecessary write to a temp location which is very time consuming.

Getting video from ALAsset

Any hint in right direction would be highly appreciated.

Waiting for your replies

Community
  • 1
  • 1
Ekra
  • 3,241
  • 10
  • 41
  • 61

2 Answers2

61

try this code:-

ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc((NSUInteger)rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:(NSUInteger)rep.size error:nil];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
codrut
  • 810
  • 10
  • 19
Leena
  • 2,678
  • 1
  • 30
  • 43
  • thanks it worked :) I hope that since you r using dataWithBytesNoCopy: freeWhenDone: we don't need to free the "buffer" explicitly? – Ekra Jan 10 '12 at 11:02
  • 2
    What if the video is not in the ALAssetLibrary, i.e. it was generated by the app or imported using UIImagePickerController and saved in the Documents area? Is there a way to do this without involving the ASAssetLibrary framework? – eddy Jan 17 '13 at 22:48
  • @eddy the question is for ALAssetLibrary so accordingly i replied now your question is if video is in documents directory then use this command NSData *aVideoData = [[NSData alloc]initWithContentsOfFile:aVideoPath]; – Leena Jan 18 '13 at 04:49
  • you might as well use an NSMutableData's buffer itself rather than malloc'ing one and then have NSData take it – user102008 Feb 15 '14 at 00:41
  • invalid attempt to access past the lifetime of its owning ALAssetsLibrary I am receiving this error. – Salman Khakwani Apr 11 '14 at 18:48
  • This doesn't work: error: can't allocate region. This error shows up after an exception is caught at the nsdata line. – pedroremedios Jun 05 '14 at 12:30
  • How to use it in swift – Hamza Ansari Oct 23 '15 at 07:15
  • It would be better if you start using Photos Framework as this library is deprecated in iOS 9.0. – Leena Oct 23 '15 at 07:26
  • @Leena Hey Leena can you give reference links or any tutorial to do this kind of stuff in iOS 9.0 using Photos Framework – Mubin Mall Mar 14 '16 at 11:04
  • 1
    @TheMall please refer this link http://stackoverflow.com/questions/26152396/how-to-access-nsdata-nsurl-of-slow-motion-videos-using-photokit – Leena Mar 14 '16 at 12:06
17

Byte buffer = (Byte)malloc(rep.size); if the rep.size is so big, maybe 300M,that will be crash. so try this code:

+ (BOOL)writeDataToPath:(NSString*)filePath andAsset:(ALAsset*)asset
{
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
    NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:filePath];
    if (!handle) {
        return NO;
    }
    static const NSUInteger BufferSize = 1024*1024;

    ALAssetRepresentation *rep = [asset defaultRepresentation];
    uint8_t *buffer = calloc(BufferSize, sizeof(*buffer));
    NSUInteger offset = 0, bytesRead = 0;

    do {
        @try {
            bytesRead = [rep getBytes:buffer fromOffset:offset length:BufferSize error:nil];
            [handle writeData:[NSData dataWithBytesNoCopy:buffer length:bytesRead freeWhenDone:NO]];
            offset += bytesRead;
        } @catch (NSException *exception) {
            free(buffer);

            return NO;
        }
    } while (bytesRead > 0);

    free(buffer);
    return YES;
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211
riven
  • 1,476
  • 2
  • 12
  • 15