3

I am trying to access video data from ALAssets library using the below code

        ALAssetRepresentation *rep = [asset defaultRepresentation];
        Byte *buffer = (Byte*)malloc(rep.size);
        NSError *error = nil;
        NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:&error];
        NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

It works fine for small video as well as pictures, But if am trying to get a large video, the code crashes saying

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:]: absurd length: 4294967295, maximum size: 2147483648 bytes'

I don't have an idea what's going on. Any one any thoughts?

Thanks in advance!

Advaith
  • 1,087
  • 3
  • 12
  • 31

2 Answers2

1

I found the solution. I guess the crash may be due to huge memory spike when we upload large files, because I am buffering data. Now I read file data as 5 MB chunks and this fix the crash. I am pasting my code below.

- (NSData *)getDataPartAtOffset:(NSInteger)offset  {
__block NSData *chunkData = nil;
if (fileAsset_){
    static const NSUInteger BufferSize = PART_SIZE; // 5 MB chunk
    ALAssetRepresentation *rep = [fileAsset_ defaultRepresentation];
    uint8_t *buffer = calloc(BufferSize, sizeof(*buffer));
    NSUInteger bytesRead = 0;
    NSError *error = nil;

    @try
    {
        bytesRead = [rep getBytes:buffer fromOffset:offset length:BufferSize error:&error];
        chunkData = [NSData dataWithData:[NSData dataWithBytesNoCopy:buffer length:bytesRead freeWhenDone:NO]];
    }
    @catch (NSException *exception)
    {
        free(buffer);
        chunkData = nil;
        // Handle the exception here...
    }

    free(buffer);
} else {
    NSLog(@"failed to retrive Asset");
}
return chunkData;

}

And I I'll call this function as

   int offset = 0; // offset that keep tracks of chunk data

  do {
        @autoreleasepool {
            NSData *chunkData = [self getDataPartAtOffset:offset];;

            if (!chunkData || ![chunkData length]) { // finished reading data
                break;
            }

            // do your stuff here

            offset +=[chunkData length];
        }
    } while (1);
Advaith
  • 1,087
  • 3
  • 12
  • 31
1

chilitechno's bit here worked for me.

Community
  • 1
  • 1
Morkrom
  • 578
  • 7
  • 26