Extra Pepperoni

To content | To menu | To search

Tag - Markdown

Entries feed - Comments feed

Saturday, December 27 2008

iPhone Users: Boycott Clickthroughs

Interstitial ads are annoying on desktop web browsers, but they're much more intrusive on handheld devices like iPhones. I have decided not to click through such ads on the iPhone, and to bail when I come across them, even when this means not reading content I want.

This is in the (likely vain) hope of convincing the people who control those websites that handheld users (at least) won't put up with that garbage.

I encourage you to join the boycott! Maybe we can get half a dozen people and really turn some heads, just like the Alice's Restaurant Anti-Massacre Movement.

Thursday, December 11 2008

hb.sh (HandBrake Wrapper) Updated for v0.9.3

As threatened, I have an update for my HandBrake wrapper script. On a Mac or Linux system, the script examines one or more DVD folders (I rip mine with MacTheRipper), and converts the DVD MPEG2 content to MP4 files suitable for Apple TV (by default) or iPhone (with an iphone argument, e.g., hb.sh iphone). It's easy to hack up for different preferences, and will require changing some variables to match your preferred media folder layout. Thanks to Brian Beardmore for the original GPL script.

The required customizations are these two lines:

inputSearchDir="$HOME/tivo-inspector/input/$mySuffix"
outputDir="$HOME/tivo-inspector/output"

The main difference in v1.0.7 of the script is that it uses HandBrake 0.9.3's new improved presets, rather than hard-coding my custom settings. I've found the new presets give excellent quality in considerably less time.

If you have trouble compiling the Linux CLI, see my earlier post about v0.9.3 (I didn't try the GUI).

You can download hb.sh v1.0.7 (recommended), or copy & paste, but might have to fix line wrapping & remove blog cruft if you do.


#!/bin/bash

# hb.sh uses HandBrakeCLI to convert whole DVDs automatically.
# Copyright (C) 2007  Brian Beardmore
# Copyright (C) 2008  Chris Pepper

#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# This script requires HandBrakeCLI <http://handbrake.fr/>.

# This script searches the entire input directory directory tree looking
# for TS_VIDEO directories looking for DVDs to encode.  The output mp4
# filename is the DVD volume name.  When multiple tracks are to encoded 
# from a DVD, the output filename is appended with the track number.
# For example, 'Monsters, Inc.' DVD has both standard and wide screen tracks
# so there are 'Monsters, Inc.1.mp4' & 'Monsters, Inc.10.mp4' files created.
# For addition information on this script contact the script's original author,
# Brian Beardmore at medfk(at)realisticsoftware(dot)com or
# http://www.realisticsoftware.com
# Or contact Chris Pepper <http://www.extrapepperoni.com/category/television/>.

# Examples
# $ ./appletv.sh
#   [ encodes all DVDs mounted and encodes any tracks longer than 60min ]
#   [ to the mp4 folder in the users Movies folder ]
# $ appletv.sh -i ~/Movies -o toPod -b 1000 -w 576 --minGetTime 50
#   [ encodes all DVDs found in the users Movies folder and encodes any ]
#   [ tracks longer than 50min, with a 1000kb/s bitrate and scales the output ]
#   [ movie to a width of 576 pixels and puts the resulting mp4 files in the ]
#   [ toPod folder in the current directory that the command was executed from ]

# Syntax: HandBrakeCLI [options] -i <device> -o <file>
# 
# ### General Handbrake Options------------------------------------------------
# 
#     -h, --help              Print help
#     -u, --update            Check for updates and exit
#     -v, --verbose <#>       Be verbose (optional argument: logging level)
#     -C, --cpu               Set CPU count (default: autodetected)
#     -Z. --preset <string>   Use a built-in preset. Capitalization matters, and
#                             if the preset name has spaces, surround it with
#                             double quotation marks
#     -z, --preset-list       See a list of available built-in presets
# 
# ### Source Options-----------------------------------------------------------
# 
#     -i, --input <string>    Set input device
#     -t, --title <number>    Select a title to encode (0 to scan only,
#                             default: 1)
#     -L, --longest           Select the longest title
#     -c, --chapters <string> Select chapters (e.g. "1-3" for chapters
#                             1 to 3, or "3" for chapter 3 only,
#                             default: all chapters)
# 
# ### Destination Options------------------------------------------------------
# 
#     -o, --output <string>   Set output file name
#     -f, --format <string>   Set output format (avi/mp4/ogm/mkv, default:
#                             autodetected from file name)
#     -m, --markers           Add chapter markers (mp4 and mkv output formats only)
#     -4, --large-file        Use 64-bit mp4 files that can hold more than
#                             4 GB. Note: Breaks iPod, PS3 compatibility.
#     -O, --optimize          Optimize mp4 files for HTTP streaming
#     -I, --ipod-atom         Mark mp4 files so 5.5G iPods will accept them
# 
# ### Video Options------------------------------------------------------------
# 
#     -e, --encoder <string>  Set video library encoder (ffmpeg,xvid,
#                             x264,theora default: ffmpeg)
#     -x, --x264opts <string> Specify advanced x264 options in the
#                             same style as mencoder:
#                             option1=value1:option2=value2
#     -q, --quality <float>   Set video quality (0.0..1.0)
#     -Q, --cqp               Use with -q for CQP instead of CRF
#     -S, --size <MB>         Set target size
#     -b, --vb <kb/s>         Set video bitrate (default: 1000)
#     -2, --two-pass          Use two-pass mode
#     -T, --turbo             When using 2-pass use the turbo options
#                             on the first pass to improve speed
#                             (only works with x264, affects PSNR by about 0.05dB,
#                             and increases first pass speed two to four times)
#     -r, --rate              Set video framerate (5/10/12/15/23.976/24/25/29.97)
#                             Be aware that not specifying a framerate lets
#                             HandBrake preserve a source's time stamps,
#                             potentially creating variable framerate video
# 
# ### Audio Options-----------------------------------------------------------
# 
#     -a, --audio <string>    Select audio track(s), separated by commas
#                             More than one output track can be used for one
#                             input.
#                             ("none" for no audio, "1,2,3" for multiple
#                              tracks, default: first one)
#     -E, --aencoder <string> Audio encoder(s) (faac/lame/vorbis/ac3) 
#                             ac3 meaning passthrough
#                             Separated by commas for more than one audio track.
#                             (default: guessed)
#     -B, --ab <kb/s>         Set audio bitrate(s)  (default: 160)
#                             Separated by commas for more than one audio track.
#     -6, --mixdown <string>  Format(s) for surround sound downmixing
#                             Separated by commas for more than one audio track.
#                             (mono/stereo/dpl1/dpl2/6ch, default: dpl2)
#     -R, --arate             Set audio samplerate(s) (22.05/24/32/44.1/48 kHz)
#                             Separated by commas for more than one audio track.
#     -D, --drc <float>       Apply extra dynamic range compression to the audio,
#                             making soft sounds louder. Range is 1.0 to 4.0
#                             (too loud), with 1.5 - 2.5 being a useful range.
#                             Separated by commas for more than one audio track.
#     -A, --aname <string>    Audio track name(s),
#                             Separated by commas for more than one audio track.
# 
# ### Picture Settings---------------------------------------------------------
# 
#     -w, --width <number>    Set picture width
#     -l, --height <number>   Set picture height
#         --crop <T:B:L:R>    Set cropping values (default: autocrop)
#     -Y, --maxHeight <#>     Set maximum height
#     -X, --maxWidth <#>      Set maximum width
#     -p, --pixelratio        Store pixel aspect ratio in video stream
#     -P, --loosePixelratio   Store pixel aspect ratio with specified width
#           <MOD:PARX:PARY>   Takes as optional arguments what number you want
#                             the dimensions to divide cleanly by (default 16)
#                             and the pixel ratio to use (default autodetected)
#     -M  --color-matrix      Set the color space signaled by the output
#           <601 or 709>      (Bt.601 is mostly for SD content, Bt.709 for HD,
#                              default: set by resolution)
# 
# ### Filters---------------------------------------------------------
# 
#     -d, --deinterlace       Deinterlace video with yadif/mcdeint filter
#           <YM:FD:MM:QP>     (default 0:-1:-1:1)
#            or
#           <fast/slow/slower>
#     -5, --decomb            Selectively deinterlaces when it detects combing
#           <MO:ME:MT:ST:BT:BX:BY>     (default: 1:2:6:9:80:16:16)
#     -9, --detelecine        Detelecine (ivtc) video with pullup filter
#                             Note: this filter drops duplicate frames to
#                             restore the pre-telecine framerate, unless you
#                             specify a constant framerate (--rate 29.97)
#           <L:R:T:B:SB:MP>   (default 1:1:4:4:0:0)
#     -8, --denoise           Denoise video with hqdn3d filter
#           <SL:SC:TL:TC>     (default 4:3:6:4.5)
#            or
#           <weak/medium/strong>
#     -7, --deblock           Deblock video with pp7 filter
#           <QP:M>            (default 5:2)
#     -g, --grayscale         Grayscale encoding
# 
# ### Subtitle Options------------------------------------------------------------
# 
#     -s, --subtitle <number> Select subtitle (default: none)
#     -U, --subtitle-scan     Scan for subtitles in an extra 1st pass, and choose
#                             the one that's only used 10 percent of the time
#                             or less. This should locate subtitles for short
#                             foreign language segments. Best used in conjunction
#                             with --subtitle-forced.
#     -F, --subtitle-forced   Only display subtitles from the selected stream if
#                             the subtitle has the forced flag set. May be used in
#                             conjunction with --subtitle-scan to auto-select
#                             a stream if it contains forced subtitles.
#     -N, --native-language   Select subtitles with this language if it does not
#           <string>          match the Audio language. Provide the language's
#                             iso639-2 code (fre, eng, spa, dut, et cetera)

# Revision history:
# 1.0.7, 2008/12 -- Update for HandBrake 0.9.3, and use presets.
# 1.0.6 -- never released.
# 1.0.5, 2008/08 -- Require bash, per ebb.
# 1.0.4, 2008/06 -- Use different suffices so different flavors can coexist.
# 1.0.3, 2008/05 -- Add basic argument processing, so "appletv" and "iphone" as argument #1 produce different output.
# 1.0.2, 2008/05 -- hacks by Pepper to use HandBrakeCLI and optimize for AppleTV.
# 1.0.1, 2008/02/24 -- hacks by Pepper to use HandBrakeCLI and optimize for iPhone.
# 0.20070329.0 - initial release


#############################################################################
# globals

# const global variables
scriptName=`basename "$0"`
scriptVers="1.0.7"
scriptPID=$$
saveDVDinfo=1       # the DVD track info is also saved as .txt file when set
skipDuplicates=1    # if this option is off, overwrite existing files
E_BADARGS=65

if [[ $# = 0 ]]
 then
  myArgs='$HANDBRAKE_ARGS -Z AppleTV'
elif [[ $1 = "appletv" ]]
 then
  myArgs='$HANDBRAKE_ARGS -Z AppleTV'
  mySuffix=AppleTV
elif [[ $1 = "AppleTV" ]]
 then
  myArgs='$HANDBRAKE_ARGS -Z AppleTV'
  mySuffix=AppleTV
elif [[ $1 = "iphone" ]]
 then
  myArgs='$HANDBRAKE_ARGS -Z "iPhone & iPod Touch"'
  mySuffix=iPhone
elif [[ $1 = "iPhone" ]]
 then
  myArgs='$HANDBRAKE_ARGS -Z "iPhone & iPod Touch"'
  mySuffix=iPhone
else
 echo "Unknown format -- aborting!"
 exit 1
fi

# set the global variables to defaults
toolName="HandBrakeCLI"
toolPath="$HOME/bin/$toolName"
toolTrackArgs="-t 0"
toolArgs="-v"
inputSearchDir="$HOME/tivo-inspector/input/$mySuffix"
outputDir="$HOME/tivo-inspector/output"
minTrackTime="3"    # in minutes


# Pepper's sometime options:
# -s 1 # first subtitle
# -a 2 # second audio track ??
# For example (best within screen): HANDBRAKE_ARGS="-s1 -t11" iphone.sh


#############################################################################
# functions

parseProcessInArgs()
{
    if [ -z "$1" ]; then
        return
    fi

    toolArgs=""

    while [ ! -z "$1" ]
    do
        case "$1" in
            -h) displayUsageExit ;;
            --help) displayUsageExit ;;
            -i) inputSearchDir=$2
                shift ;;
            --input) inputSearchDir=$2
                shift ;;
            -o) outputDir=$2
                shift ;;
            --output) outputDir=$2
                shift ;;
            --minGetTime) minTrackTime=$2
                shift ;;
            *) toolArgs="$toolArgs $1" ;;
        esac

        shift
    done
}

