Comments on Steve Jobs’s “Thoughts on Flash”

The original post by Steve Jobs’ “Thoughts on Flash”,

I was reading HTML5′s pros and cons the other day, and that reminded me of Steve Jobs. Jobs talked about Apple’s relationship with Adobe, and he also talked about his/Apple’s decision on Flash. That is, Apple is not going to support Flash in any of their products. Instead, Apple’s going to prompt open technologies like HTML5, CSS3, and Javascript. The above is the very high-level summary of Jobs’s “Thoughts on Flash”.

First, there’s “Open”.

Adobe’s Flash products are 100% proprietary. They are only available from Adobe, and Adobe has sole authority as to their future enhancement, pricing, etc. While Adobe’s Flash products are widely available, this does not mean they are open, since they are controlled entirely by Adobe and available only from Adobe. By almost any definition, Flash is a closed system.

I completely agree with Mr. Jobs. Although there are a lot of debates on Openness vs Closeness,  I have been always a big fan of open-source software and companies. I have never really forced myself to learn any Flash-related technologies. It’s not because I was lazy to learn it, but I thought there was never really a  need to learn it, that’s all. I always avoid using Flash in my webapps, even websites although Flash is highly demanded by most of customers. I don’t blame them. What I did is I told them the same effect or maybe a better effect can be done by not using Flash. And they were all OK with that. What does that tell us? It’s not Flash that customers need, but the final effect.

To be continued…

Setting Up Your Home Router And a Linux Server

This is a quick tutorial/demonstration on HOW-TO setup a linux server at home. At the end of tutorial, you should expect to have a linux server running apache2, which can be accessed anywhere in the world by type in “” in a web browser.

Keywords: Router, Priviate IP, Dynamic IP, Static IP, Ubuntu Server, Apache Server, Np-IP, Free Home Server

Here is a list of concepts you need to know before reading the rest of this tutorial.

Public/Private IP:

What are private and public IP addresses?
A computer on the Internet is identified by its IP address. In order to avoid address conflicts, IP addresses are publicly registered with the Network Information Centre (NIC). Computers on private TCP/IP LANs however do not need public addresses, since they do not need to be accessed by the public. For this reason, the NIC has reserved certain addresses that will never be registered publicly. These are known as private IP addresses, and are found in the following ranges:
From to
From to
From to


 Its basic job is to turn a user-friendly domain name like “” into an Internet Protocol (IP) address like that computers use to identify each other on the network. It’s like your computer’s GPS for the Internet.
Dynamic IP:
Router Virtual Server:

Ok, let’s get a rough idea how this looks like in a big picture.

figure 1

