Hey guys,
so with help last night in another thread, I was able to open an mjpeg file and go through it to get the data associated with the individual pictures making up the file. This is the code used for that:
When I run it, it appears to work properly. The image view ends up with a picture in it and the folder is full of 301 pictures. Problem is, the picture that ends up in the image view is not the last frame from the video and from earlier work, I think there should be about twice as many pictures. I added in the calls to NSLog to see what was going on and it ends up spitting this out at the end:
2011-02-10 17:57:24.494 Video Decoder[43585:a0f] Position: 17758931
2011-02-10 17:57:24.553 Video Decoder[43585:a0f] Position: 17819849
2011-02-10 17:57:24.554 Video Decoder[43585:a0f] *** -[NSConcreteData subdataWithRange:]: range {17880739, 17880744} exceeds data length 35675568
17 million isn't greater than 35 million, so it shouldn't be exceeding the data length? Is it that range can't hold numbers that big? If so, is there any way to change it so it can?
Thanks,
Dan
so with help last night in another thread, I was able to open an mjpeg file and go through it to get the data associated with the individual pictures making up the file. This is the code used for that:
Code:
// load video 1 into a data object
NSString *path = @"/path/to/the/file/Movies/video1.mjpeg";
NSData *vid1 = [[NSData alloc] initWithContentsOfFile:path];
long int position = 0;
long int pictureCount = 0;
long int size = 0;
const char *sizeBytes;
NSRange range;
NSString *imagePath = @"";
NSLog(@"vid1 length: %ld", [vid1 length]);
while (position < [vid1 length]) {
// find the picture size
position += size; // get to the right spot in the bit stream
range = NSMakeRange(position, (position + 5));
NSData *picSize = [vid1 subdataWithRange:range];
sizeBytes = [picSize bytes];
size = strtol(sizeBytes, NULL, 0);
// move the position in the byte stream to the end of the size bytes
position += 5;
// load the bytes for the picture
range = NSMakeRange(position, size);
NSData *picture = [vid1 subdataWithRange:range];
// create an NSImage based on the data
NSImage *image = [[NSImage alloc] initWithDataIgnoringOrientation:picture];
pictureCount++;
[videoPlayer setImage:image];
// add the image to the directory
imagePath = @"";
imagePath = [imagePath stringByAppendingFormat:@"path/to/the/pictures/pics/image%ld.jpeg", pictureCount];
// code to save the NSImage as a .jpeg
picture = [image TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:picture];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];
picture = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
BOOL success = [picture writeToFile:imagePath atomically:NO];
if (!success) {
NSLog(@"Something went wrong writing the image to the file...");
}
NSLog(@"Position: %ld\n", position);
// release the image object
[image release];
}
When I run it, it appears to work properly. The image view ends up with a picture in it and the folder is full of 301 pictures. Problem is, the picture that ends up in the image view is not the last frame from the video and from earlier work, I think there should be about twice as many pictures. I added in the calls to NSLog to see what was going on and it ends up spitting this out at the end:
2011-02-10 17:57:24.494 Video Decoder[43585:a0f] Position: 17758931
2011-02-10 17:57:24.553 Video Decoder[43585:a0f] Position: 17819849
2011-02-10 17:57:24.554 Video Decoder[43585:a0f] *** -[NSConcreteData subdataWithRange:]: range {17880739, 17880744} exceeds data length 35675568
17 million isn't greater than 35 million, so it shouldn't be exceeding the data length? Is it that range can't hold numbers that big? If so, is there any way to change it so it can?
Thanks,
Dan