ラベル LSL の投稿を表示しています。 すべての投稿を表示
ラベル LSL の投稿を表示しています。 すべての投稿を表示

2009-07-10

LSL3

最近アダルト関連・Snowglobe関連の情報を追っていますが、wikiの更新情報をみていたら、まだ公開にはなっていませんがLSL3についてのページが7/2日付けで更新されていました(その前は6/28?)。

未公開、といってもワークスペースに記述されているという意味で、探し方さえわかっていれば誰でも見れます。ただし、公式発表はされてませんので注意です。

ポイントは、ざっと目を通したところでは…
  • プリム・リンク(セット)の階層化を含むオブジェクト・モデリング、とそのスクリプティング…ここが目玉?
  • C言語並の文法…switch!
  • 型の堅牢性
  • 強力な型定義(?)…pointer?!、ユーザ定義型?!、サブ・スクリプトから起動できるユーザ定義イベント!!、ライブラリとして配布・販売できるスクリプト構成!!
内容からするに、まだ構想を明確化している段階で開発に着手してるのかどうかは不明ですが、先日発表されたHTTP-Inに続いてこれも期待!

LSL3に関するまとめJIRAは MISC-2237 で、ここの関連JIRAリストからおおよそ期待できる機能が見えてくると思います。さらに関連JIRAがあって大量ですが…。

2009-02-15

YouTube動画をSLで - Yahoo Pipes 2

さて、前回のpipeをもうちょっと工夫してみましょう。

動画の品質を指定するには、
http://www.youtube.com/get_video?video_id={動画ID}&t={動画識別コード}&fmt={出力形式}
の、「fmt={出力形式}」の部分を変えるだけで実現できます。指定値は前々回に書いた通り、
  • fmt=18...MP4 H.264/AAC stereo
  • fmt=17...MP4 MPEG-4/AAC mono (モバイル)
  • fmt=22...MP4, H.264/AAC stereo (HD)

です。

ですから、「http://www.youtube.com/get_video?video_id={動画ID}&t={動画識別コード}」の部分までをPipeで作成・出力し、「&fmt={出力形式}」の部分をSL内でユーザに指定させて、LSLで
http://www.youtube.com/get_video?video_id={動画ID}&t={動画識別コード}&fmt={出力形式}
という処理形態にするのが自然かと思います。
特にhttp_responseイベントで取得できるデータ長さは2Kbyteという制限があるので、短いに越したことはありません。
(pipe側も複雑になると動かなくなることがあります)

そこを改良したpipeがこちら。

movie formatのInput Numberモジュールを削除し、最後のLoopモジュール内のString Builderモジュールから"fmt="、"text"の2項目を削除するだけです。

後は受け取ったLSL側のllParcelMediaCommandList()関数に指定するURLに"fmt=xx"を付加するようにします。

これでfmt=18とfmt=17の対応は終わりです。

前々回も書きましたが、どのYouTube動画でもこのfmt=18とfmt=17は有効です。
ただしYouTube動画で「高画質」が用意されていない場合、fmt=18がきちんと「MP4 H.264/AAC stereo」になるかどうかはチェックしてません。でも再生時にvideoとして認識されない、ということはありませんので安心してください。

- - - - - - - - - - - - - - - - - - - - - - - - - - -

ただし、fmt=22(HD)の場合は元動画がHDでないと有効になりません(SL内でMedia URLにセットしてもvideoとして認識されません)。その動画がHDかどうか、YouTube URLを指定する前に事前にどこかでチェックしないといけないのです。

この「HDかどうか」をYouTubeページを参照する前に確認する方法はないのでしょうか。

実はあります。
参考:「Youtube でHD動画に対応しているか確認する裏技見つけた」

前回の「動画識別コード」を取得するために参照した部分、ここにその情報も含まれています。


この「fmt_map」の値の先頭が"22"であるならば、その動画はHD動画です。

