• Removing geotagged info from a video

    When I post pictures to eBay or somewhere else that I've taken at my house, I strip the geotagged information in it as I'm a bit paranoid. I wrote a small app which basically does this for JPG images. The core of the app is below.

    However, how do you do this with videos as the iPhone geotags video? At first I tried emailing the video and then exporting it via QuickTime Player to 480p format. That didn't seem to work as I think it was already 480p and therefore didn't convert. Next, I imported the video into iPhoto, dragged it out to the desktop, opened it up in QuickTime Player and then exported to 480p. Since the initial video was 1080p, QuickTime Player actually had to do a conversion and the process stripped the geotagging info.

    I'm sure I could have written an app to do this, but I haven't played around enough lately with the QuickTime APIs to know how to do this.

    The source code below is © 2011 Scott Gruby. Redistribution in source or object form is permitted granted that attribution is given to me.

    - (void) processFile:(NSString *) inPath
    {
        NSString *extension = [inPath pathExtension];
        if ([extension caseInsensitiveCompare:@"jpg"] == NSOrderedSame || [extension caseInsensitiveCompare:@"jpeg"] == NSOrderedSame)
        {
            NSURL *pictURL = [NSURL fileURLWithPath:inPath];
            CGImageSourceRef sourceRef = CGImageSourceCreateWithURL((CFURLRef) pictURL, NULL);
            if (sourceRef)
            {
                NSDictionary* metadata = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(sourceRef,0,NULL);
                NSMutableDictionary *metadataAsMutable = [[metadata mutableCopy] autorelease];
                
                
                [metadataAsMutable setObject:(id)kCFNull forKey:(NSString *)kCGImagePropertyGPSDictionary];
                [metadataAsMutable setObject:(id)kCFNull forKey:(NSString *)kCGImagePropertyIPTCDictionary];
    
                CFStringRef UTI = CGImageSourceGetType(sourceRef); //this is the type of image (e.g., public.jpeg)
                
                //this will be the data CGImageDestinationRef will write into
                NSMutableData *data = [NSMutableData data];
                
                CGImageDestinationRef destination = CGImageDestinationCreateWithData((CFMutableDataRef)data,UTI,1,NULL);
                
                if(destination)
                {
                    //add the image contained in the image source to the destination, overiding the old metadata with our modified metadata
                    CGImageDestinationAddImageFromSource(destination,sourceRef,0, (CFDictionaryRef) metadataAsMutable);
                    
                    //tell the destination to write the image data and metadata into our data object.
                    //It will return false if something goes wrong
                    BOOL success = NO;
                    success = CGImageDestinationFinalize(destination);
                    
                    if (success)
                    {
                        //now we have the data ready to go, so do whatever you want with it
                        //here we just write it to disk at the same path we were passed
                        success = [data writeToURL:pictURL atomically:YES];
                    }
                    CFRelease(destination);
                }
    
    
                [metadata release];
                CFRelease(sourceRef);
            }
        }
    }
    
  • Beat this, Lassie

    The other day our dog came into the house and my wife asked me if I let him in; I replied that I hadn't. We scratched our heads and then figured that the dog opened the screen door and walked in. This is something we've wanted the dog to do for years so we wouldn't have to let him out (our doggie door in our last house was a piece of junk and fell apart requiring me to replace the door before we sold the house).

  • Dishwasher - Luxury or necessity?

    When we looked at our rental house, we said we'd take it almost immediately, but it wasn't until we got home that we realized it didn't have a dishwasher. Was this a deal breaker for us? It wasn't, but made us think. My resourceful wife looked on Craigslist and found a portable dishwasher within a few days. I picked it up for $65 and brought it home.

    After we moved into the rental, I got a $5 part from The Home Depot to hook it to the kitchen faucet and then we tested it out. So now that we had a working dishwasher albeit a little inconvenient, the question comes down to will we use it or wash dishes by hand? In our first few days in the house, the question answered itself. We've loaded up the dishwasher and run it every few days.

    I have no problem washing dishes after family comes over or there are a lot of dishes, but washing a bunch of silverware, glasses, and plates is for the birds. It is time consuming and, in fact, uses much more water than a dishwasher. I know that people survived without dishwashers, but they also survived without computers and the Internet.

    I'm going to have to say that an automatic dishwasher (I don't count as a dishwasher) is a necessity in today's life. Why should we have to do the manual labor when we have a machine to do it?

  • When wireless doesn't work

    In the house we just sold, I had a primarily wired network with only a few things wireless. This worked out pretty well as I had gigabit Ethernet switches in a few places and everything was quite reliable. Since we moved into a rental, running Cat6 cable everywhere was not a choice, so I had to go wireless in the house. I chose my office location in a central part of the house as it had coax close to it and WiFi would cover the entire house.

    Since my choice for handling TV involved a SiliconDust HDHomeRun, I didn't have to have coax directly to the TV; I just had to have coax near my network. This wasn't a problem as I put the box next to the cable modem and my Time Capsule router. My Mac Mini and Apple TV that are hooked to our TV are connected over 802.11n to my Time Capsule and appear to function adequately for the first few days.

    However, I started to notice that some of the shows that I recorded were jumpy. I suspected that this was due to lack of bandwidth. The HDHomeRun sends a stream of about 16 MBit/second for each show it is recording to my Mac Mini. 802.11n should be able to handle this without problems. My first step was to replace my Time Capsule with a newer version that supposedly had better performance. (I also went from 1 TB to 2 TB). Unfortunately, this didn't solve the problem. I noticed the biggest issue when 2 shows were being recorded which meant that I was streaming about 32 MBit/second and then if we were watching a show, it added about another 10 MBit/second to the mix. So the Mac Mini was trying to push a lot of data and receive a lot of data over WiFi.

    The next step in solving this problem (which I'll know next week if it is the fix) was to run 50 feet of Cat6 cable from my office around a corner and over some blinds to reach the Mac Mini.

    It appears that WiFi is decent for normal operations and some streaming, but is no replacement for a wired network. In theory 802.11n should be able to handle what I'm throwing at it, but the router can't handle it, the Mac Mini can't handle it, or the protocol isn't up to what I want to see.