Pythonで作る簡易アップローダー(後日談)

IMG_0845

IMG_0845

前回の日記の続きです。

プログラムを打ってて常々思うのが、ユーザーは作った側が全く想像しなかった使い方をするんですね。でも、作る側はあらゆるパターンに対応出来るようになんて作れないので、いつもこういうところで悩まされる。

今回の例も、自分が作ったサービスが、何のプログラムに関する知識をも持ち合わせていない人が使うということで、すごく勉強になりました。

まず最初に言われたのが、「画面が固まる!アップロードできない!」というものでした。

私はちゃんと、FireFoxとAndroidブラウザからアップロード出来ることくらいは確認していたので、あれ?おかしいな。エラーが出るならまだしも、画面が固まるってのはおかしいな・・・。単純にアップロードに時間かかってるだけじゃないか?と予測しました。

たとえば、仕様上の話だと、FOMAハイスピードならば上り最大5.7Mbpsとなっているようです。しかし、こんなもん、絶対仕様通りの速度が出るとはもちろん思いませんので、まあ、1Mbpsに届かないくらいが関の山だろうな。と予測しました。すると、

1000 {\rm kbps} \div 8 {\rm bit} = 125 {\rm kb/s}

くらいなんだろうな。だから、何MBの動画をアップロードしてるのか分からないけど、せいぜいでかくても2~30MBでしょう。もし30MBならば4分くらいかかる計算だね。4分画面が遷移しないと固まると思うかもしれんね・・・なんて思ってました。

そしたら、結果的にその人は30分待ったらしいとのこと。どんだけ大容量の動画なんだと見てみると、たった11MBしかないのです。逆算すると、なんと133kbps!当初予想の13%の速度しか出ていません。いやー、たまげたモンだ。

私が試しにスマホからアップロードした動画ファイルも数MBはあったのだが、wifi環境からアップロードしたため、そんな速度しかでないとはとても思わなかった。

だから、私はアップロードページにこう書き加えた。

「なるべくwifiから接続してください。でなければPCから接続して下さい。携帯の電波(3G)から送信するとすごく時間がかかります。時間がかかっても放置しておいて下さい」

と。でも、「wifi接続」「3G」などという単語を果たして何人のユーザーが理解しているだろうか。あるいは知っていたとしても、スマホからwifiに接続できるユーザーが何人いるだろうか。私はしょうっちゅうルーターの設定の仕方などを友達から聞かれるのだが、まあ、そういう背景を考えると、少なくともPCやデジタル機器に関心がある人でないとやらないだろうね。

次は、「本当にアップロードされているのかどうか不安になる。何十分も放置しておけない。プログレスバーを表示して欲しい」と言われた。

まあ、普通はそう思うだろう。時間のかかる作業にはプログレスバーや進捗率を表示して欲しい・・・。至極当然の要求である。

しかし、簡単に端折って言うと、いまのインターネットの仕様では、こういうことは基本的に出来ない。

基本的に、今のインターネットのシステムというのは、黎明期にテキストデータと簡単な画像やバイナリデータなどのやりとりが出来ればそれで良い、という、ひどく簡単に作られたシステムを10年単位のスパンで引き継いでるので、色々と困ることが顕在化してきている。いわば、欠陥と言っても良いと思う。まともなエンジニアなら、誰しもがHTTPの仕様に憤慨しているはずで、じゃあ、なぜそれを作り替えないかというと、つまり、昔の物を捨ててそれを作り替えると言うことは、これまで作られた全てのブラウザ、機器、また、HTTPを作る全てのソフトが無用の長物になるということから、なかなか出来ないまま2010年代に突入してしまった。最近になってようやく、googleあたりがいま頑張ってどうにかしようとしている。

前述のプログレスバーの要求で言えば、「Webページへの要求と応答は必ず1セットで、それぞれ一つずつ」という仕様がこの実現を難しくしている。つまり、「この動画データを、送りますよおおおおおおおおおおおおおお」って、何分もかけて送ってる間、受け取る側は何も返答できないのだ。全部送ってから初めて「ハイ!受け取りました!」と応答することが出来る。