ちなみに「高品質」がない動画の場合は

「高品質」がある場合(でHDがない場合)は

のようです。
(判定する必要はないですが)

"pipeで「HDかどうか」をLSLに返して、LSL側で出力形式を指定し再生用URLを組み立てる"
という処理形態にのっとってpipesとLSLを変更します。

そこで
という感じにしてみます。

●pipe

右側のモジュールで「YouTube video URL (url)」とその下の「String Regex」についての説明はいままでと同じですので省きます。

右側3番目の「Item Builder」モジュールで、取得したYouTube IDを基に、itemを作成します。


左側のモジュールの一番上、「Fetch Page」もいままでと同様です。

左2番めの「Filter」モジュールで、取得してきたHTMLソースから"fmt_map=xxxx"と"t=xxx"の部分をitemとして取り出し(permit)ます。
上から3番目の「Filter」ですが、ごくたまに"dtst=xxxx"というitemが取得できることがあります。ほんとにたまーにで、毎回ではないようなので何かYouTube側で機能を盛り込み途中なのかもしれません。とりあえず今は必要ないので、運悪く取得できてしまった時のために"dtst=xxx"のitemは取り除き(block)ます。


次の「Rename」モジュール以降で、itemの体裁を整えます。
整えるために、新たにvideo.titleとvideo.descriptionという属性を、とりあえずitem.contentの値で追加します。
「Sub-element」モジュールで、video.titleとvideo.description属性のみを取り出します。取り出したのでそれぞれ、item.title、item.descriptionという属性になります。


次の「Regex」モジュール。item.titleとitem.descriptionには、"fmt_map=xxx"もしくは"t=xxx"が入っています。
item.titleの値が"fmt_map="で始まっていたら、item.titleには"fmt"を、"t="で始まっていたら"t"をセットします。
また、item.descriptionの値が"fmt_map="で始まっていたらその後ろの値を、"t="の場合もその後ろの相対をitem.descriptionにセットします。


右側下の「Union」モジュールで、先程作成したYouTube IDの入ったitemと、左モジュールで取得してきたfmtとtのitemを結合して出力します。

出力結果(CSV形式)はこうなります。


LSL側は…長いので別ページに用意しました。コピペし、適当なobjectに詰めてお使いください。

[2009-02-17追記]
HTTPリクエストからhttp_response待ちの間、正式に作成するならばタイマーを張って応答タイムアウトを取るのがベストかと思います。どこかでなんらかのエラーが発生した場合、このままだと永遠に(スクリプト・リセットをしない限り)処理が止まります。

ちなみに、http_responseのstatusについては「
Studying HTTP」の「HTTP Status Code」を参考にしています。

2009-02-11

YouTube動画をSLで - Yahoo Pipes

YouTubeをSLで再生するために必要なURL
http://www.youtube.com/get_video?video_id={動画ID}&t={動画識別コード}&fmt={出力形式}
は、どうやってつくるのでしょう。

ここではJvnさんの「【中級】youtube url変換Webサービス公開」で使われているPipeを自分用にコピー(Cloneを作成)してソースを覗きます。

(見やすいようにちょっと配置替えをしてあります)

それでは各モジュールの機能を説明していきましょう。

1.youtube url(url) ※一番上の真ん中

これはモジュール名が書き換わってしまっていますが、User Inputカテゴリの「URL Input」で、ユーザからURLを入力させるためのものです。といっても、キーボードからの入力ではなくて、URLのパラメータ(正しい言い方か、これ?w)としての入力です。
JvnさんのLSLを思い出してください。
strURL = "http://pipes.yahoo.com/pipes/pipe.run?_id=5a068edc3e7197ed30c21a4f90363fe2&_render=csv&format=18&url=" + strURL;
この最後の「url=xxxx」の部分に当たります。
Default欄には何も指定していないので、このPipeを実行する際には必ず指定すべきものです。

