COMMON LISP JP > Archives > 2010/12/27

2010/12/27 11:49:52 UTCPocket
#
URLからmp3をダウンロードする方法ってありますでしょうか。Drakmaを利用したいとおもっているのですが。。。
#
(defun download-file (url file)
  (with-open-file (fp file :direction :output :if-exists :overwrite :if-does-not-exist :create)
    (format fp "~A~%"
            (http-request url))))
#
これでhtmlとかはダウンロード可能になったのですがmp3でやるとなにやらメモリ不足とかのエラーでデバッガに落ちたりするので。。
2010/12/27 11:56:17 UTCNANRI
#
format が pretty print しようとしているのかな?
2010/12/27 11:57:02 UTCPocket
#
print系の関数の変えてみれば良いんですかね?
2010/12/27 11:57:04 UTCNANRI
#
mp3はバイナリデータなので write-sequence とかを使えばいいのだと思います。
2010/12/27 11:57:17 UTCPocket
#
なるほど。ちょっとためしてみます。
2010/12/27 11:58:48 UTCNANRI
#
あと with-open-file で開くストリームもバイナリストリームを開く必要があるような気がします。
2010/12/27 11:59:07 UTCPocket
#
なるほど。
#
上手くいったとおもいます。
#
http-requestのかえり値のsequenceが延々とプリントされてしまっているw
2010/12/27 12:04:13 UTCNANRI
#
よかったです。使ったことがなかったので、間違ってたら...と思ってました。
2010/12/27 12:04:31 UTCPocket
#
いえいえ、ありがとうございます。
2010/12/27 12:34:14 UTCsnmsts
#
mp3くらいなら平気かと思うけどでかいファイルをダウンロードしようとすると一旦メモリに展開しようとする方針はあまり良くないよ。サイズ的にタカがくくれないようなものに対応する場合http-requestの :want-stream tにしてファイルに書き出しながらループを回すの良いかな。
2010/12/27 12:35:05 UTCPocket
#
なるほど
#
その場合はどのように書きだせば良いのでしょうか。サンプルコード情報などありましたらよろしくおねがいします。binary-fileのあつかいはあまりやったことがないので...
2010/12/27 12:42:32 UTCsnmsts
#
えーと…なんかダミーでいいのでuriください
2010/12/27 12:43:04 UTCPocket
#
わかりました。
#
ちょっとさがしてみます。
2010/12/27 12:43:27 UTCsnmsts
#
ダミーじゃまずいね…
#
まyahooでもgoogleでもでちょっとかいてみる
2010/12/27 12:44:51 UTCPocket
#
http://www.yen-soft.com/ssse/sound/se/a/z/meka_ta_sui04.mp3
#
適当に素材サイトからコピーしてきたのですが...
2010/12/27 12:45:40 UTCsnmsts
#
ありがとうございます
2010/12/27 12:56:03 UTCsnmsts
#
(defun download-file (filename uri)
  (with-open-file (out filename
		       :direction :output
		       :if-exists :supersede
                       :element-type '(unsigned-byte 8))
    (let ((v (make-array 4096 :element-type '(unsigned-byte 8)))
          (input  (drakma:http-request uri :want-stream t)))
      (loop :for size := (read-sequence v input)
         :until (zerop size)
         :do (write-sequence v out :end size)))))
#
10分…酷い。
#
20分か
#
いちおうaclでは動いてる気がする。
2010/12/27 12:57:14 UTCPocket
#
なるほど
#
make-arrayの4096というのはどういう値でしょうか?
2010/12/27 12:57:54 UTCsnmsts
#
え?
#
char buf[4096];みたいな?
2010/12/27 12:58:27 UTCPocket
#
あ、なるほど、もうしわけありません。
2010/12/27 12:58:59 UTCsnmsts
#
いえ、どうこたえようかわかんね…とおもっただけなので恐縮されると困ります。
2010/12/27 12:59:35 UTCPocket
#
いえいえ、なにかそのサイズにする必要があるのかとおもったので、(magic number的な)
2010/12/27 13:00:11 UTCsnmsts
#
4000だったら良かったのか。キリが良いし打ちなれているんすよ個人的に。
#
キリが良いかどうか…自信がなくなってきた…
2010/12/27 13:01:48 UTCPocket
#
普通のファイルについてはelement-typeは指定しなくて良いんですかね?
2010/12/27 13:02:05 UTCNANRI
#
#x1000 == 4096 なのでキリがいいんじゃ
2010/12/27 13:02:54 UTCsnmsts
#
普通のファイルというのは?>Pocketさん
2010/12/27 13:03:05 UTCPocket
#
htmlとかですtxtとか
2010/12/27 13:03:08 UTCsnmsts
#
ありがとうございます>NANRIさん
2010/12/27 13:03:14 UTCPocket
#
binary以外というか..
2010/12/27 13:03:59 UTCsnmsts
#
うーん…ダウンロードに関していえばバイナリを選択しない理由は知らないですねー。
#
ダウンロードtoファイルの場合?
#
ファイルのエンコードが自動判定された場合は処理系のネイティブな文字コードに変換されて保存されますが
2010/12/27 13:05:15 UTCPocket
#
なるほど、僕の無知のようですね。mp3と普通のtxtファイルのurlの時って別に区別しなくて良いんですね!
2010/12/27 13:05:27 UTCsnmsts
#
問題無いと言いきれる状況なら良いんじゃないでしょうか。
2010/12/27 13:05:29 UTCNANRI
#
ダウンロードはテキストファイルもバイナリとして扱ったほうがよいかと。
#
日本語とかありますし
2010/12/27 13:05:46 UTCPocket
#
なるほど
2010/12/27 13:05:57 UTCNANRI
#
途中で処理するなら別ですけど
2010/12/27 13:06:32 UTCsnmsts
#
abclは少なくとも昔のバージョンではosがunixかwindowsかで保存されるファイルの文字コードが変わりますよ
#
今は違うかもですけど。
#
あとdrakmaはflexi-streamsが文字コードを処理できない場合はバイナリで結果決ますよ
#
きます。
2010/12/27 13:08:11 UTCPocket
#
なるほど
2010/12/27 13:17:17 UTCPocket
#
ありがとうございます。
#
あと初歩的な質問になるかとおもうのですが、ダウンローダーとかでプログレスバーが出たりするのですが、あれってダウンロード先のファイルサイズを取得しているんだとおもうのですが、
#
ですが<-を連発してしまった...
#
drakmaだとどういう風に実装できますかね?
2010/12/27 13:23:30 UTCNANRI
#
http-headerのContent-Lengthがダウンロードするファイルのサイズにあたります。
#
ただ、必ず返してもらえるものじゃなかったような(うろ覚え)>Content-Length
2010/12/27 13:25:11 UTCPocket
#
なるほど、
2010/12/27 13:31:15 UTCPocket
#
wgetのソースを読んでいるのですが...良くわかりませんね..
2010/12/27 13:36:06 UTCsnmsts
#
最初に帰ってくる多値にヘッダがあるのでそれっぽい値があればそれでやれる場合はやれます。やれない場合はwgetでもやれません。
2010/12/27 13:36:28 UTCPocket
#
なるほど
#
帰ってくるというのはhttp-requestからですか?
2010/12/27 13:37:25 UTCsnmsts
#
はいな
2010/12/27 13:38:27 UTCPocket
#
それだとstreamから読みこむときはどのように取得すれば良いのでしょうか...
#
2番目とかですか?
#
すいません、自分でたしかめます。
#
あ、なるほどmultiple~で取得すれば良いんですね
2010/12/27 13:42:03 UTCsnmsts
#
あーはい。drakmaのマニュアルはちゃんとしているので、httpの用途の学習を含めてマニュアル読むと良いですよ。
2010/12/27 13:43:50 UTCPocket
#
なるほどheader-valueっていうので取得できそうですね。
2010/12/27 14:43:40 UTCPocket
#
無事プログレスバー出力できました!
#
テストのためにさっきのURLを酷使してしまった..