嘘付けー、アップロード最中にプログレスバー表示されてるの見たことあるぞ、と、言う人も居るだろう。たぶん、それはブラウザが「100個あるうちの40番目まで読み込んだから40%だな」って適当に出してる(※)か、Ajaxとか呼ばれる方法で裏で頑張ってるかのどっちかだ。

(※)つまり、読み込む画像が100個あれば、100回要求を送っていると言うこと。これだけでいかに非効率か想像が付くだろう。Androidブラウザとかでは、プログレスバーの表示はなめらかに見えるが、じっくり観察するとカク付いていたり、突然進捗バーが後ろに戻ったりするのが分かる。これは、進捗率の表示を読み込むべきコンテンツ(画像とか動画とかFlashとか)の数を使っているので、粒度が荒いためだ。

Ajaxというのは、一時期、「Web2.0」とかもてはやされてた時代の技術(しかも、過去の技術の再発見)である。なんかすごいぜ!みたいな感じをふんだんに各社押し出していたが、まあ、昔からある技術をなんとか応用してやりくりして、前述の欠陥と言ってもいいレベルの遺物を表面的にごまかしてお茶を濁しているだけである。だから、ちゃんとしたエンジニアであれば、Web2.0なんて単なるビジネス上のバズワードであって、何ら意味がないと見抜いていただろう。そしてその通り、今、Web2.0なんてアホみたいなことを言う輩は居ない。

話が飛んだ。

で、プログレスバーを表示させるのはすごく難しい。具体的に言えば、サーバーにWebフレームワーク、たとえばrailsとか、Djangoとか、TomcatでServletとか、そういうものの環境一式を整え、ブラウザがアップロードを開始する前に、すべてのユーザーの間で重複しないセッションIDを生成して、それをクッキーで渡して、それがセッションの間中生きるようにして、で、アップロード中にJQueryとかつかって、セッションIDをキーにして進捗率表示のための動的ページにアクセスして定期的に進捗率を取ってくるようにして、その間、データを受け取ってるサーバー側プログラムはセッションIDごとに進捗率表示のための動的ページに情報を送って・・・という、クソクソクソクソクソクソクソクソクソクソクソ面倒なことをしなければならない。まあ、俺はそういうページを作ったことがないので正確には分からんが、裏でこういうことをやっているのは間違い無い。

しかし、そんだけクソ面倒なことをやって出来ることと言うのは、「アップロードに進捗率が表示される」という、出来て当たり前と見なされる、ひたすら地味な機能である。今時、プログレスバーが表示されたくらいですげー!!と喜んでくれる人は皆無だろう。

だから、多くのWebストレージサービスは、専用のソフトやアプリを提供することになる。ブラウザ上でこれを実現するよりも、プログラムを書いた方がずっと楽だからだ。

ユーザーは、その苦労が分からないため、「なんだよ、プログレスバーも表示されねーのかよ。つかえねーな。」と、いう評価を下すわけであるが。まあ、ここれへんは難しいよなあ・・・。

結局、今回の場合はさらに細かく「何十分待たされてもじっと待ち続けて下さい」と注意書きを書くに留めたが、これが、ビジネス上のサービスならとんでもねーことだよなあ。と、思う。

まだ問題があるよ。そういう状態で、動画がいくつか集まってきたところ、なんと、500MB超の動画を送りつけてきた猛者がいた。すげーな、おい。と思った。このレンタルサーバーの容量は1GBしかなく、ブログ部分で100MBくらいは使ってるし、他にも100MB超の動画がいくつかあったので、パンク寸前である。

これは結婚式のサプライズムービーで、おめでとうの言葉をビデオに撮るというものだ。だから、アップローダーを作る側としては、せいぜい長くても1分くらい、動画ファイルのサイズで言えば、H.264で、せいぜい数十MBのオーダーだと思うだろう。甘い。その想定は甘すぎた。

全てのユーザーが動画ファイルのコーデックまで熟知していて、送信する前に適したサイズに圧縮したりトリミングしたりしてくれる・・・なんて想定は、それ、制作者側にとって甘すぎる想定なんだな。

まあ、これはダウンロードしてすぐ削除することで対応しました。

と、こんな感じで、実際にサービス展開すると予期しなかった問題がいっぱい起こるから、だから、プログラムってのは面白い。とも言えるよね。