So, in this model, you have your local ISP provider, such as Rogers, Bell, or Teksavvy, provides you the internet access with a dynamic public IP (assuming that you are not paying extra to get a static ip, if you are not sure if you have a static ip, just assume that you don’t have one for now). So now, say is your public IP, which can be accessed anywhere in the world to locate your physical. An important note here is that, all the sub-computers under your router have the same Public IP(@, however, router will assign an unique Private IP to each computer individually (as the 192.168.* shown under each computer)

Also, in this model, you have your PC1(@, and your Ubuntu Server 10.04 (@ connect to your router (@ Your router should have a GUI interface that looks like this:

figure 2

So now, if someone type in your public IP (@, the DNS will take them to your router. In such case, they will most likely see the “404 Not Found” page. That’s because for security reasons, your router doesn’t like public access unless you specifically tell it that public accesses are acceptable.

However, that’s not the end of the world, most router today support a feature called “virtual server”, sometimes its also called “port forwarding”. What it does is that it creates a mapping between the router and the computers that connect to it. For example, if you create a virtual server as it’s shown in figure2:

IP Address is the target computer, which is your Ubuntu Server@ (with Apache2 running)

Public Port is the port that people around the world will use to access your server. In our example, it’s 80.

Private Port is the port that your Ubuntu Server@ uses for Apache2, by default, it should be 80 as well.

So in general, if someone type in on a browser’s URL, the DNS will take it to your router, and your router will map the 80 port to @ at port 80, which is the Apache2 Server on your Ubuntu Server@192.168.110

In short, the setting above will do this for you:

http://public_ip:public_port/ => http://private_ip:private_port/

Congratulations! Now you have a server that anyone in the world can access to. So, what’s next?

If you want to have more convenience access to your Ubuntu Server without type in the tedious IP, instead of a easy-to-remember domain, the following is for you.

All of the issue here is that we don’t have a static public IP. So what can we do about this:

  • Contact your ISP see if a static IP is available for you. Usually, this will cost money, but it will save you a lot of troubles.
  • Setup a background service that checks your IP periodically, and updates it to a DNS.

And in this tutorial, we will go for the second option, which is to setup this background service.

No-IP is all that we need:

  • It checks your Public IP every 5 minutes, and updates it to No-IP’s DNS.
  • It provides sub domains to map your Public IP, such as * subdomains. (I registered, and No-IP maps it to my dynamic Public IP, so people can just visit my Apache2 server by
  • It’s free. (Well, you could pay to get more features, but the basic feature is more than enough for our task)

Setting this up is very easy. There are instructions available here:, and I will not repeat them here.


here are some more tips:

  • You can buy a domain name like, and redirect to So people can just visit your Apache2 server by
  • You can create more virtual servers on your Ubuntu Server, such as mapping port 21(FTP), 22(SSH), and some other application ports you will need.
  • You can create a file server on your Ubuntu Server, and serve as a online backup solution for your laptops/mobile device
  • You can get a very cheap and dedicated server machine from “IBM Certified Used PC” (Make sure you enter IBMEPP as the promotion code to get the employee discount)

There are some useful tools to manage your Ubuntu Server. I have the following tools installed:

  • webmin: Webmin is a web-based interface for system administration for Unix. Using any modern web browser, you can setup user accounts, Apache, DNS, file sharing and much more. Webmin removes the need to manually edit Unix configuration files like /etc/passwd, and lets you manage a system from the console or remotely
  • Transmission: It’s a torrent client. It has a web interface, so everyone in my house can use it to torrent files. We normally use it to torrent TV shows, Movies, and Music. And the files will be stored in the Ubuntu Server, and everyone in the network can share them. So that we don’t have to download the same TV show multiple times in the same house. 
  • XBMC. XBMC is a open-source media centre. Since I have a TV connects to my Ubuntu Server, so I can watch movies, TV shows, and even youtube on my TV without paying the TV cable (yes, I am cheap). Setting XBMC on Ubuntu is very straight forward, the instructions are available on its official website, and/or on its community bulletin board.
  • Mercurial Server. (Ignore this if you don’t know what it is)

A Python auto-youtube-downloader

Finally, the Winter break is here. And I have some time to catch up with one of my favourite Taiwanese shows: 康熙来了(Kang Xi Lai Le). However, I find it very annoying to stream it on Youtube, so I wrote a script to auto download those FLVs to my home server, and watch them locally. Also, thanks to the author(s) from for organizing the shows on their Youtube channel, so that this script can just get the show URLs from their website without using the Youtube API to get the RSS update from their Youtube channel.

The script is available here:


1. youtube-dl

youtube-dl is a small command-line program to download videos from and a few more sites. It requires the Python interpreter, version 2.x (x being at least 5), and it is not platform specific. It should work in your Unix box, in Windows or in Mac OS X. It is released to the public domain, which means you can modify it, redistribute it or use it however you like.

2. YQL (Yahoo! Query Language)

The Yahoo! Query Language is an expressive SQL-like language that lets you query, filter, and join data across Web services. With YQL, apps run faster with fewer lines of code and a smaller network footprint.

Yahoo! and other websites across the Internet make much of their structured data available to developers, primarily through Web services. To access and query these services, developers traditionally endure the pain of locating the right URLs and documentation to access and query each Web service.

With YQL, developers can access and shape data across the Internet through one simple language, eliminating the need to learn how to call different APIs.

And this is how I use them:


import sys, os
import yql
from datetime import date
from subprocess import call

def getQuery(d, i):
query = "select * from html where url=\"\" and xpath=\"//div[@id='playerdiv']\"" % (d, i)
return query

def main(d):
if d == None:
d ="%Y-%m-%d")
y = yql.Public()
for i in range(1,6):
query = getQuery(d,i)
result = y.execute(query)
link = result.rows[0]["iframe"]["src"].split("?")
name = "%s_part_%d.flv" % (d, i)
call(["youtube-dl", link[0], "-o", name])
call(["mencoder", "-forceidx", "-of lavf", "-oac pcm", "-ovc copy", "-o %s.flv" % (d), "%s_part_*" % (d)]) # merge the parts into one file
call(["rm", "-f", "%s_part_*.flv" % (d)]) # remove all the parts
call(["rm", "-f", "*.part"]) # remove all the partial downlaods

if __name__=="__main__":
print "Downloading Kangxi on %s" % (str(sys.argv[1:]))
if(len(sys.argv) > 1):
for d in sys.argv[1:]:

Place in your system’s Path, and to download today’s episode, run kangxi without any arguments.
Or oo download Kangxi on a specified day:

maximmai@turtleland:~/Public/TVs/KangXiLaiLe$ kangxi 2011-12-28
Downloading Kangxi on ['2011-12-28']
[youtube] Setting language
[youtube] wsxY5qoXiaE: Downloading video webpage
[youtube] wsxY5qoXiaE: Downloading video info webpage
[youtube] wsxY5qoXiaE: Extracting video information
[download] Destination: 2011-12-28_part_1.flv
[download] 100.0% of 79.10M at 186.44k/s ETA 00:00
[youtube] Setting language
[youtube] LW54AGoxsto: Downloading video webpage
[youtube] LW54AGoxsto: Downloading video info webpage
[youtube] LW54AGoxsto: Extracting video information
[download] Destination: 2011-12-28_part_2.flv
[download] 63.9% of 92.85M at 181.42k/s ETA 03:09
[download] 64.2% of 92.85M at 181.67k/s ETA 03:07
[download] 100.0% of 92.85M at 177.26k/s ETA 00:00
[youtube] Setting language
[youtube] ArlyeP3Phew: Downloading video webpage
[youtube] ArlyeP3Phew: Downloading video info webpage
[youtube] ArlyeP3Phew: Extracting video information
[download] Destination: 2011-12-28_part_3.flv
[download] 100.0% of 63.46M at 190.59k/s ETA 00:00
[youtube] Setting language
[youtube] CxrLRyEGUXU: Downloading video webpage
[youtube] CxrLRyEGUXU: Downloading video info webpage
[youtube] CxrLRyEGUXU: Extracting video information
[download] Destination: 2011-12-28_part_4.flv
[download] 100.0% of 60.76M at 200.82k/s ETA 00:00
[youtube] Setting language
[youtube] kJMsqcdHjOg: Downloading video webpage
[youtube] kJMsqcdHjOg: Downloading video info webpage
[youtube] kJMsqcdHjOg: Extracting video information
[download] Destination: 2011-12-28_part_5.flv
[download] 96.1% of 55.09M at 168.38k/s ETA 00:13