「動画情報ウィンドウ」の編集履歴(バックアップ)一覧はこちら

動画情報ウィンドウ - (2008/01/04 (金) 19:18:36) の1つ前との変更点

追加された行は緑色になります。

削除された行は赤色になります。

#contents() *概要 ニコニコ動画のサイト上で表示される、動画の「ヘッダー」の部分、およびニコニコ市場(インターネット接続時)を表示します。 *機能 以下の内容を表示します。 -投稿年月日時 -動画タイトル -投稿者コメント -登録タグ -ニコニコ市場(インターネット接続時のみ) 以上の内容はvideoinfoフォルダ内にHTMLテンプレートが配置されているので、自由に編集することができます。 *機能拡張 **設定ファイル 動画情報ウィンドウのフォーマット(表示形式)はHTMLとCSSで設定されています。 設定ファイルである以下のドキュメントを書き換えることで、外観を変えたり、機能を追加したりできます。 -template.html (インターネット接続時の動画情報の表示用テンプレート) -template_off.html (保存した動画情報の表示用テンプレート) -style.css (保存した動画情報の表示用CSS) -reading.html (動画情報読み込みまでの「読み込み中...」の表示) -error.html (動画情報読み込み失敗時の表示) ※いずれもvideoinfoフォルダ内にあります。 ※動画情報を表示したときにtemp.htmlが生成されます。 ※インターネット接続時のCSSは、[[http://res.nicovideo.jp/css/_.css?071011>動画情報ウィンドウ]]から読み込んでいます。&br()↑CSSのURL直リンクはまずそうなので、クリックしてもこのページに戻ってくるようになっています。参照したい場合はブラウザのアドレス欄にコピペしてください。 ※これらのファイルの初期状態のソースは[[動画情報ウィンドウ フォーマット]]に記載しています。 **パラメータ HTML内には以下のようなパラメータが使用できます。 |%__MOVIE_NAME__%|動画ID(smXXXXXXXのこと。X:数字、IDにより1~7桁)| |%__MOVIE_ID__%|動画IDの数字部分(上記のXXXXXXXに相当)| |%__POST__%|投稿年月日・時分秒| |%__TITLE__%|動画タイトル| |%__COMMENT__%|投稿者コメント| |%__TAGS__%|登録タグ| |%__SOFT_DIR__%|NicoPlayerのインストールフォルダ| |%__DOWNLOAD_DIR__%|ダウンロードフォルダ| |%__MEDIA_PATH__%|動画ファイルのパス| |%__COMMENT_PATH__%|コメントファイルのパス| |%__PLAYLIST_PATH__%|ロード中のプレイリストファイルのパス| |%__SOFT_DIR2__%|NicoPlayerのインストールフォルダ(※1)| |%__DOWNLOAD_DIR2__%|ダウンロードフォルダ(※1)| |%__MEDIA_PATH2__%|動画ファイルのパス(※1)| |%__COMMENT_PATH2__%|コメントファイルのパス(※1)| |%__PLAYLIST_PATH2__%|ロード中のプレイリストファイルのパス(※1)| |%__VIEW_COUNT__%|再生数(※2)| |%__COMMENT_COUNT__%|コメント数(※2)| ※1 パスの区切り文字が\\となる(ソースコード内で使用) ※2 コメントファイル(xml)から値を取得するので、最新の数値ではありません。 **パラメータ使用例 :http ://www.nicovideo.jp/watch/%__MOVIE_NAME__%|動画ページのアドレス :http ://tn-skr.smilevideo.jp/smile?i=%__MOVIE_ID__%|動画のサムネイル(検索・マイページ等の縮小画像) **機能拡張サンプル いくつかのサンプルでは別途JavaScriptのライブラリが必要になります。 ダウンロード:[[prototype.js>http://www.prototypejs.org/]] [[excanvas.js>http://sourceforge.net/project/showfiles.php?group_id=163391]] ***はじめに NicoPlayerは動画情報の表示にIEコンポーネント(InternetExplorerの一部)の機能を使っています。設定は[設定ファイル]で示されている、HTML及びその周辺フォーマット(JavaScript・CSS)で記述されたファイル群で行われています。特にtemplate.htmlを編集することで、通常再生時に表示される動画情報を好みに合わせることが出来ます。またシェルを介することでNicoPlayerを操作したり、他のツールと連携したりといったことも可能です。 大きな可能性を秘めた動画情報ウィンドウですが、あまりに強力なためセキュリティ上の観点からいくつかの機能が標準で禁止されています。以下の機能拡張サンプルではこれらの機能を用いている場合が多いため、危険性を十分に認識した上で次の手順で機能使用の許可設定を行う必要があります。 >セキュリティの設定 インターネットエクスプローラ(IE)のメニュー[ツール]から[インターネットオプション]を選択する 上部のタグから[セキュリティ]を選択し、[イントラネット]・[レベルのカスタマイズ]へ進む [ActiveXコントロールとプラグイン]の  [スクリプトを実行しても安全だとマークされていないActiveXコントロールの初期化とスクリプトの実行] を有効にし、  [ActiveXコントロールに対して自動的にダイアログを表示] を無効にしてください。 これでセキュリティ上は全てのサンプルが機能するようになりました。ただし一部のサンプルではフレームワークという、開発を容易にするソフトウェアを使用しています。次の手順で導入してください。 >prototype.jsの導入 [[prototype>http://www.prototypejs.org/]]のページを開き、Download(右上)をクリックする [Download the latest stable version]をクリックし、ファイルを保存する ダウンロードしたprototype.js(設定によっては.jsが表示されないことがあります)をvideoinfoフォルダへ移動させる これでほとんどのサンプルは機能するはずです。もしうまくいかなかったら、このページの下のほうにあるコメントに書き込んでみましょう。誰かが手助けしてくれるかもしれません。自力で解決できた場合は、ぜひ躓いた点とその解決策を書き込んでください! ***動画から3秒目の画像を取り出し表示する グラフの背景(サムネイルを拡大表示)があまりに無理やりなので、自前で用意して見ました。 //今回から[[prototype.js>http://www.prototypejs.org/]](事実上標準のJavaScriptライブラリ…らしい)を導入しました。また先頭のコメントを追加したことにより、イントラネットのセキュリティ設定が適用されるようになります。すでに共有フォルダなどで環境構築されている方はそのままでかまいません。そうでない方は若干リスクが上がるものの、比較的簡易に構築できるこの設定をお勧めします(インターネットオプション>セキュリティ>イントラネット>ActiveXコントロールとプラグイン の項目を全て有効にする)。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var pathOf3GPConverter = "携帯動画変換君のパス"; function showThumbnail() { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( pathOf3GPConverter + "\\cores\\ffmpeg.exe -i \"%__MEDIA_PATH2__%\" -f image2 -pix_fmt png" + " -vframes 1 -ss 3 -s 260x200 -an -deinterlace \"%__MEDIA_PATH2__%.png\"", 0, true ); wshShell = null; $( "target1" ).innerHTML = "<img src=\"%__MEDIA_PATH2__%.png\">"; } </script> </head> <body onload="showThumbnail()"> <span id="target1" /> </body> </html> ***いろいろな値をクリップボードにコピーするボタンを設置する <td>コピー</td>の次の行から、実際に何をコピーするかの定義が始まります。ボタンを追加したい場合は行ごとコピー&ペーストで増やして、シングルクォーテーション(')で挟まれている値をお好みの内容に変更してください。このページの上のほうにある[パラメータ]の項を参考にするとよいです。 <html> <head> <script type="text/javascript"> function copyTextToClipboard( value ) { clipboardData.setData( "Text", value ); } </script> </head> <body> <table border="1"> <tr> <td>コピー</td> <td><button onclick="copyTextToClipboard( 'http://www.nicovideo.jp/watch/%__MOVIE_NAME__%' )">アドレス</button></td> <td><button onclick="copyTextToClipboard( '%__MEDIA_PATH2__%' )">ファイル</button></td> <td><button onclick="copyTextToClipboard( '%__MOVIE_NAME__%' )">ID</button></td> </tr> </table> </body> </html> ***携帯動画変換君に投げ込むボタンを設置する・MP3ファイルを抽出するボタンを設置する ( -ver0.41 ) "携帯動画変換君のパス"という所を、各自の環境に合うよう変更してください(パスの区切り文字は\ではなく\\、もしくは/を使ってください)。前提として、動画ファイルをドラッグ&ドロップするだけで変換できるようになっていなければなりません。 MP3ファイル抽出を追加しました。"FFMPEGのパス(\\ffmpeg.exeまで含む)"を環境に合わせて変更してください。FFMPEGは[[こちら>http://ffdshow.faireal.net/mirror/ffmpeg/]]からどうぞ。追記:保存先フォルダを指定するダイアログを表示するようにしました。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript"> var pathOf3GPConverter = "携帯動画変換君のパス"; var pathOfFfmpeg = "FFMPEGのパス(\\ffmpeg.exeまで含む)"; function convertWith3GPConverter() { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"" + pathOf3GPConverter + "\\3GP_Converter.exe\" \"%__MEDIA_PATH2__%\"" ); wshShell = null; } function extractMp3( path ) { var shell = new ActiveXObject( "WScript.Shell" ); shell.Run( "\"" + pathOfFfmpeg + "\" -acodec copy -y -i \"" + path + "\" \"" + path + ".mp3\"", 0, true ); shell = null; shell = new ActiveXObject( "Shell.Application" ); var folder = shell.BrowseForFolder( 0, "保存先のフォルダを選択してください", 1, "ssfDESKTOP" ); if( folder != null ) { folder.CopyHere( path + ".mp3" ); } } </script> </head> <body> <table border="1"> <tr> <td>変換</td> <td><button onclick="convertWith3GPConverter()">3GP</button></td> <td><button onclick="extractMp3( '%__MEDIA_PATH2__%' )">MP3</button></td> </tr> </table> </body> </html> ***コメントの推移をグラフ化して表示する 縦軸がコメント数、横軸が投稿日時です。canvasタグの描画に excanvas.jsを使用しているので[[こちら>http://sourceforge.net/project/showfiles.php?group_id=163391]]からダウンロードして 同じパスにおいてください。 赤線がコメントを表し、青線は100コメントごとの区切りです。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="excanvas.js"></script> <script type="text/javascript"> var canvasWidth = 260; var canvasHeight = 200; function drawGraph() { // XMLパーサオブジェクトを生成 xmldomObject = new ActiveXObject( "Microsoft.XMLDOM" ); xmldomObject.async = false; xmldomObject.load( "%__COMMENT_PATH2__%" ); // コメント数・投稿日時の尺をキャンバスサイズに合わせる var nodes = xmldomObject.getElementsByTagName( "chat" ); var firstChatDate = nodes[0].getAttribute( "date" ); var lastChatDate = nodes[nodes.length - 1].getAttribute( "date" ); var hscale = ( lastChatDate - firstChatDate ) / canvasWidth; var vscale = nodes.length / canvasHeight; var context = document.getElementById( "canvas" ).getContext( "2d" ); // 背景画像を描画 var imgObj = new Image( canvasWidth, canvasHeight ); imgObj.src = "http://tn-skr.smilevideo.jp/smile?i=%__MOVIE_ID__%"; context.drawImage( imgObj, 0, 0 ); var j = 0; var table = new Array( 15 ); // コメントの遷移を表示 context.strokeStyle = "rgba( 255, 0, 0, 1 )"; context.moveTo( 0, canvasHeight ); for( var i = 0; i < nodes.length; i++ ) { context.lineTo( ( nodes[i].getAttribute( "date" ) - firstChatDate ) / hscale, canvasHeight - ( i / vscale ) ); if( i % 100 == 99 ) { table[j++] = canvasHeight - ( i / vscale ); } } context.stroke(); // コメント数の水準線を表示 context.strokeStyle = "rgba( 0, 0, 255, 1 )"; for( var i = 0; i < j; i++ ) { context.moveTo( 0, table[i] ); context.lineTo( canvasWidth, table[i] ); } context.stroke(); } </script> </head> <body onload="drawGraph()"> <canvas id="canvas" width="260" height="200" /> </body> </html> ***コメントを再生ファイルの時間軸についてグラフ化 横軸が再生時間、縦軸がコメント数(秒単位)です。グラフをクリックすると 該当する位置にシーク(再生位置が移動)します。弾幕のありそうなところに 当たりをつけて直前に飛ぶ、といった使い方を想定しています。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="excanvas.js"></script> <script type="text/javascript"> var canvasWidth = 260; var canvasHeight = 200; function drawGraph() { xmldomObject = new ActiveXObject( "Microsoft.XMLDOM" ); xmldomObject.async = false; xmldomObject.load( "%__COMMENT_PATH2__%" ); // コメントの発言時間を集計(秒単位) var vposHash = {}, maxCount = 0, lastVpos = 0; var nodes = xmldomObject.getElementsByTagName( "chat" ); for( var i = 0; i < nodes.length; i++ ) { var nVpos = Math.round( nodes[i].getAttribute( "vpos" ) / 100 ); if( vposHash[ nVpos ] == undefined ) { vposHash[ nVpos ] = 1; } else { vposHash[ nVpos ]++; } lastVpos = Math.max( lastVpos, nVpos ); maxCount = Math.max( maxCount, vposHash[ nVpos ] ); } // スケール決定 var hscale = lastVpos / canvasWidth; var vscale = maxCount / canvasHeight; var context = document.getElementById( "canvas" ).getContext( "2d" ); // 背景画像を描画 var imageObject = new Image( canvasWidth, canvasHeight ); imageObject.src = "http://tn-skr.smilevideo.jp/smile?i=%__MOVIE_ID__%"; context.drawImage( imageObject, 0, 0 ); context.strokeStyle = "rgba( 255, 0, 0, 1 )"; context.moveTo( 0, canvasHeight ); // グラフを描画 for( var i = 0; i < lastVpos; i++ ) { var count = vposHash[i]; if( count != undefined ) { context.lineTo( i / hscale, canvasHeight - ( count / vscale ) ); } } context.stroke(); } function seek() { var pos_percent = Math.round( ( event.offsetX / canvasWidth ) * 100 ); var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" player -seek pos_percent=" + pos_percent ); } </script> </head> <body onload="drawGraph()"> <canvas id="canvas" width="260" height="200" onclick="seek()" /> <span /> </body> </html> ***プレイリストのサムネイルを列挙し、クリックしたら再生する プレイリストにサムネイルが表示されたらいいな、と思っていたので力ずくでやってみました。 NicoPlayerの機能は全然使っていません。動画情報ですらないです。巨大なプレイリストで 使うと、問題がありそうです。ActiveXを使っているので携帯動画変換君に投げ込むボタンと 同じ条件でないと機能しません。 <html> <head> <meta http-equiv="content-type" content="text/html;charset=shift_jis"> <script language="javascript"> <!-- function listupThumbnails() { var strtt = "", fso = new ActiveXObject( 'Scripting.FileSystemObject' ); var file = fso.OpenTextFile("NicoPlayerのインストールパス\\default.m3u"); splited = file.ReadAll().match( /sm[0-9]+/ig ); for( var i = 0; i < splited.length; i++ ) { strtt += "<img src=\"http://tn-skr.smilevideo.jp/smile?i=" + splited[i].match( /[0-9]+/ ) + "\""; strtt += " onClick=\"play(\'" + splited[i] + "\');\">"; strtt += ( i % 5 == 4 ) ? "<br>\n" : "\n"; } document.getElementsByTagName( "span" )[0].innerHTML = strtt; } function play( strg ) { var fso = new ActiveXObject( 'Scripting.FileSystemObject' ); var filesCollection = fso.GetFolder( "動画のダウンロードパス" ).Files; for( var file = new Enumerator( filesCollection ); !file.atEnd(); file.moveNext() ) { var fileName = file.item().Name; if( fileName.match( new RegExp( strg + ".*\.flv" ) ) ) { var wshShell = new ActiveXObject( 'WScript.Shell' ); wshShell.Run( '"NicoPlayerのインストールパス\\NicoPlayer.exe" "動画のダウンロードパス\\' + fileName + '\"' ); return; } } } //--> </script> </head> <body onLoad="listupThumbnails();"> <span/> </body> </html> ***リンク先の動画タイトル・再生/コメント数をツールチップとして表示する ( -ver0.44 ) Ajaxちっくに書き直して、再生/コメント数を追加してみました。簡易化のためbodyタグ内に%__COMMENT__%しか置いていませんが、ページ全体に対し有効なので初期ファイルにコードを追加するだけでも大丈夫です。aタグは動画情報ウィンドウでは無意味なのでlink.onclick = new Function( "return false;" );で無効化しています。これで誤爆防止のためspan等で置き換える必要がなくなります。onclickイベントでアクションを起こしたい場合、"func(); return false;"等としてください。 <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var targetLinks = $H(); var decorateLinks = function() { $A( document.links ).each( function( link ) { link.onclick = new Function( "return false;" ); if( link.href.match( /watch\/(sm\d+)/ ) ) { targetLinks[RegExp.$1] = link; var url = link.href.replace( "watch", "thumb" ); new Ajax.Request( url, { method : "get", onComplete : getThumbnailPage } ); } } ); } var getThumbnailPage = function( request ) { var text = request.responseText; var title = text.match( /<img alt="([^"]+)/ ) ? RegExp.$1 : ""; var playCount = text.match( /再生:<strong>([\d,]*)/ ) ? RegExp.$1 : ""; var commentCount = text.match( /コメント:<strong>([\d,]*)/ ) ? RegExp.$1 : ""; var movieName = text.match( /watch\/(sm\d+)/ ) ? RegExp.$1 : ""; targetLinks[movieName].title = title + "\n再生:" + playCount + " コメント:" + commentCount; } </script> </head> <body onload="decorateLinks()"> %__COMMENT__% </body> </html> ***マイリスト・タグ検索をTubePlayerっぽく表示する( -ver0.45 ) マイリストやタグ検索のリンクをクリックすると、ウィンドウをポップアップしてTubePlayerっぽく一覧表示します。カーソルを重ねたとき文字が青色になれば、すでにダウンロード済みなのでクリックするとすぐに再生できます。逆に赤くなればまだダウンロードしておらず、クリックするとダウンロードを開始します。ウィンドウを閉じるときは右上の×をクリックしてください。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <style> #dummy { position:absolute; visibility:hidden; } #table { font-size:9pt; width:100% } #template { position:absolute; visibility:hidden; } #target { position:absolute; top:0pt; left:0pt; width:100% } .even { background-color:#dddddd; cursor:pointer } .odd { background-color:#ffffff; cursor:pointer } </style> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var localFlvFiles; var $_ = function( target, key ) { return $A( target.getElementsByTagName( key ) ); } EscapeUTF8=function(str){ return str.replace(/[^*+.-9A-Z_a-z-]/g,function(s){ var c=s.charCodeAt(0); return (c<16?"%0"+c.toString(16):c<128?"%"+c.toString(16) :c<2048?"%"+(c>>6|192).toString(16)+"%"+(c&63|128).toString(16) :"%"+(c>>12|224).toString(16)+"%"+(c>>6&63|128).toString(16)+"%" +(c&63|128).toString(16)).toUpperCase() }) }; // リンク編集(通常動作無効・マイリストのリンクのみshowDecoratedMylist起動) var decorateLinks = function() { searchFlvFiles(); $A( document.links ).each( function( link ) { link.onclick = new Function( "return false;" ); if( link.href.match( /mylist\/(\d+)/ ) ) { link.onclick = new Function( "showDecoratedMylist(this);return false;" ); } else if( link.href.match( /tag\/(.+)/ ) ) { link.onclick = new Function( "showDecoratedTag(this);return false;" ); } } ); } var showDecoratedMylist = function( link ) { new Ajax.Request( link.href, { method : "get", onComplete : responseMylistPage } ); } var showDecoratedTag = function( link ) { var url = "http://www.nicovideo.jp/tag/" + EscapeUTF8( link.innerHTML ); new Ajax.Request( url, { method : "get", onComplete : parseTagPage } ); } var responseMylistPage = function( response ) { var dummy = $( "dummy" ); dummy.innerHTML = response.responseText; // ページを解釈して要素(タイトル、再生数、…)を取得 // テーブル(ID:mylists) -> 行<tr>(ベース) -> 強調<strong>/リンク<a> // 例)タイトル -> 2番目のリンクの内容 再生数 -> 3番目の強調の内容 var items = $A(); var mylists = $( "mylists" ); var trs = $_( mylists, "tr" ); trs.each( function( tr ) { var movieName = $_( tr, "a" )[1].href.match( /sm\d+/ )[0]; var flag = localFlvFiles[movieName]; items.push( { date : $_( tr, "strong" )[0].innerHTML , time : $_( tr, "strong" )[1].innerHTML , play : $_( tr, "strong" )[2].innerHTML , comment : $_( tr, "strong" )[3].innerHTML , mylist : "-" , title : $_( tr, "a" )[1].innerHTML , name : movieName , color : flag ? "blue" : "red" , action : flag ? "play" : "download" } ); } ); dummy.innerHTML = ""; showTable( items ); } var parseTagPage = function( response ) { var dummy = $( "dummy" ); dummy.innerHTML = response.responseText; var items = $A(); var table = $_( dummy, "table" )[8]; var tds = $_( table, "td" ); var strongs = $_( tds[0], "a" ); var buffer = ""; tds.each( function( td ) { var movieName = $_( td, "a" )[1].href.match( /sm\d+/ )[0]; var flag = localFlvFiles[movieName]; items.push( { date : "-" , time : $_( td, "strong" )[0].innerHTML , play : $_( td, "strong" )[1].innerHTML , comment : $_( td, "strong" )[2].innerHTML , mylist : $_( td, "strong" )[3].innerHTML , title : $_( td, "a" )[1].innerHTML , name : movieName , color : flag ? "blue" : "red" , action : flag ? "play" : "download" } ); } ); dummy.innerHTML = ""; showTable( items ); } var showTable = function( items ) { // 要素リストitemsを元にテーブル構築 var table = $( "template" ).cloneNode( true ); table.setAttribute( "id", "table" ); items.each( function( item, index ) { var tr = document.createElement( "tr" ); tr.setAttribute( "class", ( index % 2 ) ? "odd": "even" ); tr.setAttribute( "onmouseover", "this.style.color=\""+ item.color + "\";" ); tr.setAttribute( "onmouseout" , "this.style.color=\"black\";" ); tr.setAttribute( "onclick" , item.action + "( \'" + item.name + "\' );" ); var keys = $A( new Array( "date", "time", "play", "comment", "mylist", "title", "name" ) ); keys.each( function( key ) { var td = document.createElement( "td" ); var text = document.createTextNode( item[key] ); td.appendChild( text ); tr.appendChild( td ); } ); table.appendChild( tr ); } ); // 表示(再描画のため空文字列""を追加挿入) $( "target" ).innerHTML = ""; $( "target" ).appendChild( table ); $( "target" ).innerHTML += ""; } var searchFlvFiles = function() { if( !localFlvFiles ) { localFlvFiles = $H(); var fs = new ActiveXObject( "Scripting.FileSystemObject" ); var files = new Enumerator( fs.GetFolder( "%__DOWNLOAD_DIR2__%" ).Files ); while( !files.atEnd() ) { if( files.item().Name.match( /(sm\d+).*\.flv/ ) ) { localFlvFiles[RegExp.$1] = files.item(); } files.moveNext(); } } } function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } var play = function( movieName ) { execBuildupCommand( "\"" + localFlvFiles[movieName].Path + "\"" ); } var download = function( movieName ) { execBuildupCommand( "http://www.nicovideo.jp/watch/" + movieName ); } </script> </head> <body onload="decorateLinks();"> %__COMMENT__% <br /> %__TAGS__% <table id="template" style="width:100%;background-color:#ffffff"> <tr style="background-color:#000000;color:#ffffff"> <th>Date<small>▼</small></th><th>Time</th><th>Play</th><th>Comment</th><th>Mylist</th><th>Title</th> <th align="right"><span style="cursor='pointer'" onclick="$('table').style.visibility='hidden';">×</span></th> </tr> </table> <div id="target2"></div> <div id="target"></div> <div id="dummy"></div> </body> </html> ***ランキングをTubePlayerっぽく表示する ( -ver0.45 ) ページサイズ制限(50KB)に引っかかったため削除。(2008/01/02 18:39) ***検索をTubePlayerっぽく表示する ( -ver0.45 ) マイページをTubePlayerっぽく表示する、の検索版です。EscapeUTF8は[[こちら>http://nurucom-archives.hp.infoseek.co.jp/digital/escape-codec-library.html]]からお借りしました(感謝(-人-)。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <style> #dummy { position : absolute; visibility : hidden; } table { font-size : 9pt; } .even { background-color : #efdbdd; cursor : pointer } .odd { background-color : #deefdb; cursor : pointer } </style> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var localFlvFiles; EscapeUTF8=function(str){ return str.replace(/[^*+.-9A-Z_a-z-]/g,function(s){ var c=s.charCodeAt(0); return (c<16?"%0"+c.toString(16):c<128?"%"+c.toString(16) :c<2048?"%"+(c>>6|192).toString(16)+"%"+(c&63|128).toString(16) :"%"+(c>>12|224).toString(16)+"%"+(c>>6&63|128).toString(16)+"%" +(c&63|128).toString(16)).toUpperCase() }) }; var $_ = function( target, key ) { return $A( target.getElementsByTagName( key ) ); } var getSearchPage = function( page ) { var url = "http://www.nicovideo.jp/search/" + EscapeUTF8( $F( "keyword" ) ) + "?" + $F( "select" ); if( page ) { url += "page=" + page; } new Ajax.Request( url, { method : "get", onComplete : responseSearchPage } ); } var responseSearchPage = function( request ) { var dummy = $( "dummy" ); dummy.innerHTML = request.responseText; searchFlvFiles(); var items = $A(); var tables = $_( dummy, "table" ); var tds = $_( tables[7], "td" ); tds.each( function( td ) { var strongs = $_( td, "strong" ); var as = $_( td, "a" ); as[1].href.match( /watch\/(sm\d+)/ ); var movieName = RegExp.$1; var flag = localFlvFiles[movieName]; items.push( { time : strongs[0].innerHTML , play : strongs[1].innerHTML , comment : strongs[2].innerHTML , mylist : strongs[3].innerHTML , title : as[1].innerHTML , name : movieName , action : flag ? "play" : "download" , color : flag ? "blue" : "red" } ); } ); var nextPage = 0; var imgs = $_( tables[6], "img" ); if( imgs[1].src.match( /next_on/ ) ) { if( imgs[1].parentNode.href.match( /page=(\d+)/ ) ) { nextPage = RegExp.$1; } } dummy.innerHTML = ""; showTable( nextPage, items ); } var showTable = function( nextPage, items ) { var template = new Template( "<td>#{time}</td><td>#{play}</td><td>#{comment}</td>" + "<td>#{mylist}</td><td>#{title}</td><td>#{name}</td>" ); var buffer = "<a href=\"#\" onclick=\"getSearchPage( \'" + nextPage + "\' ); return false;\">Next</a>" + "<table>"; buffer += "<tr><th>Time</th><th>P</th><th>C</th><th>M</th><th>Title</th><th>ID</th></tr>"; items.each( function( item, index ) { buffer += "<tr class=\""+ ( ( index % 2 ) ? "odd" : "even" ) + "\"" + " onclick=\"" + item.action + "( \'" + item.name + "\' )\"" + " onmouseover=\"this.style.color=\'" + item.color + "\'\"" + " onmouseout=\"this.style.color=\'black\'\">" + template.evaluate( item ); + "</tr>"; } ); buffer += "</table>"; $( "target" ).innerHTML = buffer; } var searchFlvFiles = function() { if( !localFlvFiles ) { localFlvFiles = $H(); var fs = new ActiveXObject( "Scripting.FileSystemObject" ); var files = new Enumerator( fs.GetFolder( "D:\\NicoPlayer\\Down" ).Files ); while( !files.atEnd() ) { if( files.item().Name.match( /(sm\d+).*\.flv/ ) ) { localFlvFiles[RegExp.$1] = files.item(); } files.moveNext(); } } } function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } var play = function( movieName ) { execBuildupCommand( "\"" + localFlvFiles[movieName].Path + "\"" ); } var download = function( movieName ) { execBuildupCommand( "http://www.nicovideo.jp/watch/" + movieName ); } </script> </head> <body onload="getSearchPage()"> <input id="keyword" value="初音ミク"></input> <select id="select" onchange="getSearchPage()"> <option value="">コメントが新しい</option><option value="sort=v">再生数が多い</option> </select> <button onclick="getSearchPage()">検索</button> <div id="dummy"></div> <div id="target"></div> </body> </html> ***投稿者コメントのニコニコ動画内リンク(動画・マイページ)をクリックするとサムネイルを表示する ( -ver0.42 ) ブログパーツと同じ表示です。次にどの動画に飛ぶかな、というときの参考にどうぞ。表示した内容をさらに編集かけて、リンククリックで再生とかダウンロードとかコメント更新とかにすれば、さらに使い勝手がよくなるのではないでしょうか。スタイルシートがないとリンクが分からないので最小限入れました。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <style type="text/css"> span#link{ color:blue; text-decoration:underline; cursor:pointer } </style> <link rel="stylesheet" type="text/css" href="http://www.nicovideo.jp/css/thumb.css"> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> function showThumbnail( path ) { var url = "http://www.nicovideo.jp/" + path; var ajax = new Ajax.Updater( "target", url, { method : "get" } ); ajax = null; } function editCommentLinks() { var comment = $( "comment" ); var atags = $A( comment.getElementsByTagName( "a" ) ); atags.each( function( atag ) { var href = atag.getAttribute( "href" ); if( href.match( /watch\/(sm[0-9]+)/ ) ) { atag.outerHTML = "<span id=\"link\" onclick=\"showThumbnail( 'thumb/"+ RegExp.$1 + "' )\">" + RegExp.$1 + "</span>"; } else if( href.match( /mylist\/([0-9]+\/[0-9]+)/ ) ) atag.outerHTML = "<span id=\"link\" onclick=\"showThumbnail( 'thumb_mylist/"+ RegExp.$1 + "' )\">mylist/" + RegExp.$1 + "</span>"; } ); } </script> </head> <body onload="editCommentLinks()"> <span id="comment">%__COMMENT__%</span> <br/> <span id="target"></span> </body> </html> ***プレイリストを検索しリストをリアルタイム更新、該当する行をクリックすると再生 NicoPlayerで表示するとonclickが機能しないので検索ボタンを押してください。ブラウザで見るとリアルタイムで更新します。 動画情報でやることではないですが、プレイリストにこんな機能がつくとうれしいな!という感じで。 <html> <head> <meta http-equiv="content-type" content="text/html;charset=shift_jis"> <script language="javascript"> var pathOfNicoPlayer = "NicoPlayerのインストールパス"; var pathOfDownload = "動画ファイルのダウンロードパス"; function getPlaylistWithRequest( keyword ) { if( keyword == "" ) { keyword = document.getElementsByTagName( "input" )[0].value; } var fso = new ActiveXObject( 'Scripting.FileSystemObject' ); var playlistFile = fso.OpenTextFile( pathOfNicoPlayer + "\\default.m3u", 1 ); var filePathList = playlistFile.ReadAll().split( "\n" ); playlistFile.Close(); var strt = ""; for( var i = 0; i < filePathList.length; i++ ) { var fileName = fso.GetFileName( filePathList[i] ); var regex = new RegExp( keyword ); if( fileName.match( regex ) ) { strt += "<span onClick=\"play( this.innerHTML )\">" + fileName + "</span><br>"; } } document.getElementsByTagName( "span" )[0].innerHTML = keyword + strt; } function play( fileName ) { var wshShell = new ActiveXObject( 'WScript.Shell' ); wshShell.Run( pathOfNicoPlayer + "\\NicoPlayer.exe \"" + pathOfDownload + "\\" + fileName + "\"" ); } </script> </head> <body onLoad="getPlaylistWithRequest( '.*' );"> <input type="text" onkeyup="getPlaylistWithRequest( this.value )"> <input type="submit" value = "検索" onclick="getPlaylistWithRequest( '' )"> <br/> <span/> </body> </html> ***動画ページを全て表示する ページ総行数制限に引っかかったため削除。(2008/01/02 13:33) ***動画ページを全て表示する2 ( -ver0.41 ) 上記[動画ページを全て表示する]と違って公式Flashも機能します。適当なポータルサイトを指定すると、便利になるかもしれません。ちなみに<meta http-equiv="refresh" content="0;url=http://~">を使うと新規ウィンドウを開こうとし、標準ブラウザに制御が移ってしまいます。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript"> function redirect() { var shellObject = new ActiveXObject( "WScript.Shell" ); // 動画ページ直通(動画情報ウィンドウの中で動画が再生される一発芸) shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" videoinfo -move href=\"http://www.nicovideo.jp/watch//%__MOVIE_NAME__%\"" ); // ブログパーツ(サムネイル・再生数やコメント数など、こちらのほうが実用的) // shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" videoinfo -move href=\"http://www.nicovideo.jp/thumb/%__MOVIE_NAME__%\"" ); shellObject = null; } </script> </head> <body onload="redirect()" /> </html> ***プレイリスト一覧を表示し切り替える ( -ver0.41 ) プレイリストファイルを気軽に切り替えられます。[[スクリプト]]や上記の拡張を使ってマイページやタグ、検索ワードごと大量のプレイリストを作成している場合特に有効です。CSS要素を省くと異様にしょぼくなりましたが仕様です。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); // 0:ウィンドウ非表示(-6まであり) true:終了待機フラグ shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } function showPlaylists() { var strt = "<table>"; var fsObject = new ActiveXObject( "Scripting.FileSystemObject" ); var files = fsObject.GetFolder( "%__SOFT_DIR2__%" ).Files; for( var file = new Enumerator( files ); !file.atEnd(); file.moveNext() ) { var fileName = file.item().Name; if( fsObject.GetExtensionName( fileName ) == "m3u" ) { strt += "<tr><td onclick=\"setPlaylist( '" + file.item().Path.gsub( /\\/, "\\\\" ) + "' )\" >" + fileName + "</td></tr>"; } } $( "target2" ).innerHTML += strt + "</table>"; files = null; } function setPlaylist( val ) { execBuildupCommand( "playlist -clear" ); execBuildupCommand( "\"" + val + "\" -addlist" ); } </script> </head> <body> <span id="target1" onclick="showPlaylists()">プレイリスト</span> <br /> <span id="target2"></span> </body> </html> ***公式のNGリストを取得し表示する ( -ver0.41 ) それだけです。これといって有効な連携が思いつかなかった…。 <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> function showIgnorelist() { var xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = false; xml.load( "http://www.nicovideo.jp/api/configurengclient?mode=get" ); var nodes = $A( xml.getElementsByTagName( "source" ) ); var strt = ""; nodes.each( function ( node ) { strt += node.text + " "; } ); $( "target" ).innerHTML = strt; xml = null; } </script> </head> <body onload="showIgnorelist()"> <span id="target"></span> </body> </html> ***ダウンロード済みのコメントファイルを結合する ( -ver0.42 ) 1000コメントと500コメントのファイルがあれば、1500コメントがまとまった1つのファイルが出来ます(プレイリストに追加登録)。本家開発とかぶってる感ぷんぷんですが、どんな感じになるのか先行体験してみたいかたはどうぞ。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="nicoplayer.js"></script> <script type="text/javascript"> function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } function uniteComment() { // コメントファイルの捜索 var filesPath = []; var fsObject = new ActiveXObject( "Scripting.FileSystemObject" ); var files = fsObject.GetFolder( "%__DOWNLOAD_DIR2__%" ).Files; for( var file = new Enumerator( files ); !file.atEnd(); file.moveNext() ) { var item = file.item(); if( item.Name.match( /\(%__MOVIE_NAME__%\)\[.+\]\.xml/ ) ) { filesPath.push( item.Path ); } } // 読み込み var nodes = [], threadNode, viewCounterNode; xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = false; filesPath.each( function( filePath ) { xml.load( filePath ); nodes = nodes.concat( $A( xml.getElementsByTagName( "chat" ) ) ); } ); threadNode = xml.getElementsByTagName( "thread" )[0]; viewCounterNode = xml.getElementsByTagName( "view_counter" )[0]; xml = null; // 重複除去 var unique = {}; nodes = nodes.findAll( function ( node ) { var no= node.getAttribute( "no" ); if( unique[no] ) { return false; } unique[no] = true; return true; } ); // ソート nodes.sortBy( function( node ) { return parseInt( node.getAttribute( "no" ) ); } ); // 新規コメントファイル作成 xml = new ActiveXObject( "Microsoft.XMLDOM" ); var packetNode = xml.createElement( "packet" ); xml.appendChild( packetNode ); // $( "target" ).innerHTML = nodes.last().getAttribute( "no" ); threadNode.setAttribute( "last_res", nodes.last().getAttribute( "no" ) ); packetNode.appendChild( threadNode ); packetNode.appendChild( viewCounterNode ); nodes.each( function( node ) { packetNode.appendChild( node ); } ); var newCommentPath = "%__DOWNLOAD_DIR2__%\\%__TITLE__%(%__MOVIE_NAME__%).xml" xml.save( newCommentPath ); packetNode = null; xml = null; // プレイリストに追加 execBuildupCommand( "\"" + newCommentPath + "\" -addlist" ); } </script> </head> <body> <button onclick="uniteComment()">コメントを結合する</button> </body> </html> ***過去のコメントを取得する ( -ver0.42 ) ページ総行数制限に引っかかったため削除。(2008/01/02 13:30) ***一つ前のコメントを取得する ( -ver0.44 ) 今再生している、一番最初のコメントの日時を使って取得します。日時指定をする必要がない点を除けば、過去のコメントを取得する、とほとんど同じです(prototype.jsのAJAXオブジェクトを使って書き換えました)。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> $_ = function( target, key ) { return $A( target.getElementsByTagName( key ) ); } $_A = function( target, key ) { return target.getAttribute( key ); } function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } var parametersHash = $H(); var when; show = function() { var url, param, vid = "%__MOVIE_NAME__%"; // 動画ページへアクセス url = "http://www.nicovideo.jp/watch/" + vid; new Ajax.Request( url, { method : "get", asynchronous : false } ); // ダウンロード元サーバ・スレッド番号・ユーザIDを取得 url = "http://www.nicovideo.jp/api/getflv?v=" + vid; new Ajax.Request( url, { method : "get", asynchronous : false, onComplete : getParameters } ); // キー取得 url = "http://www.nicovideo.jp/api/getwaybackkey?thread=" + parametersHash["thread_id"]; new Ajax.Request( url, { method : "get", asynchronous : false, onComplete : getParameters } ); // 取得時間取得 var xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.load( "%__COMMENT_PATH2__%" ); when = $_A( $_( xml, "chat" )[0], "date" ); xml = null; // コメント取得 param = "<thread res_from=\"-1000\"" + " when=\"" + when + "\"" + " waybackkey=\"" + parametersHash["waybackkey"] + "\"" + " user_id=\"" + parametersHash["user_id"] + "\"" + " version=\"20061206\"" + " thread=\"" + parametersHash["thread_id"] + "\"" + "/>"; url = parametersHash["ms"]; new Ajax.Request( url, { postBody : param, asynchronous : false, onComplete : getComment } ); } // パラメタをハッシュへ格納 function getParameters( request ) { var parametersList = $A( unescape( request.responseText ).split( "&" ) ); parametersList.each( function( parameter ) { if( parameter.match( /([^=]+)=(.+)/ ) ) { parametersHash[RegExp.$1] = RegExp.$2; } } ); } function getComment( request ) { var xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.loadXML( request.responseText ); var date = new Date(); date.setTime( when * 1000 ); var path = "%__DOWNLOAD_DIR2__%\\%__TITLE__%(%__MOVIE_NAME__%)[" + date.getYear() + "." + date.getMonth() + "." + date.getDate() + " " + date.getHours() + "時" + date.getMinutes() + "分].xml"; xml.save( path ); xml = null; // プレイリストに追加 execBuildupCommand( "\"" + path + "\" -addlist" ); } </script> </head> <body> <button onclick="show()">取得</button><br /> <span id="target"></span> </body> </html> *コメント #pcomment()
#contents() *概要 ニコニコ動画のサイト上で表示される、動画の「ヘッダー」の部分、およびニコニコ市場(インターネット接続時)を表示します。 *機能 以下の内容を表示します。 -投稿年月日時 -動画タイトル -投稿者コメント -登録タグ -ニコニコ市場(インターネット接続時のみ) 以上の内容はvideoinfoフォルダ内にHTMLテンプレートが配置されているので、自由に編集することができます。 *機能拡張 **設定ファイル 動画情報ウィンドウのフォーマット(表示形式)はHTMLとCSSで設定されています。 設定ファイルである以下のドキュメントを書き換えることで、外観を変えたり、機能を追加したりできます。 -template.html (インターネット接続時の動画情報の表示用テンプレート) -template_off.html (保存した動画情報の表示用テンプレート) -style.css (保存した動画情報の表示用CSS) -reading.html (動画情報読み込みまでの「読み込み中...」の表示) -error.html (動画情報読み込み失敗時の表示) ※いずれもvideoinfoフォルダ内にあります。 ※動画情報を表示したときにtemp.htmlが生成されます。 ※インターネット接続時のCSSは、[[http://res.nicovideo.jp/css/_.css?071011>動画情報ウィンドウ]]から読み込んでいます。&br()↑CSSのURL直リンクはまずそうなので、クリックしてもこのページに戻ってくるようになっています。参照したい場合はブラウザのアドレス欄にコピペしてください。 ※これらのファイルの初期状態のソースは[[動画情報ウィンドウ フォーマット]]に記載しています。 **パラメータ HTML内には以下のようなパラメータが使用できます。 |%__MOVIE_NAME__%|動画ID(smXXXXXXXのこと。X:数字、IDにより1~7桁)| |%__MOVIE_ID__%|動画IDの数字部分(上記のXXXXXXXに相当)| |%__POST__%|投稿年月日・時分秒| |%__TITLE__%|動画タイトル| |%__COMMENT__%|投稿者コメント| |%__TAGS__%|登録タグ| |%__SOFT_DIR__%|NicoPlayerのインストールフォルダ| |%__DOWNLOAD_DIR__%|ダウンロードフォルダ| |%__MEDIA_PATH__%|動画ファイルのパス| |%__COMMENT_PATH__%|コメントファイルのパス| |%__PLAYLIST_PATH__%|ロード中のプレイリストファイルのパス| |%__SOFT_DIR2__%|NicoPlayerのインストールフォルダ(※1)| |%__DOWNLOAD_DIR2__%|ダウンロードフォルダ(※1)| |%__MEDIA_PATH2__%|動画ファイルのパス(※1)| |%__COMMENT_PATH2__%|コメントファイルのパス(※1)| |%__PLAYLIST_PATH2__%|ロード中のプレイリストファイルのパス(※1)| |%__VIEW_COUNT__%|再生数(※2)| |%__COMMENT_COUNT__%|コメント数(※2)| ※1 パスの区切り文字が\\となる(ソースコード内で使用) ※2 コメントファイル(xml)から値を取得するので、最新の数値ではありません。 **パラメータ使用例 :http ://www.nicovideo.jp/watch/%__MOVIE_NAME__%|動画ページのアドレス :http ://tn-skr.smilevideo.jp/smile?i=%__MOVIE_ID__%|動画のサムネイル(検索・マイページ等の縮小画像) **機能拡張サンプル いくつかのサンプルでは別途JavaScriptのライブラリが必要になります。 ダウンロード:[[prototype.js>http://www.prototypejs.org/]] [[excanvas.js>http://sourceforge.net/project/showfiles.php?group_id=163391]] ***はじめに NicoPlayerは動画情報の表示にIEコンポーネント(InternetExplorerの一部)の機能を使っています。設定は[設定ファイル]で示されている、HTML及びその周辺フォーマット(JavaScript・CSS)で記述されたファイル群で行われています。特にtemplate.htmlを編集することで、通常再生時に表示される動画情報を好みに合わせることが出来ます。またシェルを介することでNicoPlayerを操作したり、他のツールと連携したりといったことも可能です。 大きな可能性を秘めた動画情報ウィンドウですが、あまりに強力なためセキュリティ上の観点からいくつかの機能が標準で禁止されています。以下の機能拡張サンプルではこれらの機能を用いている場合が多いため、危険性を十分に認識した上で次の手順で機能使用の許可設定を行う必要があります。 >セキュリティの設定 インターネットエクスプローラ(IE)のメニュー[ツール]から[インターネットオプション]を選択する 上部のタグから[セキュリティ]を選択し、[イントラネット]・[レベルのカスタマイズ]へ進む [ActiveXコントロールとプラグイン]の  [スクリプトを実行しても安全だとマークされていないActiveXコントロールの初期化とスクリプトの実行] を有効にし、  [ActiveXコントロールに対して自動的にダイアログを表示] を無効にしてください。 これでセキュリティ上は全てのサンプルが機能するようになりました。ただし一部のサンプルではフレームワークという、開発を容易にするソフトウェアを使用しています。次の手順で導入してください。 >prototype.jsの導入 [[prototype>http://www.prototypejs.org/]]のページを開き、Download(右上)をクリックする [Download the latest stable version]をクリックし、ファイルを保存する ダウンロードしたprototype.js(設定によっては.jsが表示されないことがあります)をvideoinfoフォルダへ移動させる これでほとんどのサンプルは機能するはずです。もしうまくいかなかったら、このページの下のほうにあるコメントに書き込んでみましょう。誰かが手助けしてくれるかもしれません。自力で解決できた場合は、ぜひ躓いた点とその解決策を書き込んでください! ***動画から3秒目の画像を取り出し表示する グラフの背景(サムネイルを拡大表示)があまりに無理やりなので、自前で用意して見ました。 //今回から[[prototype.js>http://www.prototypejs.org/]](事実上標準のJavaScriptライブラリ…らしい)を導入しました。また先頭のコメントを追加したことにより、イントラネットのセキュリティ設定が適用されるようになります。すでに共有フォルダなどで環境構築されている方はそのままでかまいません。そうでない方は若干リスクが上がるものの、比較的簡易に構築できるこの設定をお勧めします(インターネットオプション>セキュリティ>イントラネット>ActiveXコントロールとプラグイン の項目を全て有効にする)。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var pathOf3GPConverter = "携帯動画変換君のパス"; function showThumbnail() { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( pathOf3GPConverter + "\\cores\\ffmpeg.exe -i \"%__MEDIA_PATH2__%\" -f image2 -pix_fmt png" + " -vframes 1 -ss 3 -s 260x200 -an -deinterlace \"%__MEDIA_PATH2__%.png\"", 0, true ); wshShell = null; $( "target1" ).innerHTML = "<img src=\"%__MEDIA_PATH2__%.png\">"; } </script> </head> <body onload="showThumbnail()"> <span id="target1" /> </body> </html> ***いろいろな値をクリップボードにコピーするボタンを設置する <td>コピー</td>の次の行から、実際に何をコピーするかの定義が始まります。ボタンを追加したい場合は行ごとコピー&ペーストで増やして、シングルクォーテーション(')で挟まれている値をお好みの内容に変更してください。このページの上のほうにある[パラメータ]の項を参考にするとよいです。 <html> <head> <script type="text/javascript"> function copyTextToClipboard( value ) { clipboardData.setData( "Text", value ); } </script> </head> <body> <table border="1"> <tr> <td>コピー</td> <td><button onclick="copyTextToClipboard( 'http://www.nicovideo.jp/watch/%__MOVIE_NAME__%' )">アドレス</button></td> <td><button onclick="copyTextToClipboard( '%__MEDIA_PATH2__%' )">ファイル</button></td> <td><button onclick="copyTextToClipboard( '%__MOVIE_NAME__%' )">ID</button></td> </tr> </table> </body> </html> ***携帯動画変換君に投げ込むボタンを設置する・MP3ファイルを抽出するボタンを設置する ( -ver0.41 ) "携帯動画変換君のパス"という所を、各自の環境に合うよう変更してください(パスの区切り文字は\ではなく\\、もしくは/を使ってください)。前提として、動画ファイルをドラッグ&ドロップするだけで変換できるようになっていなければなりません。 MP3ファイル抽出を追加しました。"FFMPEGのパス(\\ffmpeg.exeまで含む)"を環境に合わせて変更してください。FFMPEGは[[こちら>http://ffdshow.faireal.net/mirror/ffmpeg/]]からどうぞ。追記:保存先フォルダを指定するダイアログを表示するようにしました。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript"> var pathOf3GPConverter = "携帯動画変換君のパス"; var pathOfFfmpeg = "FFMPEGのパス(\\ffmpeg.exeまで含む)"; function convertWith3GPConverter() { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"" + pathOf3GPConverter + "\\3GP_Converter.exe\" \"%__MEDIA_PATH2__%\"" ); wshShell = null; } function extractMp3( path ) { var shell = new ActiveXObject( "WScript.Shell" ); shell.Run( "\"" + pathOfFfmpeg + "\" -acodec copy -y -i \"" + path + "\" \"" + path + ".mp3\"", 0, true ); shell = null; shell = new ActiveXObject( "Shell.Application" ); var folder = shell.BrowseForFolder( 0, "保存先のフォルダを選択してください", 1, "ssfDESKTOP" ); if( folder != null ) { folder.CopyHere( path + ".mp3" ); } } </script> </head> <body> <table border="1"> <tr> <td>変換</td> <td><button onclick="convertWith3GPConverter()">3GP</button></td> <td><button onclick="extractMp3( '%__MEDIA_PATH2__%' )">MP3</button></td> </tr> </table> </body> </html> ***コメントの推移をグラフ化して表示する 縦軸がコメント数、横軸が投稿日時です。canvasタグの描画に excanvas.jsを使用しているので[[こちら>http://sourceforge.net/project/showfiles.php?group_id=163391]]からダウンロードして 同じパスにおいてください。 赤線がコメントを表し、青線は100コメントごとの区切りです。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="excanvas.js"></script> <script type="text/javascript"> var canvasWidth = 260; var canvasHeight = 200; function drawGraph() { // XMLパーサオブジェクトを生成 xmldomObject = new ActiveXObject( "Microsoft.XMLDOM" ); xmldomObject.async = false; xmldomObject.load( "%__COMMENT_PATH2__%" ); // コメント数・投稿日時の尺をキャンバスサイズに合わせる var nodes = xmldomObject.getElementsByTagName( "chat" ); var firstChatDate = nodes[0].getAttribute( "date" ); var lastChatDate = nodes[nodes.length - 1].getAttribute( "date" ); var hscale = ( lastChatDate - firstChatDate ) / canvasWidth; var vscale = nodes.length / canvasHeight; var context = document.getElementById( "canvas" ).getContext( "2d" ); // 背景画像を描画 var imgObj = new Image( canvasWidth, canvasHeight ); imgObj.src = "http://tn-skr.smilevideo.jp/smile?i=%__MOVIE_ID__%"; context.drawImage( imgObj, 0, 0 ); var j = 0; var table = new Array( 15 ); // コメントの遷移を表示 context.strokeStyle = "rgba( 255, 0, 0, 1 )"; context.moveTo( 0, canvasHeight ); for( var i = 0; i < nodes.length; i++ ) { context.lineTo( ( nodes[i].getAttribute( "date" ) - firstChatDate ) / hscale, canvasHeight - ( i / vscale ) ); if( i % 100 == 99 ) { table[j++] = canvasHeight - ( i / vscale ); } } context.stroke(); // コメント数の水準線を表示 context.strokeStyle = "rgba( 0, 0, 255, 1 )"; for( var i = 0; i < j; i++ ) { context.moveTo( 0, table[i] ); context.lineTo( canvasWidth, table[i] ); } context.stroke(); } </script> </head> <body onload="drawGraph()"> <canvas id="canvas" width="260" height="200" /> </body> </html> ***コメントを再生ファイルの時間軸についてグラフ化 横軸が再生時間、縦軸がコメント数(秒単位)です。グラフをクリックすると 該当する位置にシーク(再生位置が移動)します。弾幕のありそうなところに 当たりをつけて直前に飛ぶ、といった使い方を想定しています。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="excanvas.js"></script> <script type="text/javascript"> var canvasWidth = 260; var canvasHeight = 200; function drawGraph() { xmldomObject = new ActiveXObject( "Microsoft.XMLDOM" ); xmldomObject.async = false; xmldomObject.load( "%__COMMENT_PATH2__%" ); // コメントの発言時間を集計(秒単位) var vposHash = {}, maxCount = 0, lastVpos = 0; var nodes = xmldomObject.getElementsByTagName( "chat" ); for( var i = 0; i < nodes.length; i++ ) { var nVpos = Math.round( nodes[i].getAttribute( "vpos" ) / 100 ); if( vposHash[ nVpos ] == undefined ) { vposHash[ nVpos ] = 1; } else { vposHash[ nVpos ]++; } lastVpos = Math.max( lastVpos, nVpos ); maxCount = Math.max( maxCount, vposHash[ nVpos ] ); } // スケール決定 var hscale = lastVpos / canvasWidth; var vscale = maxCount / canvasHeight; var context = document.getElementById( "canvas" ).getContext( "2d" ); // 背景画像を描画 var imageObject = new Image( canvasWidth, canvasHeight ); imageObject.src = "http://tn-skr.smilevideo.jp/smile?i=%__MOVIE_ID__%"; context.drawImage( imageObject, 0, 0 ); context.strokeStyle = "rgba( 255, 0, 0, 1 )"; context.moveTo( 0, canvasHeight ); // グラフを描画 for( var i = 0; i < lastVpos; i++ ) { var count = vposHash[i]; if( count != undefined ) { context.lineTo( i / hscale, canvasHeight - ( count / vscale ) ); } } context.stroke(); } function seek() { var pos_percent = Math.round( ( event.offsetX / canvasWidth ) * 100 ); var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" player -seek pos_percent=" + pos_percent ); } </script> </head> <body onload="drawGraph()"> <canvas id="canvas" width="260" height="200" onclick="seek()" /> <span /> </body> </html> ***プレイリストのサムネイルを列挙し、クリックしたら再生する プレイリストにサムネイルが表示されたらいいな、と思っていたので力ずくでやってみました。 NicoPlayerの機能は全然使っていません。動画情報ですらないです。巨大なプレイリストで 使うと、問題がありそうです。ActiveXを使っているので携帯動画変換君に投げ込むボタンと 同じ条件でないと機能しません。 <html> <head> <meta http-equiv="content-type" content="text/html;charset=shift_jis"> <script language="javascript"> <!-- function listupThumbnails() { var strtt = "", fso = new ActiveXObject( 'Scripting.FileSystemObject' ); var file = fso.OpenTextFile("NicoPlayerのインストールパス\\default.m3u"); splited = file.ReadAll().match( /sm[0-9]+/ig ); for( var i = 0; i < splited.length; i++ ) { strtt += "<img src=\"http://tn-skr.smilevideo.jp/smile?i=" + splited[i].match( /[0-9]+/ ) + "\""; strtt += " onClick=\"play(\'" + splited[i] + "\');\">"; strtt += ( i % 5 == 4 ) ? "<br>\n" : "\n"; } document.getElementsByTagName( "span" )[0].innerHTML = strtt; } function play( strg ) { var fso = new ActiveXObject( 'Scripting.FileSystemObject' ); var filesCollection = fso.GetFolder( "動画のダウンロードパス" ).Files; for( var file = new Enumerator( filesCollection ); !file.atEnd(); file.moveNext() ) { var fileName = file.item().Name; if( fileName.match( new RegExp( strg + ".*\.flv" ) ) ) { var wshShell = new ActiveXObject( 'WScript.Shell' ); wshShell.Run( '"NicoPlayerのインストールパス\\NicoPlayer.exe" "動画のダウンロードパス\\' + fileName + '\"' ); return; } } } //--> </script> </head> <body onLoad="listupThumbnails();"> <span/> </body> </html> ***リンク先の動画タイトル・再生/コメント数をツールチップとして表示する ( -ver0.44 ) Ajaxちっくに書き直して、再生/コメント数を追加してみました。簡易化のためbodyタグ内に%__COMMENT__%しか置いていませんが、ページ全体に対し有効なので初期ファイルにコードを追加するだけでも大丈夫です。aタグは動画情報ウィンドウでは無意味なのでlink.onclick = new Function( "return false;" );で無効化しています。これで誤爆防止のためspan等で置き換える必要がなくなります。onclickイベントでアクションを起こしたい場合、"func(); return false;"等としてください。 <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var targetLinks = $H(); var decorateLinks = function() { $A( document.links ).each( function( link ) { link.onclick = new Function( "return false;" ); if( link.href.match( /watch\/(sm\d+)/ ) ) { targetLinks[RegExp.$1] = link; var url = link.href.replace( "watch", "thumb" ); new Ajax.Request( url, { method : "get", onComplete : getThumbnailPage } ); } } ); } var getThumbnailPage = function( request ) { var text = request.responseText; var title = text.match( /<img alt="([^"]+)/ ) ? RegExp.$1 : ""; var playCount = text.match( /再生:<strong>([\d,]*)/ ) ? RegExp.$1 : ""; var commentCount = text.match( /コメント:<strong>([\d,]*)/ ) ? RegExp.$1 : ""; var movieName = text.match( /watch\/(sm\d+)/ ) ? RegExp.$1 : ""; targetLinks[movieName].title = title + "\n再生:" + playCount + " コメント:" + commentCount; } </script> </head> <body onload="decorateLinks()"> %__COMMENT__% </body> </html> ***マイリスト・タグ検索をTubePlayerっぽく表示する( -ver0.45 ) マイリストやタグ検索のリンクをクリックすると、ウィンドウをポップアップしてTubePlayerっぽく一覧表示します。カーソルを重ねたとき文字が青色になれば、すでにダウンロード済みなのでクリックするとすぐに再生できます。逆に赤くなればまだダウンロードしておらず、クリックするとダウンロードを開始します。ウィンドウを閉じるときは右上の×をクリックしてください。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <style> #dummy { position:absolute; visibility:hidden; } #table { font-size:9pt; width:100% } #template { position:absolute; visibility:hidden; } #target { position:absolute; top:0pt; left:0pt; width:100% } .even { background-color:#dddddd; cursor:pointer } .odd { background-color:#ffffff; cursor:pointer } </style> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var localFlvFiles; var $_ = function( target, key ) { return $A( target.getElementsByTagName( key ) ); } EscapeUTF8=function(str){ return str.replace(/[^*+.-9A-Z_a-z-]/g,function(s){ var c=s.charCodeAt(0); return (c<16?"%0"+c.toString(16):c<128?"%"+c.toString(16) :c<2048?"%"+(c>>6|192).toString(16)+"%"+(c&63|128).toString(16) :"%"+(c>>12|224).toString(16)+"%"+(c>>6&63|128).toString(16)+"%" +(c&63|128).toString(16)).toUpperCase() }) }; // リンク編集(通常動作無効・マイリストのリンクのみshowDecoratedMylist起動) var decorateLinks = function() { searchFlvFiles(); $A( document.links ).each( function( link ) { link.onclick = new Function( "return false;" ); if( link.href.match( /mylist\/(\d+)/ ) ) { link.onclick = new Function( "showDecoratedMylist(this);return false;" ); } else if( link.href.match( /tag\/(.+)/ ) ) { link.onclick = new Function( "showDecoratedTag(this);return false;" ); } } ); } var showDecoratedMylist = function( link ) { new Ajax.Request( link.href, { method : "get", onComplete : responseMylistPage } ); } var showDecoratedTag = function( link ) { var url = "http://www.nicovideo.jp/tag/" + EscapeUTF8( link.innerHTML ); new Ajax.Request( url, { method : "get", onComplete : parseTagPage } ); } var responseMylistPage = function( response ) { var dummy = $( "dummy" ); dummy.innerHTML = response.responseText; // ページを解釈して要素(タイトル、再生数、…)を取得 // テーブル(ID:mylists) -> 行<tr>(ベース) -> 強調<strong>/リンク<a> // 例)タイトル -> 2番目のリンクの内容 再生数 -> 3番目の強調の内容 var items = $A(); var mylists = $( "mylists" ); var trs = $_( mylists, "tr" ); trs.each( function( tr ) { var movieName = $_( tr, "a" )[1].href.match( /sm\d+/ )[0]; var flag = localFlvFiles[movieName]; items.push( { date : $_( tr, "strong" )[0].innerHTML , time : $_( tr, "strong" )[1].innerHTML , play : $_( tr, "strong" )[2].innerHTML , comment : $_( tr, "strong" )[3].innerHTML , mylist : "-" , title : $_( tr, "a" )[1].innerHTML , name : movieName , color : flag ? "blue" : "red" , action : flag ? "play" : "download" } ); } ); dummy.innerHTML = ""; showTable( items ); } var parseTagPage = function( response ) { var dummy = $( "dummy" ); dummy.innerHTML = response.responseText; var items = $A(); var table = $_( dummy, "table" )[8]; var tds = $_( table, "td" ); var strongs = $_( tds[0], "a" ); var buffer = ""; tds.each( function( td ) { var movieName = $_( td, "a" )[1].href.match( /sm\d+/ )[0]; var flag = localFlvFiles[movieName]; items.push( { date : "-" , time : $_( td, "strong" )[0].innerHTML , play : $_( td, "strong" )[1].innerHTML , comment : $_( td, "strong" )[2].innerHTML , mylist : $_( td, "strong" )[3].innerHTML , title : $_( td, "a" )[1].innerHTML , name : movieName , color : flag ? "blue" : "red" , action : flag ? "play" : "download" } ); } ); dummy.innerHTML = ""; showTable( items ); } var showTable = function( items ) { // 要素リストitemsを元にテーブル構築 var table = $( "template" ).cloneNode( true ); table.setAttribute( "id", "table" ); items.each( function( item, index ) { var tr = document.createElement( "tr" ); tr.setAttribute( "class", ( index % 2 ) ? "odd": "even" ); tr.setAttribute( "onmouseover", "this.style.color=\""+ item.color + "\";" ); tr.setAttribute( "onmouseout" , "this.style.color=\"black\";" ); tr.setAttribute( "onclick" , item.action + "( \'" + item.name + "\' );" ); var keys = $A( new Array( "date", "time", "play", "comment", "mylist", "title", "name" ) ); keys.each( function( key ) { var td = document.createElement( "td" ); var text = document.createTextNode( item[key] ); td.appendChild( text ); tr.appendChild( td ); } ); table.appendChild( tr ); } ); // 表示(再描画のため空文字列""を追加挿入) $( "target" ).innerHTML = ""; $( "target" ).appendChild( table ); $( "target" ).innerHTML += ""; } var searchFlvFiles = function() { if( !localFlvFiles ) { localFlvFiles = $H(); var fs = new ActiveXObject( "Scripting.FileSystemObject" ); var files = new Enumerator( fs.GetFolder( "%__DOWNLOAD_DIR2__%" ).Files ); while( !files.atEnd() ) { if( files.item().Name.match( /(sm\d+).*\.flv/ ) ) { localFlvFiles[RegExp.$1] = files.item(); } files.moveNext(); } } } function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } var play = function( movieName ) { execBuildupCommand( "\"" + localFlvFiles[movieName].Path + "\"" ); } var download = function( movieName ) { execBuildupCommand( "http://www.nicovideo.jp/watch/" + movieName ); } </script> </head> <body onload="decorateLinks();"> %__COMMENT__% <br /> %__TAGS__% <table id="template" style="width:100%;background-color:#ffffff"> <tr style="background-color:#000000;color:#ffffff"> <th>Date<small>▼</small></th><th>Time</th><th>Play</th><th>Comment</th><th>Mylist</th><th>Title</th> <th align="right"><span style="cursor='pointer'" onclick="$('table').style.visibility='hidden';">×</span></th> </tr> </table> <div id="target2"></div> <div id="target"></div> <div id="dummy"></div> </body> </html> ***ランキングをTubePlayerっぽく表示する ( -ver0.45 ) ページサイズ制限(50KB)に引っかかったため削除。(2008/01/02 18:39) ***検索をTubePlayerっぽく表示する ( -ver0.45 ) マイページをTubePlayerっぽく表示する、の検索版です。EscapeUTF8は[[こちら>http://nurucom-archives.hp.infoseek.co.jp/digital/escape-codec-library.html]]からお借りしました(感謝(-人-)。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <style> #dummy { position : absolute; visibility : hidden; } table { font-size : 9pt; } .even { background-color : #efdbdd; cursor : pointer } .odd { background-color : #deefdb; cursor : pointer } </style> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var localFlvFiles; EscapeUTF8=function(str){ return str.replace(/[^*+.-9A-Z_a-z-]/g,function(s){ var c=s.charCodeAt(0); return (c<16?"%0"+c.toString(16):c<128?"%"+c.toString(16) :c<2048?"%"+(c>>6|192).toString(16)+"%"+(c&63|128).toString(16) :"%"+(c>>12|224).toString(16)+"%"+(c>>6&63|128).toString(16)+"%" +(c&63|128).toString(16)).toUpperCase() }) }; var $_ = function( target, key ) { return $A( target.getElementsByTagName( key ) ); } var getSearchPage = function( page ) { var url = "http://www.nicovideo.jp/search/" + EscapeUTF8( $F( "keyword" ) ) + "?" + $F( "select" ); if( page ) { url += "page=" + page; } new Ajax.Request( url, { method : "get", onComplete : responseSearchPage } ); } var responseSearchPage = function( request ) { var dummy = $( "dummy" ); dummy.innerHTML = request.responseText; searchFlvFiles(); var items = $A(); var tables = $_( dummy, "table" ); var tds = $_( tables[7], "td" ); tds.each( function( td ) { var strongs = $_( td, "strong" ); var as = $_( td, "a" ); as[1].href.match( /watch\/(sm\d+)/ ); var movieName = RegExp.$1; var flag = localFlvFiles[movieName]; items.push( { time : strongs[0].innerHTML , play : strongs[1].innerHTML , comment : strongs[2].innerHTML , mylist : strongs[3].innerHTML , title : as[1].innerHTML , name : movieName , action : flag ? "play" : "download" , color : flag ? "blue" : "red" } ); } ); var nextPage = 0; var imgs = $_( tables[6], "img" ); if( imgs[1].src.match( /next_on/ ) ) { if( imgs[1].parentNode.href.match( /page=(\d+)/ ) ) { nextPage = RegExp.$1; } } dummy.innerHTML = ""; showTable( nextPage, items ); } var showTable = function( nextPage, items ) { var template = new Template( "<td>#{time}</td><td>#{play}</td><td>#{comment}</td>" + "<td>#{mylist}</td><td>#{title}</td><td>#{name}</td>" ); var buffer = "<a href=\"#\" onclick=\"getSearchPage( \'" + nextPage + "\' ); return false;\">Next</a>" + "<table>"; buffer += "<tr><th>Time</th><th>P</th><th>C</th><th>M</th><th>Title</th><th>ID</th></tr>"; items.each( function( item, index ) { buffer += "<tr class=\""+ ( ( index % 2 ) ? "odd" : "even" ) + "\"" + " onclick=\"" + item.action + "( \'" + item.name + "\' )\"" + " onmouseover=\"this.style.color=\'" + item.color + "\'\"" + " onmouseout=\"this.style.color=\'black\'\">" + template.evaluate( item ); + "</tr>"; } ); buffer += "</table>"; $( "target" ).innerHTML = buffer; } var searchFlvFiles = function() { if( !localFlvFiles ) { localFlvFiles = $H(); var fs = new ActiveXObject( "Scripting.FileSystemObject" ); var files = new Enumerator( fs.GetFolder( "D:\\NicoPlayer\\Down" ).Files ); while( !files.atEnd() ) { if( files.item().Name.match( /(sm\d+).*\.flv/ ) ) { localFlvFiles[RegExp.$1] = files.item(); } files.moveNext(); } } } function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } var play = function( movieName ) { execBuildupCommand( "\"" + localFlvFiles[movieName].Path + "\"" ); } var download = function( movieName ) { execBuildupCommand( "http://www.nicovideo.jp/watch/" + movieName ); } </script> </head> <body onload="getSearchPage()"> <input id="keyword" value="初音ミク"></input> <select id="select" onchange="getSearchPage()"> <option value="">コメントが新しい</option><option value="sort=v">再生数が多い</option> </select> <button onclick="getSearchPage()">検索</button> <div id="dummy"></div> <div id="target"></div> </body> </html> ***投稿者コメントのニコニコ動画内リンク(動画・マイページ)をクリックするとサムネイルを表示する ( -ver0.42 ) ブログパーツと同じ表示です。次にどの動画に飛ぶかな、というときの参考にどうぞ。表示した内容をさらに編集かけて、リンククリックで再生とかダウンロードとかコメント更新とかにすれば、さらに使い勝手がよくなるのではないでしょうか。スタイルシートがないとリンクが分からないので最小限入れました。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <style type="text/css"> span#link{ color:blue; text-decoration:underline; cursor:pointer } </style> <link rel="stylesheet" type="text/css" href="http://www.nicovideo.jp/css/thumb.css"> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> function showThumbnail( path ) { var url = "http://www.nicovideo.jp/" + path; var ajax = new Ajax.Updater( "target", url, { method : "get" } ); ajax = null; } function editCommentLinks() { var comment = $( "comment" ); var atags = $A( comment.getElementsByTagName( "a" ) ); atags.each( function( atag ) { var href = atag.getAttribute( "href" ); if( href.match( /watch\/(sm[0-9]+)/ ) ) { atag.outerHTML = "<span id=\"link\" onclick=\"showThumbnail( 'thumb/"+ RegExp.$1 + "' )\">" + RegExp.$1 + "</span>"; } else if( href.match( /mylist\/([0-9]+\/[0-9]+)/ ) ) atag.outerHTML = "<span id=\"link\" onclick=\"showThumbnail( 'thumb_mylist/"+ RegExp.$1 + "' )\">mylist/" + RegExp.$1 + "</span>"; } ); } </script> </head> <body onload="editCommentLinks()"> <span id="comment">%__COMMENT__%</span> <br/> <span id="target"></span> </body> </html> ***プレイリストを検索しリストをリアルタイム更新、該当する行をクリックすると再生 NicoPlayerで表示するとonclickが機能しないので検索ボタンを押してください。ブラウザで見るとリアルタイムで更新します。 動画情報でやることではないですが、プレイリストにこんな機能がつくとうれしいな!という感じで。 <html> <head> <meta http-equiv="content-type" content="text/html;charset=shift_jis"> <script language="javascript"> var pathOfNicoPlayer = "NicoPlayerのインストールパス"; var pathOfDownload = "動画ファイルのダウンロードパス"; function getPlaylistWithRequest( keyword ) { if( keyword == "" ) { keyword = document.getElementsByTagName( "input" )[0].value; } var fso = new ActiveXObject( 'Scripting.FileSystemObject' ); var playlistFile = fso.OpenTextFile( pathOfNicoPlayer + "\\default.m3u", 1 ); var filePathList = playlistFile.ReadAll().split( "\n" ); playlistFile.Close(); var strt = ""; for( var i = 0; i < filePathList.length; i++ ) { var fileName = fso.GetFileName( filePathList[i] ); var regex = new RegExp( keyword ); if( fileName.match( regex ) ) { strt += "<span onClick=\"play( this.innerHTML )\">" + fileName + "</span><br>"; } } document.getElementsByTagName( "span" )[0].innerHTML = keyword + strt; } function play( fileName ) { var wshShell = new ActiveXObject( 'WScript.Shell' ); wshShell.Run( pathOfNicoPlayer + "\\NicoPlayer.exe \"" + pathOfDownload + "\\" + fileName + "\"" ); } </script> </head> <body onLoad="getPlaylistWithRequest( '.*' );"> <input type="text" onkeyup="getPlaylistWithRequest( this.value )"> <input type="submit" value = "検索" onclick="getPlaylistWithRequest( '' )"> <br/> <span/> </body> </html> ***動画ページを全て表示する ページ総行数制限に引っかかったため削除。(2008/01/02 13:33) ***動画ページを全て表示する2 ( -ver0.41 ) 上記[動画ページを全て表示する]と違って公式Flashも機能します。適当なポータルサイトを指定すると、便利になるかもしれません。ちなみに<meta http-equiv="refresh" content="0;url=http://~">を使うと新規ウィンドウを開こうとし、標準ブラウザに制御が移ってしまいます。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript"> function redirect() { var shellObject = new ActiveXObject( "WScript.Shell" ); // 動画ページ直通(動画情報ウィンドウの中で動画が再生される一発芸) shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" videoinfo -move href=\"http://www.nicovideo.jp/watch//%__MOVIE_NAME__%\"" ); // ブログパーツ(サムネイル・再生数やコメント数など、こちらのほうが実用的) // shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" videoinfo -move href=\"http://www.nicovideo.jp/thumb/%__MOVIE_NAME__%\"" ); shellObject = null; } </script> </head> <body onload="redirect()" /> </html> ***プレイリスト一覧を表示し切り替える ( -ver0.41 ) プレイリストファイルを気軽に切り替えられます。[[スクリプト]]や上記の拡張を使ってマイページやタグ、検索ワードごと大量のプレイリストを作成している場合特に有効です。CSS要素を省くと異様にしょぼくなりましたが仕様です。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); // 0:ウィンドウ非表示(-6まであり) true:終了待機フラグ shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } function showPlaylists() { var strt = "<table>"; var fsObject = new ActiveXObject( "Scripting.FileSystemObject" ); var files = fsObject.GetFolder( "%__SOFT_DIR2__%" ).Files; for( var file = new Enumerator( files ); !file.atEnd(); file.moveNext() ) { var fileName = file.item().Name; if( fsObject.GetExtensionName( fileName ) == "m3u" ) { strt += "<tr><td onclick=\"setPlaylist( '" + file.item().Path.gsub( /\\/, "\\\\" ) + "' )\" >" + fileName + "</td></tr>"; } } $( "target2" ).innerHTML += strt + "</table>"; files = null; } function setPlaylist( val ) { execBuildupCommand( "playlist -clear" ); execBuildupCommand( "\"" + val + "\" -addlist" ); } </script> </head> <body> <span id="target1" onclick="showPlaylists()">プレイリスト</span> <br /> <span id="target2"></span> </body> </html> ***公式のNGリストを取得し表示する ( -ver0.41 ) それだけです。これといって有効な連携が思いつかなかった…。 <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> function showIgnorelist() { var xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = false; xml.load( "http://www.nicovideo.jp/api/configurengclient?mode=get" ); var nodes = $A( xml.getElementsByTagName( "source" ) ); var strt = ""; nodes.each( function ( node ) { strt += node.text + " "; } ); $( "target" ).innerHTML = strt; xml = null; } </script> </head> <body onload="showIgnorelist()"> <span id="target"></span> </body> </html> ***ダウンロード済みのコメントファイルを結合する ( -ver0.42 ) 1000コメントと500コメントのファイルがあれば、1500コメントがまとまった1つのファイルが出来ます(プレイリストに追加登録)。本家開発とかぶってる感ぷんぷんですが、どんな感じになるのか先行体験してみたいかたはどうぞ。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="nicoplayer.js"></script> <script type="text/javascript"> function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } function uniteComment() { // コメントファイルの捜索 var filesPath = []; var fsObject = new ActiveXObject( "Scripting.FileSystemObject" ); var files = fsObject.GetFolder( "%__DOWNLOAD_DIR2__%" ).Files; for( var file = new Enumerator( files ); !file.atEnd(); file.moveNext() ) { var item = file.item(); if( item.Name.match( /\(%__MOVIE_NAME__%\)\[.+\]\.xml/ ) ) { filesPath.push( item.Path ); } } // 読み込み var nodes = [], threadNode, viewCounterNode; xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = false; filesPath.each( function( filePath ) { xml.load( filePath ); nodes = nodes.concat( $A( xml.getElementsByTagName( "chat" ) ) ); } ); threadNode = xml.getElementsByTagName( "thread" )[0]; viewCounterNode = xml.getElementsByTagName( "view_counter" )[0]; xml = null; // 重複除去 var unique = {}; nodes = nodes.findAll( function ( node ) { var no= node.getAttribute( "no" ); if( unique[no] ) { return false; } unique[no] = true; return true; } ); // ソート nodes.sortBy( function( node ) { return parseInt( node.getAttribute( "no" ) ); } ); // 新規コメントファイル作成 xml = new ActiveXObject( "Microsoft.XMLDOM" ); var packetNode = xml.createElement( "packet" ); xml.appendChild( packetNode ); // $( "target" ).innerHTML = nodes.last().getAttribute( "no" ); threadNode.setAttribute( "last_res", nodes.last().getAttribute( "no" ) ); packetNode.appendChild( threadNode ); packetNode.appendChild( viewCounterNode ); nodes.each( function( node ) { packetNode.appendChild( node ); } ); var newCommentPath = "%__DOWNLOAD_DIR2__%\\%__TITLE__%(%__MOVIE_NAME__%).xml" xml.save( newCommentPath ); packetNode = null; xml = null; // プレイリストに追加 execBuildupCommand( "\"" + newCommentPath + "\" -addlist" ); } </script> </head> <body> <button onclick="uniteComment()">コメントを結合する</button> </body> </html> ***過去のコメントを取得する ( -ver0.42 ) ページ総行数制限に引っかかったため削除。(2008/01/02 13:30) ***一つ前のコメントを取得する ( -ver0.44 ) 今再生している、一番最初のコメントの日時を使って取得します。日時指定をする必要がない点を除けば、過去のコメントを取得する、とほとんど同じです(prototype.jsのAJAXオブジェクトを使って書き換えました)。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> $_ = function( target, key ) { return $A( target.getElementsByTagName( key ) ); } $_A = function( target, key ) { return target.getAttribute( key ); } function execBuildupCommand( argument ) { var shellObject = new ActiveXObject( "WScript.Shell" ); shellObject.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + argument, 0, true ); shellObject = null; } var parametersHash = $H(); var when; show = function() { var url, param, vid = "%__MOVIE_NAME__%"; // 動画ページへアクセス url = "http://www.nicovideo.jp/watch/" + vid; new Ajax.Request( url, { method : "get", asynchronous : false } ); // ダウンロード元サーバ・スレッド番号・ユーザIDを取得 url = "http://www.nicovideo.jp/api/getflv?v=" + vid; new Ajax.Request( url, { method : "get", asynchronous : false, onComplete : getParameters } ); // キー取得 url = "http://www.nicovideo.jp/api/getwaybackkey?thread=" + parametersHash["thread_id"]; new Ajax.Request( url, { method : "get", asynchronous : false, onComplete : getParameters } ); // 取得時間取得 var xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.load( "%__COMMENT_PATH2__%" ); when = $_A( $_( xml, "chat" )[0], "date" ); xml = null; // コメント取得 param = "<thread res_from=\"-1000\"" + " when=\"" + when + "\"" + " waybackkey=\"" + parametersHash["waybackkey"] + "\"" + " user_id=\"" + parametersHash["user_id"] + "\"" + " version=\"20061206\"" + " thread=\"" + parametersHash["thread_id"] + "\"" + "/>"; url = parametersHash["ms"]; new Ajax.Request( url, { postBody : param, asynchronous : false, onComplete : getComment } ); } // パラメタをハッシュへ格納 function getParameters( request ) { var parametersList = $A( unescape( request.responseText ).split( "&" ) ); parametersList.each( function( parameter ) { if( parameter.match( /([^=]+)=(.+)/ ) ) { parametersHash[RegExp.$1] = RegExp.$2; } } ); } function getComment( request ) { var xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.loadXML( request.responseText ); var date = new Date(); date.setTime( when * 1000 ); var path = "%__DOWNLOAD_DIR2__%\\%__TITLE__%(%__MOVIE_NAME__%)[" + date.getYear() + "." + date.getMonth() + "." + date.getDate() + " " + date.getHours() + "時" + date.getMinutes() + "分].xml"; xml.save( path ); xml = null; // プレイリストに追加 execBuildupCommand( "\"" + path + "\" -addlist" ); } </script> </head> <body> <button onclick="show()">取得</button><br /> <span id="target"></span> </body> </html> ***コメントをこっそり投稿する ( -ver0.45 ) 自分専用コメントファイルを作り、そこに投稿します。他の誰にも見えません。コメ職人気分が味わえるかもしれません。再生時間は1/100秒単位で指定してください。 <!-- saved from url=(0017)http://localhost/ --> <html> <head> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var $_ = function( target, key ) { return $A( target.getElementsByTagName( key ) ); } // ローカルコメントファイル作成 var createTrialCommentFile = function( path ) { var fs = new ActiveXObject( "Scripting.FileSystemObject" ); if( fs.FileExists( path ) ) return; var file = fs.CreateTextFile( path ); file.Write( "<?xml version=\"1.0\" encoding=\"UTF-8\"?><packet></packet>" ); file.Close(); } // ローカルコメントファイルにコメント追加 var xml; var postCommentTrial = function() { var path = "%__DOWNLOAD_DIR2__%\\%__TITLE__%(%__MOVIE_NAME__%)[Local].xml"; createTrialCommentFile( path ); if( !xml ) { xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = false; } xml.load( path ); var packet = $_( xml, "packet" )[0]; var chat = xml.createElement( "chat" ); chat.setAttribute( "vpos", $F( "time" ) ); chat.setAttribute( "mail", $F( "command" ) ); chat.text = ( $F( "comment" ) ); packet.appendChild( chat ); xml.save( path ); } var execBuildupCommand = function( param ) { var shell = new ActiveXObject( "WScript.Shell" ); shell.Run( "\"%__SOFT_DIR2__%\\NicoPlayer.exe\" " + param, 0, true ); shell = null; } </script> </head> <body> <input id="time" value="0" />[1/100(s)] <input id="command" value="ue" /> <input id="comment" value="test" /> <button onclick="postCommentTrial()">投稿</button> <div id="target"></div> </body> </html> *コメント #pcomment()

表示オプション

横に並べて表示:
変化行の前後のみ表示:
目安箱バナー