Review: 2046

Whenever someone asked why I left 2046, I always gave them some vague answer. It was easier.

So began 2046, the new film written and directed by Kar Wai Wong. It continually amazes me when I watch a subtitled film, particularly at the cinema, how quickly you begin to ‘hear’ the actors saying the words in English. Films that draw you in, like 2046, with it complex, interwoven relationships between reality and the text the main character writes, quickly become as easy to follow (in the dialog sense, not necessarily the plot sense!) as a film in your native language. And 2046 was certainly a film that you had to work to follow. Beginning in (what we later find to be) the fictional world (/place/time?) of 2046, we see a Japanese man, on a train, counting incessantly. This quickly returns to when Chow, the main character and journalist/writer, was preparing to leave Singapore. The bulk of the story takes place in the hotel in Hong Kong where Chow lives throughout the second half of the 1960s. The film focusses on his relationships with several women. The first woman we learn about is LuLu, also known as Mimi, a girl he knew in Singapore, who has apparently forgotten him. After she is murdered, he wants to move into her room, 2046, in a (small?) hotel; but it is unavailable, and he moves into 2047 instead. He comes to like that room, and stays there, and has relationships with Bai, and Wang Jing Wen, the eldest daughter of the hotelier. I won’t say any more about the plot, other than it’s worth it.

Do you know what people did in the old days when the had a secret? The used to climb a mountain, find a tree, and cut a hole in it. They, they would whisper their secret into the hole, and fill it with mud. That way, no-one would ever find out their secret.

Films like this are thought provoking. When you walk out of the cinema wanting to talk about the film, and what it’s really about, you know the little over 2 hours you spent there was worth it. Jaq was of the opinion that the film is about unrequited love: loving what you can’t have. Jing Wen loves Tak, but is not allowed by her father to be with him; Chow loves Jing Wen, but she does not love him, she only loves Tak; Bai loves Chow, who does not love her. Do people love one another more if they are not loved back?

(Bai) - Can I borrow you tonight? (Chow) - I promised myself there was one thing I would never lend someone else.