verifyFindCLTool()
{
    # attempt to find the HandBrakeCLI if the script toolPath is not good
    if [ ! -x "$toolPath" ];
    then
        toolPathTMP=`PATH=.:/Applications:/:/usr/bin:/usr/local/bin:$HOME:$PATH which $toolName | sed '/^[^\/]/d' | sed 's/\S//g'`

        if [ ! -z $toolPathTMP ]; then 
            toolPath=$toolPathTMP
        fi
    fi  
}

displayUsageExit()
{
    echo "Usage: $scriptName [options]"
    echo ""
    echo "    -h, --help              Print help"
    echo "    -i, --input <string>    Set input directory to process all DVDs in it (default: /Volumes/)"
    echo "    -o, --output <string>   Set output directory for all output files (default: ~/Movies/mp4/)"
    echo "    --minGetTime <number>   Set the minimum time (mins) of the track/s to encode (default: 60)"

    if [ -x "$toolPath" ];
    then
        echo "   $toolName possible options"
        hBrakeHelp=`$toolPath --help 2>&1`
        hBrakeHelpPt=`printf "$hBrakeHelp" | egrep -v '( --input| --output| --help|Syntax: |^$)'`
        printf "$hBrakeHelpPt\n"
    else
        echo "    The options available to HandBrakeCLI except -o  and -i"
        if [ -e "$toolPath" ];
        then
            echo "    ERROR: $toolName command tool is not set up to execute"
            echo "    ERROR: attempting to use tool at $toolPath"
        else
            echo "    ERROR: $toolName command tool could not be found"
            echo "    ERROR: $toolName can be installed in ./ /usr/local/bin/ /usr/bin/ ~/ or /Applications/"
        fi
    fi

    echo ""

    exit $E_BADARGS
}