2.movie format (number) ※右はじ上

これも同様に名前が書き換わっていますが、User Inputカテゴリの「Number Input」で、ユーザから数値を入力させるためのものです。
JvnさんのLSLでいくと、「format=xx」の部分になります。

3.String Regex ※中央やや上

これはStringカテゴリにあるモジュールです。文字列を正規化表現を使って生成するものです。
(正規化表現についてはつっこまないでください! 超苦手です!)
何をやっているかというと、1で指定されたYouTubeURLの文字列からv=以降の動画IDを抜き出しています。
http://www.youtube.com/watch?v=ohvjtDevshU
こういうYouTube URLだと「ohvjtDevshU」の部分です。

4.Fetch Page ※左一番上

これはSouceカテゴリにあるモジュールです。指定されたURLのHTMLページ(ソース)を読み込みます。さらに「Cut content from...to」欄で、HTMLソース上の指定した部分だけをitemとして取り出します。
つまりHTMLソース上の「watch_fullscreen?」で始まり、次の「;」までです。

実はここにYouTubeをSLで再生させるためのt=パラメータ「動画識別コード(勝手に命名)」が書かれているのです。

[2009-02-12 追記]
実はもう一箇所あって、同じHTMLソース上の"var swfArgs = {"で始まり、次の"};"で終わる部分にもあります。(別の動画の識別コードなので上記とコードは異なっています)

ただし、こちらの場合だと、識別コードを取得したあと"t="と組み合わせるという手間が増えるので、上記のほうがいいかと思います。

5.Loop ※左上から2番目

Operatorカテゴリにあるモジュールです。item数分だけ指定した処理を行います。
この場合は1個しかitemがないので1回処理されるだけです。
処理の内容は、Loopモジュール中にある「String Regex」で、文字列を正規化表現を使って書き換えるものです。

item.content(4で切り取ってきた文字列が入っている)の中身から、「t=」で始まり次の「&」で終わる部分までを取り出し、item.loop:strregexに格納します。

6.Loop ※左一番下

5と同様、Loopモジュールです。5と同様、ここでも1個しかitemがないので1回処理されるだけです。
処理の内容は、「String Builder」モジュールを使って、文字列を生成し、新規のitemとして出力します。

生成用の文字列は「String」の下にある各欄を上から順につなげたものになります。
  1. 欠けて見えませんが、"http://www.youtube.com/get_video?video_id="
  2. これも、結合線が隠れてしまっていますが、3のモジュールで作成した動画ID
  3. "&"
  4. 5のモジュールで作成したitem.loop:strregexの中身。要するに"t=xxxxxxxxxxxxxxxxx"の部分
  5. "&fmt="
  6. 2のモジュールで指定された数字。出力形式

と、これで、http://www.youtube.com/get_video?video_id={動画ID}&t={動画識別コード}&fmt={出力形式}
がRSS形式で生成され出力されます。

さて次はこのpipeの出力結果をLSLで利用します。
llHTTPRequest()関数でこのpipeを実行します。
pipeの実行は
http://pipes.yahoo.com/pipes/pipe.run?_id={pipeのID}
の後に、必要なパラメータを指定していきます。このpipeの場合は
&url={YouTube URL}&format={出力形式}
です。指定の順番は気にしなくて大丈夫です。

結果はhttp_responseイベントのbodyに返ってきます。

ここで、pipeを普通に実行するとRSS形式のデータが返ってくることに注意してください。
単純に
http://pipes.yahoo.com/pipes/pipe.run?_id={pipeのID}&url={YouTubeURL}&format={出力形式}
としてやると、
bodyはrssのタグやらなにやらが大量に含まれます。

しかもきちんとRSSの仕様に準拠していないと、値は返ってきません。

このpipeでは単純にURLの1行文字列が必要なので、CSV形式で結果を返すようにpipeを実行します。
CSV形式の出力には実行URLに
&_render=csv
を追加します。