What is it that Chow has vowed never to lend? He doesn’t say, and that to me is the key to films like this. I interpreted it that Chow never wanted to lend someone “false hope”; Jaq interpreted it that we would never lend his love. Leaving something to the imagination, while still providing a framework to make an interpolation means that people take from a film according to what they put in, and are capable of thinking. All of the women in 2046 are stunning beauties. When some of them ‘become’ androids, apparently they are airbrushed: I didn’t notice. The (near) flawlessness of their faces (and bottoms, which get quite a lot of screen time) mean that they could be inhuman. Apparently, each of the actors only speaks in their language, yet they all understand one another. I did notice there were several languages (Chinese, apparently both Cantonese and Mandarin, Japanese, and Cambodian - or something else), but I think that only adds depth and magic to the film. I didn’t realise until reading another review (post-watching) that some of the characters (Chow, and Su Lizhen #1) are in his previous film, In the Mood for Love. That might be next on the DVD list. Verdict: I love it.

TransAdelaide Rail Safety Advertisement

I saw a great ad on TV tonight. It had a female cyclist walking her bike along ready to cross the railway tracks, and then cut to two young boys walking/playing along a section of track. The boys played with a ball, and then it cut back to the cyclist, as the lights started to flash, and she stopped at the crossing. The boys’ ball bounced ahead of one of them, and he ran to get it, the other heard the train coming, and moved off the track. The train was shown going right up to the boy, and then some Computer Graphics virtually made him turn to dust as the train would have hit him. The cyclist waited until the train had crossed, and then proceeded to cross the tracks, not seeing the train on the other set of tracks, coming from the other direction. The same CGI effect was used as she was hit by the train. I’d record and post the ad here, if I had a digital video recorder… The power of these ads was quite impressive. I catch the train, and I have to cross the track every morning and night. (There is an underpass at the other station I get off at). Whilst there is only one metro train track - the trains need to wait at a larger station if one of them is a little late - there is a second line, for interstate freight and passenger transport. It surprises me how often I see a kid get off the train, jump down onto the track and walk off along the track. And the thing about it is that doing that isn’t any quicker. I have seen kids do that, and leave the tracks at the crossing, at the same time I arrive there. I guess it’s just a need to do the wrong thing, but most of the time they are by themselves! The other morning I saw a kid walking along the track towards the station - I didn’t see from how far he walked along the rails, but it must have been a significant distance, as there are no houses or roads near where he came from. I can sort of understand someone getting off the train knowing there will be no train for at least 10 minutes (due to the single track), but unless the morning kid saw a train go past, he could not know how long it would be before the next train arrived. The one from 5 minutes ago could be late, and he might not realise in time…it scares the hell out of me. Not for my safety, but for the fact I would be the person who witnessed the accident. I would have to live with the consequences of a stupid kid being hit by a train in front of me…maybe I’m being selfish, but I don’t care. I actually have a fear of being hit by a train. I’m not sure why, but every time I walk across the track, I think that I will get my foot caught in the line, and not be able to move in time. I also don’t take my wallet out of my pocket until I am in the train, as I see myself dropping it, or my train ticket down the gap between the train and the platform. This means that at Adelaide Railway Station, I go through the gates, taking my wallet out, and putting my ticket into the machine. I then put my wallet away before I get to my train, and board the train, and then take my wallet out again. I think I’m crazy.

Renaming Songs

I had thought that renaming a track from one user of a shared iTunes library (where the files are shared, but each has her own library file, with ratings/play counts, etc) would cause iTunes to not be able to find it for the other users. But, I renamed “Tom’s Dinner” to “Tom’s Diner” (Suzanne Vega), and switched over to the other user, thinking I’d have to do the old Find Track trick, but iTunes was smart enough to realise that the track it needed had changed name…and updated the library automatically.

Livin’ Thing • Greatest Hits • Electric Light Orchestra

iTunes Compilations, and Duplicates

I have one feature I’d like to see in iTunes - the ability to mark tracks as ‘identical’, and have them belonging to two (or more) albums, but sharing the rating, play count, and even disk space. That would be cool. Especially since I have lots of tracks in this situation.

realdump: dump RealPlayer stream to file

The following function/script will dump the data from a RealPlayer stream to disk as a WAV file. Put it into your ~/.profile, or make a shell script out of it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    function realdump
    {
        if test -f $1 ; then
            realdump `cat $1`
        else
            export temp=${1/#*\//}
            export filename=${temp/.*/.wav}
            ~/bin/mplayer -cache 128 -vc dummy -vo null -ao pcm -aofile $filename $1
        fi
        if test $_# -gt 1 ; then
            shift
            realdump $*
        fi
        
    }

It creates a file with the same basename (the filename minus the extension), with an extension of .wav; there is no checking to see if the file exists already, and old file will be overwritten. The argument to realdump can be either the URLs of the streams, or the name of a file with the URLs of the streams in it. It should handle files with multiple entries, so you can concatenate a series of .ram files, and it should download each of them in turn. Ensure they have different filenames, not just different directories!

Downloading RSTP streams.

The BBC has a heap of stuff available on their website as part of the Beethoven Experience, but I found my copy of RealPlayer had expired. I’d rather dump the data to disk and listen to it later (on my iPod, probably). But, the only ways I could find to do this didn’t work with the software I had. Specifically:

1
    mplayer -dumpstream rtsp://rmv8.bbc.net.uk/radio3/classical/pizarro/sonata01.rm

fails, as does using VLC. I’m downloading newer versions of both of these, but I’m not that hopeful. Mplayer seems to not want to access network protocols, VLC cannot decode. Nor can it just dump to disk, without interpreting the data.

iTunes Shared Library Checker

I now have the code to check the library XML file and see if there are missing tracks (ie, the files are not where they are expected to be). This code is quite slow, but simple to follow. (It took around 2 min to run). I also have the code that gets a list of the files in the library directory. It must be simple to combine this information, and work out which ones are:

  1. Files that are ’new’: they only exist on disk, not in the library. Chances are they were added by another user.
  2. Files that have become detached: there is a file and a library location, but they don’t quite match up. This is probably because the users have ‘Keep Library Arranged’ turned on, and one of them has made a change to a track name, artist or album; or made a change to the compilation flag.

The trick will be having the list of files, and removing items from the list that have been located in the library. This will leave list that just need to be sorted into alpha and beta above.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    import os
    import urllib
        
    library = os.path.expanduser('~')+'/Music/iTunes/iTunes Music Library.xml'
    startpath = '/Volumes/Media/Music'
    def greppy(library)
        data = open(library).readlines()
        tracks = {}
        this_track = 0
        for line in data:
            if line.count('<key>Track ID'):
                this_track = line.split('integer>')[1][:-2]
            elif line.count('<key>Location</key>'):
                tracks[this_track] = urllib.url2pathname(
                         line.split('string>')[1][16:-2]).replace(
                         '&#38;','&')
        
    findstr = "find "+startpath+"-type f -not -name .aacgained -not -name ._* -not -name .DS_Store | sort"
    treedata = os.popen(findstr).readlines()
        
    data = greppy(library)
        
    missing = {}
    surplus = treedata[:]
        
    for i in data:
        try:
            surplus.remove(urllib.urlopen(data[i]).url[7:]+'\n')
        except IOError:
            missing[i] = data[i]
        except ValueError:
            pass

This leaves two data structures of interest: missing, a dictionary with the ‘missing tracks’ from iTunes, and surplus, a list with files that do not have an associated iTunes library entry. Note: I’ve turned off comments, as this post seems to get a lot of comment spam.

Extracting Data from XML

Python does have tools for grepping XML files, but I’ve never been able to get them to work to my liking. I’ve generally just stripped out the data I need. And I will continue to do so, as it’s probably much faster than filtering through all of the crud I don’t need.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    library = os.path.expanduser('~')+'/Music/iTunes/iTunes Music Library.xml'
    data = open(library).readlines()
        
    tracks = {}
    this_track = 0
    for line in data:
        if line.count('<key>Track ID'):
            this_track = line.split('integer>')[1][:-2]
        elif line.count('<key>Location</key>'):
            tracks[this_track] = urllib.url2pathname(line.split('string>')[1][16:-2]).replace('&#38;','&')

The above code will search through the library file, and grab info on each track: just the database ID, and the location (which is a URI, encoded to remove spaces and dodgy characters. The info is then put into a dictionary, where the key is the database ID, and the value is the location. Note that there is a replace() at the end of the last line - for some reason python’s urllib.url2pathname() function doesn’t replace & characters - I guess that’s because these aren’t really intended to be in a filename. Also, on my NSLU2 the extended characters are replaced by underscores, but I’m going to update to samba 3 (at the risk of mucking up the entire library…) to see if this fixes that issue. Anyway, after coding this, I had a bit of a think, and came up with the following method of doing the same (ensure it’s all on one line):

1
2
3
    grep Location ~/Music/iTunes/iTunes\ Music\ Library.xml |
      awk 'sub("<key>Location</key%gt;<string>file://localhost","",$1)' |
      sed 'sx</string>xx'

The python version uses between 5-8 seconds of CPU time, the grep version around 1.5, but does not associate the database ID’s with the locations, which I need. It also looks to be much easier to do the changing of characters (%20, for instance, into a space) that I need to do so I can check to see if files exist. Actually, using urllib.urlopen(), I can use the escaped/quoted version to see if the file exists, but it might be slow.

Find Missing Tracks

Continuing on from my last programming related post, I’ve been giving some thought to the opposite problem: when tracks are in the iTunes Library, but the file they refer to is not there. iTunes marks these with an exclaimation mark in front of the track, but only if it realises they are in fact missing. Often, just clicking on a track does not mean iTunes knows that track is missing. A Get Info on such a track prompts the user for a choice between removing the track from the library, or locating it. It might be possible to use the following AppleScript paradigm to get a list of the tracks that are missing:

1
2
3
4
5
6
7
8
9
tell application "iTunes"
    set theTracks to every track in playlist 1
    set missing to {}
    repeat with theTrack in theracks
        if location of theTrack is [unknown] then
            set missing to missing + theTrack
        end if
    end repeat
end tell

Of course, that would be dead slow, as it relies on a couple of AppleScript events for each track. (Also, it may not work, but some sort of try - else - end try clause might work.) A better solution might be to sort through the iTunes Music Library.xml file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    import os
        
    data = open("iTunes Music Library.xml").readlines()
    missing = []
        
    for line in data:
        if "<location>" in line:
            #extract location
            location = line.split("/Volumes")[1].split("</location>")[0]
            #check if location is not a file
            if not os.path.isfile(location):
                missing.append(location)

Assuming that the mount point is the same as the last time the XML file was written (and iTunes seems to be pretty clever about working out things like /Volumes/Media vs. /Volumes/Media-1, then your list missing should contain a list of files that are in the library, but not where iTunes expects them to be. It might be possible to then match these two lists (from this script), and see which ones are likely to be ‘modified tracks’, where one user has changed the track name, artist or album. It may even be worthwhile having a list of all track locations, and seeing if there are any duplicates, that will solve the problem of duplicates int he library that are the same file. I’d like to have python parse the XML file, and create data structures reflecting the XML data - but skip everything but the database ID and filename, as these are the things that we really need - but I haven’t had much luck with this type of process in the past. I jsut had a thought on how to do it, though.

Sing-along Music

Note to self: Classical Music is good public transport music. Why? Because you are less likely to sing along. People look strangely at you when you sing on the train, for some reason.