getTrackListLongerThan()
{
    # Two input arguments are are need. 
    #   arg1 is the time in minutes selector
    #   arg2 is the raw text stream from the track 0 call to HandBrake
    #   returns: a list of track numbers of tracks longer than the selector

    if [ $# -lt 2 ]; then
        return ""
    fi

    minTime="$1"
    shift
    allTrackText="$*"
    aReturn=""

    trackList=`eval "echo \"$allTrackText\" | egrep '(^\+ title |\+ duration\:)' | sed -e 's/^[^+]*+ //'g -e 's/title \([0-9]*\):/\1-/'g -e 's/duration: //'g"`

    trackNumber=""
    for aline in $trackList
    do
        trackLineFlag=`echo $aline | sed 's/[0-9]*-$/-/'`
        if [ $trackLineFlag = "-" ];
        then
            trackNumber=`echo $aline | sed 's/\([0-9]*\)-/\1/'`
        else
            set -- `echo $aline | sed -e 's/(^[:0-9])//g' -e 's/:/ /g'`
            if [ $3 -gt 29 ];
            then let trackTime=($1*60)+$2+1
            else let trackTime=($1*60)+$2
            fi

            if [ $trackTime -gt $minTime ];
            then aReturn="$aReturn $trackNumber"
            fi
        fi
    done

    echo "$aReturn"
}

makeFullPath()
{
    aReturn=""
    currentPath=`pwd`

    if [ $# -gt 0 ]; then
        inPath="$*"

        # put full path in front of path if needed
        aReturn=`echo "$inPath" | sed -e "s!~!$currentPath/!" -e "s!^./!$currentPath/!" -e "s!^\([^/]\)!$currentPath/\1!" -e "s!^../!$currentPath/../!"`

        # remove ../ from path - only goes 4 deep
        aReturn=`echo "$aReturn" | sed -e 's!/[^\.^/]*/\.\./!/!g' | sed -e 's!/[^\.^/]*/\.\./!/!g' | sed -e 's!/[^\.^/]*/\.\./!/!g' | sed -e 's!/[^\.^/]*/\.\./!/!g'`

        # cleanup by removing //
        aReturn=`echo "$aReturn" | sed -e 's!//!/!g'`
    fi

    echo "$aReturn"
}

isPIDRunning()
{
    aResult=0

    if [ $# -gt 0 ]; then
        txtResult="`ps ax | egrep \"^[ \t]*$1\" | sed -e 's/.*/1/'`"
        if [ -z "$txtResult" ];
        then aResult=0
        else aResult=1
        fi
    fi

    echo $aResult
}

#############################################################################
# MAIN SCRIPT

# initialization functions
verifyFindCLTool
parseProcessInArgs $*
# see if the output directory needs to be created
if [ ! -e $outputDir ]; then
    mkdir -p "$outputDir"
fi

# sanity checks
if [[ ! -x $toolPath || ! -d $inputSearchDir || ! -d $outputDir || -z "$toolArgs" ]]
 then

  if [[ ! -x $toolPath ]]
   then echo "ERROR: $toolPath is not executable!"
  fi
  if [[ ! -d $inputSearchDir ]]
   then echo "ERROR: $inputSearchDir is not a valid input directory!"
  fi
  if [[ ! -d $outputDir ]]
   then echo "ERROR: $outputDir is not a valid output directory!"
  fi
  if [[ ! -z "$toolArgs" ]]
   then echo "ERROR: $toolArgs is unset!"
  fi

    displayUsageExit
fi

# fix input and output paths to be full paths
inputSearchDir=`makeFullPath $inputSearchDir`
outputDir=`makeFullPath $outputDir`

# display the basic setup information
echo "$scriptName v$scriptVers"
echo "  Start: `date`"
echo "  Input directory: $inputSearchDir"
echo "  Output directory: $outputDir"
echo "  Minimum get track time: $minTrackTime mins"
echo "  Tool path: $toolPath"
echo "  Tool args: $toolArgs"
echo "  My args: $myArgs"
echo "  - - - - - - - - - - - - - - - -"

# find all the DVD videos in the input search directory tree
# spaces in file path temporarily become /008 and paths are separated with spaces
dvdTSVidList=`find $inputSearchDir -name VIDEO_TS -print0 | tr ' ' '\007' | tr '\000' ' '`

# process each DVD video found
for dvdTSDir in $dvdTSVidList
do
    # correct the tmp char back to spaces in the DVD file paths
    dvdTSDir=`echo $dvdTSDir | tr '\007' ' '`

    # get the DVD's name and path to root of the DVD
    dvdVolPath=`dirname "$dvdTSDir"`
    dvdName=`basename "$dvdVolPath"`
    dvdNameALNUM=`basename "$dvdVolPath" | sed 's/[^[:alnum:]^-^_]//g'`

    # display information
    echo "  * Processing DVD '$dvdName'"

    # create tmp link to the dvdVolPath to workaround a problem that
    # the HandBrakeCLI tool has a problem with spaces in the input
    # file paths in a script
    tmpNoSpacePath="/tmp/dvdVol-$dvdNameALNUM-$scriptPID"
    ln -s "$dvdVolPath" $tmpNoSpacePath

    # get the track list information from the DVD
    cmd="$toolPath -i $tmpNoSpacePath $toolTrackArgs /dev/null 2>&1"
    dvdTrackInfo=`eval $cmd`
    # save the DVD info
    outputFilePath="$outputDir/${dvdName}.txt"
    if [ $saveDVDinfo -eq 1 ]; then
        if [[ ! -e  $outputFilePath || skipDuplicates -eq 0 ]]; then
            echo "$dvdTrackInfo" | egrep '[ \t]*\+' > "$outputFilePath"
        fi
    fi
    # get the track number of tracks which are longer then the time desired
    trackFetchList=`getTrackListLongerThan $minTrackTime "$dvdTrackInfo"`
    if [ ! -z "$trackFetchList" ];
    then
        echo "   Will encode the following tracks: `echo $trackFetchList | sed 's/ /, /g'` "
    else
        echo "   No tracks on this DVD are longer than the minimum track time setting"
    fi

    trackCount=`echo $trackFetchList | wc -w`
    for aTrack in $trackFetchList
    do
        if [ $trackCount -gt 1 ]
            then outputFilePath="$outputDir/${dvdName}-${aTrack}.$mySuffix.m4v"
            else outputFilePath="$outputDir/${dvdName}.$mySuffix.m4v"
        # .m4v is important for AppleTV
        fi
        cmd="$toolPath $myArgs -i $tmpNoSpacePath $toolArgs -t $aTrack -o \"$outputFilePath\" > /tmp/${dvdNameALNUM}Results.txt 2>&1"

        if [[ ! -e  $outputFilePath || skipDuplicates -eq 0 ]];
        then
            # simple command execution
            #ripResult=`eval $cmd`

            # background command execution with some status

            echo "Command is: $cmd"

            eval $cmd &
            cmdPID=$!
            while [ `isPIDRunning $cmdPID` -eq 1 ]; do
                cmdStatusTxt="`tail -n 1 /tmp/${dvdNameALNUM}Results.txt | grep 'Encoding: '`"
                if [ ! -z "$cmdStatusTxt" ]; then
                    echo -n "$cmdStatusTxt"
                fi
                sleep 1s
            done
            echo ""
            wait $cmdPID

        else
            echo "   Output file SKIPPED because it ALREADY EXISTS"
        fi

        if [ -e /tmp/${dvdNameALNUM}Results.txt ]; then
            rm /tmp/${dvdNameALNUM}Results.txt
        fi
    done

    rm $tmpNoSpacePath
done

echo "  - - - - - - - - - - - - - - - -"
echo "  End: `date`"

exit 0

Wednesday, November 5 2008

AT+T Cannot Forward a Phone Number

I need a new phone number for a few months, to forward to my cell phone. Apparently AT&T has an institutional blind spot around forwarding, though. I called AT&T Wireless, and had to explain myself several times (over 25 minutes). She was unable to help, so transferred me to her manager, who could not help either. The Wireless manager forwarded me to AT&T Long Distance (800 222-0300).

After much repetitive explanation, LD said they were unable to help me because I wasn't asking about a long distance number. LD forwarded me to AT&T Local Service (800 288-2747).

The Local sales rep said she(?) was unable to help, and that I needed to speak with AT&T Wireless (since, after all, I want to forward to an AT&T iPhone). I explained that I did not want to speak to Wireless, as they had already explained they can only forward my cell phone to a different number, rather than forwarding a new number to my cellphone. She asked if I had been helped to my satisfaction (part of the script), and I explained I had not been helped yet, and didn't even know who she was about to pass me along to. She apologized, assured me the next group would be able to help, ignored me as I asked (twice) who she was transferring me to, and transferred me back to Wireless. Obviously she wanted to be rid of me, and no longer cared if I was helped.

The next Wireless rep understood better, at least. She checked with 4 managers, and confirmed the Wireless group does not offer forwarding into cellphones. When asked, she passed me on to Wireless Business Services (800 999-5445) -- unfortunately it was Wireless Business Services, and they were confused by my number not being tied to a business account.

Eventually the BWS rep offered me a new wireless contract for $10/month, with a $175 early termination fee any time between 30 days and 2 years. This would get me a new number, and could be forwarded to my existing iPhone. $240 seems like a lot for something I only expect to need for a few months. Interestingly, the residential Wireless reps had mentioned this, but seemed rather confused about it -- among other things, they said the termination fee only applied within the first 6 months. $60 for 1-6 months seems pretty good in comparisoin!

Not an impressive performance, considering I spent over an hour on the phone with Customer Service.

Now I'm looking at the various $10/month web-based forwarding / phone management services. Recommendations welcome (during November)!

Thursday, September 11 2008

iTunes 8's Video Improvements, and Updated App Bugs

Update: Thanks to Dave Makower for a workaround. Per Dave's suggestion, I signed out of the Apple Store and signed back in as my account @mac.com. This is the default, so signing in with just my account (without explicitly typing @mac.com) should worked just as well, but apparently it doesn't. Thanks, Dave! I hope short names work properly in iTunes soon. Or perhaps it's just that I used a different login name when I initially downloaded the software...

Update 2: from Kevin Ross:

Hi, I'm emailing to let you know that I had similar problems updating apps. My solution was to go through the app store and "buy" every app over again. I did it with all my free apps first and they all upgraded fine, then I did it with Super Monkey Ball, iTunes saw that I already had it, told me so and said I wouldn't be charged, and installed the upgrade free of charge. Just a little tidbit to help you out in case Dave's workaround doesn't work later.


I just discovered that iTunes 8 makes large strides in handling videos. Previous versions were unable to change the Movie/TV Show/Music Video type flag, or set Show, Season, or Episode. v8 adds all these capabilities. I no longer need Set Video Kind from Selected from the most excellent Doug's AppleScripts for iTunes, and can now sort out imported video from iTunes' Get Info window.

Additionally, iTunes used to say it had over a dozen application updates for me, but fail to access my account or say I had none when I tried to get them. Now it shows me 19 updates, and seems to have the correct list, although it cannot actually install them. It appears to be something about upgrading free applications, which was broken last week (in different ways) too.

Here is what happens when I click Download All Free Updates:

MZCommerceSoftware.OwnsNoneSoftawareApplicationForUpdate_message

Here is a bogus tooltip for Life (not necessarily related to the updating problems):

MZAccessibility.buybutton.getupdateapp

And a message telling me I cannot get Life 1.0.3, apparently because I don't have an earlier 1.x version of Life (actually, I have 10.0.1). I get this for every app.

Individually, I am able to upgrade free apps -- I don't mind paying their full price of "Free". I'm not willing to test Apple's bugs to find out if Apple they would really re-bill me for what should be free upgrades to purchased apps, though, as this erroneous message claims. Here iTunes told me I cannot get the free LifeGame for free; I get the same message for every app, free or purchased.

You do not qualify for this price.

To make the problem even more aggravating, App Store on the iPhone has the same issue -- when I try to upgrade Twitteriffic Premium or Toy Bot Diaries, it tells me I'll have to pay full price. I want those updates! I hope this is sorted out soon.

Thursday, August 14 2008

Suggested iPhone apps

Frank just got an iPhone, so I was listing off suggested apps, and decided to post the list. Almost all of them are free.

  • NetNewsWire/iPhone: RSS reader which synchs with NNW on Mac, FeedDemon on Windows, and Newsgator Online; all are free
  • Instapaper: Multi-computer bookmarking service -- links to http://www.instapaper.com/
  • (paid) Twitteriffic Premium (Free shows ads): http://twitter.com/reppep
  • Stanza: ebook reader
  • Remote: iTunes & AppleTV control
  • (paid) TouchTerm: ssh client
  • (paid) pTerm: ssh client
  • Facebook
  • AIM (just for free SMS)
  • Now Playing
  • Scribble: need a drawing program to play with Julia
  • Shazam: identifies recorded music the iPhone can "hear"
  • Shakespeare: complete works
  • Yelp (Amy likes)
  • Google

Games

  • (paid) Toy Bot
  • Phone Saber
  • Fire Drop
  • Moonlight Mahjong Lite
  • Labyrinth LE
  • Life
  • Tap Tap Revenge
  • Advent (I don't play it, but keep it for the ecstasy it will someday induce in an old Zork fan)

Monday, August 4 2008

iPhone 2.0 Subtleties

I upgraded to iPhone OS v2.0 a while before I got a 3G iPhone (very worthwhile for me, since I spend most of my time outside Wi-Fi coverage now). Since the upgrade, I have noticed a few things which I have not seen mentioned elsewhere.

Continual pseudo-GPS updating in original models

On my original iPhone under iPhone OS v1.x, tapping the crosshair button in Maps used to locate me -- the button turned blue while the iPhone was fixing my location, then turned grey again when done. To update my location I had to tap the button to get a new location fix. Under v2.0, after tapping the button it stays blue, and the iPhone updates my location automatically until I tap again (to turn it grey and switch location auto-updating off) or exit Maps. This is well-known on 3G models, but I was surprised and pleased to see auto-relocation on the original iPhone.

Pause to rotate (walker unfriendly)

Under iPhone 1.x, I could rotate the iPhone to re-orient Safari while walking. Under v2.0 the iPhone does not reorient while I am walking -- I have to stand still for it to notice the change in orientation and rotate. Annoying, as it means I will have to stop in the middle of crowds to trigger rotation.

More switches to iPod.app when resuming music playback?

Under v1.x, after a sync or reboot, the first time I hit the earphone button to start music playback, the iPhone would switch into iPod mode, but I could stop and start without switching into iPod mode. I have a feeling that it switches into iPod mode sometimes now (after I first started and stopped playback), at times when it would not have before. This is unconfirmed, though.

Upside-down for iPod videos

I believe this changed from v1.1.4 to v2.0, but could be wrong about when. In earlier software versions, iPod movie playback only worked when rotated 90° counterclockwise. Alex hates this, as it puts the speakers behind your right hand. With v2.0, iPod movies can also be played back 90° clockwise, which puts the speakers under the left hand. YouTube still only works counterclockwise, though.

Loss of background functionality with apps vs. Safari

I am very happy with NetNewsWire, Twitteriffic, and Instapaper, but iPhone 2.0 doesn't let them run in the background. This means NetNewsWire and Twitteriffic always need to update when I launch them, as opposed to the Mac apps which update automatically in the background. It also means I cannot multitask -- when I was using NewsGator Online and m.twitter.com, I was able to switch between Safari tabs and Mail, and keep them working in the background as I switched to whichever was done. The apps are much better than the webapps, but the regression of having to wait really bugs me. Fortunately it's lessened somewhat by the 3G iPhone's improved update speed.

Another disappointment is that neither NetNewsWire nor Twitteriffic supports rotation. I thought Apple didn't support it outside Safari proper (both NetNewsWire and Twitteriffic incorporate the WebKit engine Safari uses) until I realized Instapaper supports rotation, and Stanza supports rotation (even upside-down, which Safari does not). I'm sure there are real reasons Brent & Craig have not yet provided rotation in their apps, but as I understand it, they are not allowed to discuss them, or how Instapaper & Stanza do it -- even under NDA, despite the fact that this is released software!

On the other hand, reading Slashdot via NewsGator Online stunk. The delay to get each article was very aggravating, and NGO was useless on the train. NNW/iPhone makes reading Slashdot a pleasure.

Also, Remote is great.

Friday, July 11 2008

iPhone Apps: First Impresssions

I've been waiting for NetNewsWire for iPhone since I first heard of it, and have already registered Twitterrific Premium, which is very slick (although I'm not sure how GPS or photos work). I am somewhat disappointed that NNW/iPhone doesn't proactively download updates; that's one of the nice things about NNW on the Mac -- it's always pretty current, and I never have to wait for an update. On the iPhone, where I may not even be able to get an update on the train, it's problematic. I was hoping NNW/iPhone would proactively sync feeds, so I could use it on the subway while out of coverage, but no joy.

Twice, all apps have failed to launch until I rebooted, and I've had a couple unexpected reboots.

Most apps are very slick, although AIM and iMaze both disappoint. Very much looking forward to using Remote for real, and wondering if I should have gotten an Apple TV for our living room stereo instead of an AirPort Express/n...

There's a trick to replacing the 4 persistent apps in the Dock at the bottom: you cannot drag into the Dock to bump them out of the way; instead you must drag something out of the Dock to make room first, and then you can drag an app into the free space.

It's annoying that deleting an app from the iPhone leaves it on the Mac; moreso that re-synching re-installs the app on the iPhone and forces a full (slow) backup of the iPhone. Adding insult to injury, I cannot control-click an app in iTunes to re-install it, or get rid of the confirmation on every deletion from iTunes.

The AIM client stinks. Not sure if it's push enabled, but it has serious flaws and bugs, both.

Moving apps around Springboard is a bit buggy. As I moved them from one screen to another, Springboard moved a bunch of extra apps to later screens -- many more than were actually necessary to make room. I always have 7 screens of apps, even when they all fit on 6. Under 1.1.4, there were no empty screens -- empty ones were automatically removed; I preferred that behavior.

I expect to get an iPhone 3G Monday -- can't do it this weekend.

Where's the OpenSSH port?!?! I do hope Apple didn't reject a submission...


Update 2008/07/12: The extra screen is correct. When in app rearrangement mode, the iPhone always provides an extra screen so I can move apps there; in normal mode the extra screen goes away.

Sunday, June 15 2008

iPhone 3G Economics

Steve Jobs announced that the iPhone 3G would be "Twice as fast. Half the price".

Ever since Om Malik's interview with AT&T's Ralph de la Vega, people have been noticing and commenting on the fact that this ignores the mandatory 2-year AT&T contract, and in fact iPhone 3Gs will generally cost more, thanks to the higher monthly fees.

Unfortunately, Amy doesn't want my original $400 iPhone -- perhaps a friend who can't justify the 3G charges will buy it for $100.

The $300 16gb iPhone 3G will be worth the money for me -- I spend a significant amount of time each day waiting for pages to load, and still take a Treo 650 & Bluetooth GPS unit on driving trips. But I'm disappointed in Apple for choosing a clearly misleading catchphrase for a product which doesn't need deceit and customer confusion to sell well.

I don't use SMS much, but I do sometimes, and I don't want to worry about the astronomical per-message costs, so I like the $5/month flat rate plan. And I certainly want the $30/month unlimited 3G data plan.

Fortunately, I'm now able to drop back from the 900-minute/month plan I upgraded to, down to the base 450-minute/month plan, which will save $20/month, and nicely offset the additional $15/month for unlimited 3G & 200 SMS.

Now that AppleCare has failed me, and the iPhone isn't as much of a hardware investment, and I don't walk outdoors across campus (drops on carpet are much less destructive than on asphalt or concrete outside), I've decided not to purchase AppleCare or a case for my new iPhone (my 11-month-old plastic incase protector is falling apart, and kept the iPhone from fitting in any dock). I like the idea of leaving the iPhone charging in its dock overnight, rather than lying on a night table.

So with the new iPhone, I'll save $70 on a 2-year AppleCare contract and $30 for the case. This is enough to pay for MobileMe service. Hopefully it will be solid, as opposed to the current .Mac service, based on the unreliable iSync.

I wonder how much turn-by-turn GPS with spoken directions will cost on the iPhone. I know TomTom and Garmin are quite interested, and Google Maps can do real-time driving GPS without spoken directions -- I don't know what the iPhone options will be, though.

I have a couple large questions. First, how well will MobileMe work? Second, how much will turn-by-turn GPS with spoken directions cost? Hardware GPS units are in the several-hundred-dollar range, while Google offers free or cheap GPS with directions but no speech. I'm looking forward to seeing what is available using the iPhone SDK.

I'll have a much faster iPhone (and probably OpenSSH -- hooray!), and next time an attractive upgrade rolls around, I won't have $500 invested in the previous generation.


To sum up, I'll save $20/m on extra minutes, and pay an additional $15/m on 3G data & SMS. I'll save $100 on protection, and pay $100/year on MobileMe. If things don't change over the next 2 years, I'll end up paying $40 more, which isn't bad, but also isn't "Half the price."

Thursday, May 22 2008

Nicer Batch Encoding with HandBrake

A while ago I posted a script for driving HandBrakeCLI. But it was lame that I had two not-quite-identical versions of the script -- one for iPhone output and another for Apple TV. At a guess, Brian Beardmore only needed one type. Now that we watch movies on the Apple TV and I watch on the iPhone, it was silly to have two different scripts. So I added simple argument processing.

hb.sh v1.0.3

If there first argument is iphone, then hb.sh optimizes for iPhone. If the argument is appletv or there are no arguments, hb.sh optimizes for Apple TV. It's very easy to tweak or add your own types -- just look for myArgs in the script and add or adjust as desired. I run this script on my Linux server, which has lots of disk space and is generally idle.


On my MacBook Pro, I have a couple aliases to facilitate things. I copy DVD folders to ~/tivo/tivo-inspector/input and run one of these. When done, the script opens up ~/tivo/tivo-inspector/. I move the DVD folders out of input and the processed .m4v video out of output; then I drop the .m4v files onto iTunes' LIBRARY area (so it doesn't stop whatever it's currently playing) and check iPhone videos to sync to the iPhone (the Apple TV has plenty of space, so everything syncs to it). Note that these lines may be too wide to display properly in WordPress -- just Copy and Paste, and you'll get the full text.

alias hbatv="ssh -t inspectore time screen bin/hb.sh appletv; open ~/tivo/tivo-inspector"
alias hbip="ssh  -t inspectore time screen bin/hb.sh iphone;  open ~/tivo/tivo-inspector"

Note that inspectore is the name of my Linux server. This would work just as well with HandBrakeCLI on a Mac "server" -- or even Windows, if you set it up to accept remote commands (CygWin, anyone?).


Reminder: You must adjust the inputSearchDir and outputDir paths for the running HandBrakeCLI.

pepper@inspector:~$ egrep tivo bin/hb.sh
inputSearchDir="$HOME/tivo-inspector/input"
outputDir="$HOME/tivo-inspector/output"

In the future version I'd like to support for arbitrary HandBrakeCLI arguments on the hb.sh command line, but I first have to see if HandBrakeCLI can handle gracefully conflicting arguments from built-ins and the command line.

Wednesday, April 16 2008

Goodbye to The Register

I've been reading The Register for years. The biggest draw for me is that their idea of what's interesting matches my own pretty closely, so the relevance is very high, and I don't know any other sites/publications that provide timely coverage in roughly the same space.

Unfortunately, they're clowns. They obviously don't edit, and don't fix obvious mistakes when pointed out. For a while they had opposing columnists, one claiming Intel was crushing AMD and another claiming AMD was crushing Intel -- posting supposedly authoritative articles on the same days. My interpretation was that The Register doesn't care whether they print stuff that's flat wrong (obviously at least one of those columnists was, even if they were both personally convinced it was the other guy), so long as it draws traffic. This is one thing if labeled as editorial, but they're not that sophisticated.

Their articles are confused or simply wrong often enough that a couple friends refuse to read anything they publish. I prefer the current facts enough that I am willing to overlook the absurd editorial.

They use FeedBurner, and downloading their articles over EDGE on the iPhone is slow. To aggravate matters, their CSS is screwed up; I have to wait for the page to download, then it resizes, then it pauses and downloads some more, then it reflows. It can take over a minute to get a readable article. The AV Club is even slower to download and reflow, which is one reason I read it less.

But recently The Register has started doing full-page ads before the articles. This is aggravating on a desktop, but completely unacceptable on an iPhone. I've removed their feed from NetNewsWire/NewsGator.

Saturday, February 16 2008

Reading in bed, and iPhone trick

The other day I was lying on my side, trying to read a web page on the iPhone. I turned the iPhone 90° clockwise, but it obligingly re-rotated the text 90° counter-clockwise, leaving me again out of sync. I grumbled something about the irritation of being outmaneuvered by a handheld gadget. Amy's brilliant suggestion: rotate it another 90° CCW. Since the iPhone doesn't offer 180° rotation, this left the text rotated 90° -- aligned with my head.

Thanks, Amy!

Wednesday, January 16 2008

Macworld & NYSec

This afternoon (morning in SF), Steve announced the excellent MacBook Air (which I don't want), the iPhone 1.1.3 update (which I very much like and have already benefitted from), AppleTV "Take 2" (which I will order if it can play MPEG2 from the TiVo easily), and iTunes movie rentals (which are useless for parents who watch half a movie at a time).

This afternoon, I went to NYsec, hosted by Ryan Naraine and Matasano Security. An interesting group with several good stories.

Friday, November 30 2007

iPhone Subtleties

Update 2007/12/15: The iPod has two shuffle modes. I'd been going to the list of songs and hitting Shuffle, but this isn't sticky. The trick is to 1) start playing a song, 2) tap on the cover area to get the track position slider, and 3) tap the shuffle icon on the right side. This is sticky, and I now have shuffle play by default! Still no shuffle by album, though...


The iPhone has a few very small features which show a surprising level of thought went into its design before launch.

The do not disturb switch. This has been a signature feature of Treos for years -- completely disabling the speaker. Apple got smarter: the iPhone's side switch mutes incoming calls, SMS notifcations, & calendar alerts. But the alarm clock and immediate actions on the phone, including speakerphone and iPod playback (with earphones disconnected) -- still use the speaker. So Apple has evolved from "mute" to "do not disturb", which is much more useful.

Keyboard key-up. Registering keys on finger lift allows correction without mistyping (if you're paying attention) and provides some really handy tricks, like dragging from shift to I to get a capital I in one (long) tap instead of three -- works for numbers & punctuation too.

iPod stop on earphone removal. When you unplug earphones, the iPhone stops music or video playback. I use this feature at least twice a day, when I get home or to work. If the iPhone is in a holster or bag, this saves the trouble of getting it out to stop playback. Apple could have opted to activate the speaker instead, but people unplug their earphones and stop using the iPod much more often than they switch from earphones to speakers.

Earphone remote behavior. When listening to music, it fades out if the phone rings; I thought this was silly, but it's nice. When I hit the button on the remote, the phone answers; when I hit the button later to hang up, the music resumes. If I'm using the iPhone (in any app) and hit the earphone remote, music starts (or stops) playing; this saves me a few steps on switching into the iPod app and back to what I was doing. When watching video, it pauses and resumes. Between that, the double-click to skip to next track, and the volume controls on the side of the iPod (easily accessible in a belt holster), I don't miss the 6-button iPod remote.

Unfortunately, it's always alphabetical play of everything on the iPhone, so I have to switch to iPod and start Shuffle play the first time; then it stays in Shuffle mode until either a) the iPhone gets confused and stops playing, or b) I plug into a Mac; neither of these should switch me out of Shuffle mode, actually.

And that reminds me: What genius at Apple decided that iPhone users don't want to shuffle by album? So much for "the best iPod ever". Pfeh!

But overall, the iPhone is remarkably sophisticated. Perhaps Ive & Jobs and their 5 closest friends spent a year writing down all the things about cellphones that annoyed them, and brought that into the iPhone design discussions.

Friday, November 16 2007

Crackhead of the week: Phil Manchester @ The Register

With thanks to Daring Fireball's JotW.

I like The Register because they cover the stuff I'm interested in, and their leanings correlate reasonably well with my own. But they don't edit their stuff, and have no shame about being wrong or just lost in left field. Today's example:

Android: developer dream or Google cash machine?

By Phil Manchester

Published Friday 16th November 2007 18:49 GMT

However, it will take more than a $10 million "incentive" (http://www.sci-tech-today.com/story.xhtml?story_id=030002Y7BBKU) to truly galvanize people and generate a powerful and self-sustaining grassroots developer movement and ISV community. Some of the open source technologies changing today's market, after all, built up critical mass because they were good, useful or employed a community friendly license - not because early developers got huge cash dongles.

Um, no. People write free and cheap Palm, Symbian, Windows Mobile, Google Maps, and (now) iPhone apps all the time. You don't need to pay them $10,000,000 to do so.

Google's Android agenda is far from clear, but it seems money is a driving factor, rather than a genuine desire to liberate developers and phone users from the nasty old telcos with an open platform. After all, Android's backers include some of those very carriers that liked to lock you in (http://www.openhandsetalliance.com/oha_members.html) and have proved nothing more than an anchor on software and service innovation, but who just happen to be lagging the US market leaders.

See, the logical fallacy here is more subtle, but still big enough to throw a phone through. Google has never claimed that money wasn't a driving factor. There are lots of people who are interested in Android for primarily non-commercial reasons. Nobody who's awake ever thought Google (or the other Open Handset Alliance members) were among them. It's "Don't be evil.", not "Liberate developers." Whether or not you think Google is evil (I think they're scary and cool, but not evil), they never pretended Android wasn't supposed to make much money. Is there anyone, aside from Phil Manchester, who didn't know that Google likes to make money and is quite good at it?

Enlightened capitalism maybe - but capitalism just the same.

Duh.

Friday, October 19 2007

Cracking Apple's Code: 1,500

A bizarre and perverse journey is completed. At 12:21am 2007/10/19, I reported my 1,500th documentable bug to Apple. I have actually reported a bunch more over the years, which have since been lost to the sands of history. I remember reporting bugs against eWorld and Newton beta software! But I can currently identify 1,500 bug reports against Apple's products.

A few of these, of course, are bogus -- there have been times I just made a mistake, and thought it was an Apple problem. Some of my mistakes indicate that Apple's user interface needed clarification or improvement; others are simply my foolish mistakes.

Many of my reports are documentation issues. Right now, I'm looking at Apple's thousands of pages of brand-new documentation on Mac OS X 10.5 "Leopard" Server and sighing (repeatedly) -- I don't have time to read the half on topics that interest me -- but as an admin, the documentation has to be correct. Rockefeller has an Apple Enterprise Support contract, but they are limited, expensive, and problematic to use. Most Mac admins have to make do with peer support, and Apple supports this because Apple only has to support (some of) the fora -- not pay support staff. This means Mac admins need to be able to help ourselves through researching and the documentation. Ambiguous or simply incorrect documentation is bad. Fortunately Apple aspires to perfection (though they don't always aspire very hard -- the early Mac OS X manual pages were badly neglected).

Other reports are feature requests, handled slightly differently but through the same bug reporting system. For example, I want to use my iPhone as a secure password store, an offline web browser, and with a Bluetooth GPS. Feature requests are how I tell Apple my priorities for product development -- sometimes they even pay attention! ;)

And lots of bug reports are bugs. This is a bittersweet time, as I recognize my reports behind a bunch of fixes in Leopard, but I also know I'm about to lose a lot of traction. Until very recently, Apple has been focused on perfecting Leopard -- meaning things have been fluid and could be improved, and there was lots of pressure to fix bugs. Now that they have finalized 10.5.0 and are preparing to sell it, the developers are hoping they didn't miss any hideous bugs and recovering. In a little while they'll go back to the grindstone to start fixing and building 10.5.1, but 10.5 will never be as flexible again. It's going to be a while before I can start pestering Apple about what to do for Mac OS 10.6, and various bugs or design flaws will be too large to build into a point release, meaning they are already baked into the 10.5.x series, not eligible for fixing during Leopard's lifetime.

Tuesday, October 16 2007

AppleCare let me down

Last night, the AppleCare phone rep assured me that Apple would replace or repair my iPhone free under AppleCare. At rubber vs. road time, however, the Apple "Genius" showed his sad face and explained that AppleCare only covers defects in manufacture (which would make it useless, as you'll almost always find those within the 90-day warranty). My (second) replacement iPhone cost me $249 + tax (why do they charge tax for a service replacement??), or $279 today.

I also got a rubber shell to protect the iPhone, since I obviously can't depend on AppleCare for any repairs in the future.

Unfortunately, all these protective wrappers make the iPhone larger (and less pretty). This wouldn't matter so much if Steve Jobs hadn't sold the svelte elegance of the iPhone so heavily. So the three iPhone holsters I bought (all problematic for one reason or another) won't fit, and nobody should use them, since iPhones really need full-time protection (meaning a sleeve or hard case). I'll stick with my $5 Treo (650) case, which is large enough for 2 iPhones, or one iPhone in an incase sleeve.

Regarding Apple Support: It's nice to have good things to say, I am now a sad panda.

Apple Support: It's nice to have good things to say

Update: See next post, "AppleCare let me down".

This morning, when I tried to play music on my iPhone, it told me I had "No songs" on the iPhone. I couldn't even use the bottom buttons to switch to video mode, but Settings:General:About told me I had "0 Songs" & "0 Videos", even though I only had 420mb free on the iPhone. I keep 4gb of music on the phone, so they were obviously onboard, just not accessible. No problem, I figured -- this is exactly what iPhone Restore is for.

Adding injury to insult, tonight I noticed that the iPhone kept raising the ringer volume spontaneously. I keep it in vibrate mode, so this isn't such a problem, but I thought my new Luxmo case was bad. Alex has one that's not quite right, so I got the other two models, and they're both quite flawed -- hard to get the iPhone out, and one presses on the power button -- I keep taking the iPhone out and seeing the prompt to do a full shutdown. I now suspect my problem wasn't the case, because I saw the iPhone's metal shell itself is a bit bent, and the volume up button is stuck in. Hopefully a belt holster didn't do that!

I plugged the iPhone into my MBP, and it picked up the iPhone's version, serial number, and phone number, but instead of 8gb, iTunes showed its capacity as "n/a". I tried to do a full restore, and it failed:

The iPhone "iPhone" could not be restored. An unknown error occurred (-18).

This was bad -- I couldn't get today's photos or PIM updates off the iPhone, and I couldn't restore it.

I reset all settings -- avoiding the full wipe in case I wasn't able to get data back onto the tabula rasa iPhone. I thought it might be a bad cable (unlikely -- it was fine yesterday), or bad Dock port on the iPhone (damaged at the same time as the volume control, perhaps?). I tried the MBP's other USB port, and Amy's MacBook -- still the same error -18.

I called Apple Educational Support, but they were closed. I called Apple iPhone support (800 my iPhone), which is open later (24 hours?), and spoke to a very nice fellow who couldn't find error -18, but talked me through putting the iPhone into Restore mode:

  1. Launch iTunes.
  2. Turn iPhone off (hold down top power button & swipe when prompted).
  3. Hold down Home button.
  4. Plug iPhone into USB/Dock cable.
  5. iPhone shows a picture of a Dock cable being plugged into the iTunes CD icon.
  6. Release Home button.

The first time, this didn't work -- iTunes didn't notice the iPhone. That was very worrisome, but the second time I tried, it restored the iPhone. Perhaps a full wipe (can be done with Home & Power on the iPhone, or from Settings:General:Reset) would have done it too.

I asked about the volume buttons, explaining the case is bent, and was told I can get a box and send it in, but return takes 5-7 days. My several PowerBook repairs have been consistently faster than the official time estimate, but this is still not a good option. The alternative is to bring it to an Apple Store and get it either replaced or repaired. They can provide a loaner "service iPhone" for $29, but this fee is waived as part of my AppleCare contract. Hopefully they won't give me a hard time about what's covered under AppleCare -- Apple's policies for what it covers are considerably more stringent than phone companies, who are very flexible about what they cover.

The AppleCare Protection Plan for iPhone Terms and Conditions includes the following:

b. Limitations The Plan does not cover:

...

(ii) Damage to the Covered Equipment caused by accident, abuse, neglect, misuse (including faulty installation, repair or maintenance by anyone other than Apple or an Apple Authorized Service Provider), unauthorized modification, extreme environment (including extreme temperature or humidity), extreme physical or electrical stress or interference, fluctuation or surges of electrical power, lightning, static electricity, fire, acts of God or other external causes;

...

(iv) Problems caused by a device that is not the Covered Equipment, including equipment that is not Apple-branded, whether or not purchased at the same time as the Covered Equipment;

...

(xiii) Except as specifically provided herein, any other damages that do not arise from defects in materials and workmanship or ordinary and customary usage of the Covered Equipment.

Unfortunately, the Apple "Genius Bar" always requires a significant wait, even with an appointment. The concierge site is currently down, but hopefully I'll be able to minimize the wait by making an appointment before I head in http://concierge.apple.com/store/R095.

Restoring was complicated by the stuck volume button -- it apparently kept registering during the restore, aborting the sync. I eventually got it all restored, though.

Thursday, October 11 2007

iPhone vs. sieve filtering

The iPhone makes heavy use of email. It's the easiest way to send yourself a URL and the only way to get Notes out of the iPhone (for now, at least).

I generally try to filter as much as possible out of my INBOX, including mail from me (mostly replies to mailing lists I'm on, and I don't need to read what I just wrote), but I want mail from my iPhone to stay in the INBOX where it's easy to find. I was annoyed that my sieve filters apparently cannot match on the body of messages, only on headers, but the solution turns out to be very easy -- I put this at the top of my sieve file, and now mail from my iPhone (but not my Macs) shows up in INBOX:

# personal short circuit
if allof
 (
  header :contains "From" "pepper@",
  header :contains "X-Mailer" "iPhone Mail"
 )
 { stop; }

Saturday, October 6 2007

iPhone: Zoom Zoom Zoom

iPhone zooming is complicated. When designing MobileSafari (the iPhone version of the Safari web browser), Apple opted to preserve the desktop Safari experience as closely as possible. This lets them talk about "the real web in your pocket", and provides Apple an opportunity to sneer at competing handheld devices that present "the mobile web" instead. The reality, of course, is that there's some value to the mobile web, or it wouldn't exist. The issue is that the iPhone is quite limited compared to a Mac or PC 'desktop' (or laptop) computer, so mobile browsers have been making trade-offs for years to come as close as practical to the desktop experience, while accepting that there must be deficiencies.

One area where Apple's desktop mimicry is particularly clear is in page rendering. MobileSafari appears to first calculate how desktop Safari would lay out a particular page, then compress it to fit on the iPod's relatively tiny screen, and let you zoom around the page to read content of interest. This gives great demo, but begs the question: When I'm reading a web site on my iPhone, why would I care what it looks like on my desktop? My desktop has 4,224,000 pixels, a full keyboard, and a 5-button 2D scrolling mouse. My iPhone has 153,600 pixels (less than 1/27th as many) and 10 fat fingers. Denial of these differences is a neat trick, but can never completely succeed.

For comparison, Plucker focuses on getting easy-to-read text onto a handheld device, with optional support for anti-aliased fonts and images up to the maximum display quality of the Palm's screen. This means lines wrap wherever they fit, text is whatever size you choose (although the built-in set of fonts is quite limited), and web pages look nothing like they would on a full-sized computer. Plucker's display model is quite popular, and very much "the mobile web" Steve Jobs scoffed at, although Plucker for offline web browsing -- it predates the iPhone's 802.11g and EDGE standards. A full-sized computer downloads web pages, reformats and compresses them for the Palm, and stores them for later downloading. The Palm part works even without a network connection -- subways passengers, rejoice!

Similarly, one almost always wants to scroll a full page in a web browser and the Palm has physical keys for this, but the iPhone instead scrolls based on how far and fast you flick. I'd prefer an option (at least in MobileSafari) to always scroll by a page. This would save me both the effort of figuring out how far and fast to flick, and time finding my place after scrolling.

My initial reaction to MobileSafari was that the fonts were surprisingly fuzzy and hard to read. Naturally -- they were designed for computers with more and larger pixels, being scaled down by the iPhone's smaller pixels, and scaled again to fit on-screen. Sometimes fonts are scaled up, to make them easier to read. In contrast, Plucker never scales its fonts.

Craig Hockenberry's furbo.org has several articles on the iPhone, including pointers for web designers on how to manage iPhone scaling. It doesn't answer my question, though: How can I choose a particular font size, and get the iPhone to wrap text to fit? Unfortunately, I don't think there is an answer right now.


MobileSafari scaling is complicated and occasionally buggy. I am aware of these scaling options:

When a page is loaded, the iPhone renders it as closely as it can to the way desktop Safari would -- not at all based on the iPhone's capabilities, but instead for a fictitious Mac. Then it shrinks everything down to fit the width of the iPhone's screen (either 320 pixels in vertical mode, or 480 in horizontal mode).

I tried to duplicate the iPhone's default scaling, and it was a pretty good match for a 684-pixel-wide by 695-pixel-high Mac Safari 3 window (475,380 total, over 3 times as many pixels as an iPhone has). At 72dpi that would be 9.5" by 9.65", or 13.54" diagonal; on a 110dpi 15" MacBook Pro it's 6.22" by 6.32", or 8.86" diagonal. In contrast, the iPhone screen displays the same text at 2" wide by 3" high, or 3.5" diagonal. Tiny!!

If you tap twice on a column of text, the iPhone zooms to fit the column to the width of the screen. For pages that have no native width (plain HTML, no layout), tapping twice centers the tapped paragraph on-screen -- very handy for scrolling, as you can just tap at the bottom of the screen each time you get to the end of the page. For pages with layout, tapping twice a second time zooms back out.

If you tap twice on an image, the iPhone zooms to fit the entire image on-screen. It does not work for all images, such Questionable Content -- perhaps because QCs are too tall, and MobileSafari doesn't even try to fit them.

If you place two fingers on the screen and pinch them together, the iPhone zooms out. If you "unpinch", it zooms in. Unfortunately the iPhone does not reflow the text to fit edge-to-edge, so this is almost never convenient for reading -- either space is wasted or text is off-screen.

That's six different zoom options and I may be missing more. But none is the one I want (which would be easiest to read) because the iPhone's browser always wraps text to match desktop Safari, and never to provide the most readable page on the iPhone.

In reality, I double-tap almost every page to zoom a column to full width, and then hope that I can read the text in either vertical or horizontal mode. Usually I can.

I find the whole subject disappointing. I had more readable web pages on the Treo 600 and 650 for years! Apple could make the iPhone a superior device for reading web sites and ebooks, but has instead gotten hung up on "the real web in your pocket" and pretending that iPhones are running desktop Safari.

Update 2007/10/26: Apple's just-released "Safari on iPhone Part II: Optimization" video discloses that the iPhone renders everything to 980w * 1091h, presumably calculated based on the usable width of a browser window on a 1280x1024 17" LCD after menu bar, Dock, and Safari controls. This leaves me wondering why 684w * 695h was such a close match.

I've added a couple lines to a couple of my pages, and they improve iPhone presentation substantially (no, they aren't new, but they do work):

<meta name="viewport" content="width=device-width">
<meta name="viewport" content="initial-scale=.8">

Monday, September 24 2007

iPhone Link Farming

The iPhone doesn't support a start/home page. Every time you open a new Safari page (equivalent to a tab) it opens to a new page, unless you open it from another page with a "target" attribute. Fortunately, its MobileSafari browser is very smart about suggesting recently visited sites; typing one or two letters typically brings up the site I want as a suggestion. Email addressing works the same way -- it appears to prioritize recently used addresses, so if you visit the same sites (or email the same correspondents) repeatedly, it's usually right.

On the other hand, sometimes you want a "link farm" (bookmarks page). I keep one with a bunch of links, both for use on the iPhone itself and also for visiting on Macs for working with the iPhone: http://www.reppep.com/~pepper/iphone/. I'm a big fan of tabbed browsing on desktop computers (ever notice how, in relation to iPhones and other handheld computers, laptops become "desktops"?). On the iPhone, I prefer to keep my bookmark page open, and open new tabs off it. There's a JavaScript bookmarklet to make every link open a new window, but it doesn't do the trick for me.

Instead I keep my iPhone bookmarks on a simple page containing a few lists of links. Since this page changes frequently, I have a BBEdit GREP Pattern to do the necessary. It converts a plain URL, into a proper <a> tag with a unique target attribute (the hostname), and wraps the whole thing in a <li>/</li> pair; this gives me a readable and clickable link that opens in a new window. I tried target="_new" and target="_blank", but no joy. Here's the pattern, to save time for future link farmers...

Search for: ^(https?://)([^/\r]+)(.*)$

Replace with: \t<li><a href="\1\2\3" target="\2">\1\2\3</a></li>

- page 1 of 2