※ただしCSV出力にはSnumaさんのブログにあるとおり、日本語文字列に問題が発生します。CSVデータには文字コード指定(mime)がないからだと思われます。

あとは、返ってきたbodyの内容からURL部分だけを抜き出して、HTML特殊文字表記(こういう名称だっけ?)になっている"&"を"&"に置き換え、llParcelMediaCommandList()関数でURL等をセットするだけです。

2009-02-10

YouTube動画をSLで - まずは単体再生

なんかあっちでもこっちでも出てて旬な話題っぽいのでYahoo Pipesで作ってみることにします。

作ることに興味がなくて、SLで使うことにだけ興味のある人は
Jvnさんの「【中級】youtube url変換Webサービス公開」をどうぞ!
LSLにコピペするときにちょっと注意です。

一番最初のスクリプトのstate set、イベントhttp_responseの最後のところ、
integer idx = llSubStringIndex(strURL, "&");
while( idx > -1)
{
strURL = llDeleteSubString(strURL, idx+1, idx+4);
idx = llSubStringIndex(strURL, "&");
}
ここですが、このままコピペすると永久ループしてしまい、処理が終わりません。たぶんホームページ上での表示の問題でこんな表示になってしまっているのだと思います。
以下のように直さないといけません。
integer idx = llSubStringIndex(strURL, "&");
while( idx > -1)
{
strURL = llDeleteSubString(strURL, idx+1, idx+4);
idx = llSubStringIndex(strURL, "&");
}

あるいは while でまわすのではなく、Snumaさんの「[LSL] 複数の文字列を一気に置き換えたい」を参考に、
list listTemp = llParseStringKeepNulls(strURL, ["&"], []);
strURL = llDumpList2String(listTemp, "&");
に書き換えてもOKです。

- - - - - - - - - - - - - - - - - - - -
では、ここからは作りたい人のための情報です。

要するに、YouTube動画をSLで再生するには下記URL
http://www.youtube.com/get_video?video_id={動画ID}&t={動画識別コード}&fmt={出力形式}
を作成して、このリンクを土地のMedia URLにセットするだけです。

t={}は最近付け加わったので、今後も変わらないかどうかは保証の限りではありません。
YouTubeがこのやり方を公式発表しているわけでもないようですし。

●動画ID
これはYouTubeの各動画ページのURI
http://www.youtube.com/watch?v=71MM68d8Viw
のv=以降の部分です。

●出力形式
フラッシュ形式だとか、モバイル用品質だとか、高品質だとかHDだとかです。
これは「YoutubeのHD動画正式対応で、改めて動画形式をまとめてみる」で表形式にまとめられています。
Jvnさんのものでは、標準が17(モバイル)、高品質が18、もっと上(HD?)はhttpではなく、rtsp(リアルタイム・ストリーミング)です。
ですが17のモバイルだとかなり品質が落ちてしまうので、SL内では
  • 標準...18(MP4 H.264/AAC stereo)
  • 低画質...17(MP4 MPEG-4/AAC mono)
  • HD...22(MP4, H.264/AAC stereo)
というのがいいかと思います。

fmt=18とfmt=22は試した感じでは、確かにfmt=22の方がきれいです。
ただし! 「SL内で再生する」という目的からするとビットレート2Mbps超は非常に辛く、ほぼ趣味の世界といったところではないでしょうかw

動画によっては「HDないよ!」とか「(YouTube上では)高品質で見るがないよ!」と思われるかもしれませんが、どの動画でもfmt=18とfmt=17は有効です。fmt=22だけはHDでアップロードされていないと使うことができません。

参考までにSL内で各フォーマットを試してみた結果を。
動画はLINZOOさんの作成された「GION LIVE FINAL」です。
fmt=17


fmt=18


fmt=22


●動画識別コード
名称は勝手に付けましたw これも動画個別にあります。詳細は後ほど。