日記はScrapboxに移動しました。

  • antipopのlivedoor Readerでの購読者数が1,000人に達しました

    antipopのlivedoor Readerでの購読者数が1,000人に達しました。ありがとうございます!
    f:id:antipop:20070401022626p:image
    今後も、当ブログをご覧になってくださってる方にとって、なにか少しでもためになるようなエントリを書いていきたいと、改めて思ったりしてます><ノ

  • 図解・はてなちゃんと学ぶ、livedoor Reader の使い方 #1

    f:id:antipop:20061122015442j:image
    powered by はてなちゃんセリフ

  • livedoor Reader と GMail に見る、大量のチェックボックス処理 UI における革新的工夫について

    , , ,

    HTML には、複数の項目を選択する UI として、たとえばチェックボックスがあります。こんなやつですね

    好きなメンバを選択してください(複数可)









    これぐらいの量だったら、選択するにせよ解除するにせよ、まぁたいしたことはないかもしれませんが、もし、選択項目が数十あるいは数百あったらどうでしょうか。激しくめんどくさいですよね。
    世界的に優れたフィードリーダである livedoor Reader は、フィードリーダとしての使い勝手は当然として、そんなところにも実は気を配っていたりします。
    たとえば、LDR のおすすめフィード登録画面「アルファブロガーズ」を見てみると(livedoor ID でログインする必要があります)、アルファブロガーさんのブログが数十個表示されるのですが、これを選択または解除するに際して、チェックボックスを一個ずつぽちぽちクリックする必要はありません。ブログ名の右方向に広がる空白のあたりをマウスでさーっと撫でてみると、それだけでスムーズに選択・解除が反転していきます。
    他方では、GMail の工夫も見逃すことができません。GMail において大量のチェックボックスを処理する場合には、一般的なファイラで採用されているのと同様の、Shift クリックによる範囲指定選択・解除ができます。これで、大量のメールを間単に、素早くさばくことができます。
    このように、チェックボックスのような、古くからある UI ひとつひとつをないがしろにすることなく工夫をこらすことで、ユーザエクスペリエンスを激烈に高めることが可能です。みなさんも同様の UI を作成する場合には、是非参考にしてみてはいかがでしょうか。

    ヤコブ・ニールセンのAlertbox -そのデザイン、間違ってます-
    • Jakob Nielsen、 舩井 淳、 奥泉 直子、 川崎 幹人
    • RBB PRESS
    • 2006-07-12
    • ¥ 2,730
    • Book

    Web情報アーキテクチャ―最適なサイト構築のための論理的アプローチ
    • ルイス ローゼンフェルド、 ピーター モービル、 Louis Rosenfeld、 Peter Morville、 篠原 稔和、 ソシオメディア
    • オライリージャパン
    • 2003-08
    • ¥ 4,620
    • Book
  • 未読フィード恐怖症について、あるいは、それ Greasemonkey でよくね?

    , ,

    ただ、RSSリーダーに慣れてくると、陥りがちな病気があるんです。
    その名も「未読RSS恐怖症」です。RSSリーダーに調子に乗って大量のブログやニュースサイトを登録したことで、毎日更新通知される大量の記事に処理が追いつかなくなり、徐々にRSSリーダーの未読記事が膨れ上がり、だんだんRSSリーダーを開くのが嫌になってくるという恐ろしい(?)病気です。

    それGre(ry)
    詳細については、livedoor Readerとは – はてな に掲載されている vi モードのあたりを。
    とはいえ、まぁ、LDR であれば「最速インターフェース研究会 :: how many feeds do you subscribe to?」を参考にして、レートを駆使すれば、かなりの程度までどうにかなるのではないでしょうか。
    僕の LDR は、毎日だいたい 1,500 から 2,000 くらい新着エントリがあって、フィードにレートをつけるのがめんどうくさくて放置してあるので、フラット表示にして、端から端まで全部、少なくともタイトルだけは眺めています。まぁ、レート管理しないでも済む程度の情報にしか触れていないってことですが。
    今後はぼちぼちレートつけるようにしていきたいなぁ。

    ストレスフリーの仕事術―仕事と人生をコントロールする52の法則
    デビッド アレン David Allen 田口 元
    二見書房 (2006/05)
  • livedoor Reader で読んだフィードの履歴を遡れるようにする greasemonkey スクリプト

    ,

    LDR でさくさくフィードを読み進めているときに、さっき読んでたフィードに戻りたいと思いきや、すでにマイフィードのリストは更新されており、そのフィードは消えていて簡単には戻れずに、残念な思いをすることがあります。
    そこで、以下の通りのスクリプトを書いて、読んだフィードの履歴を遡れるようにしてみました。Shift + p / Shift + n で履歴をいったりきたりできます。
    LDR のキャッシュの仕組みがよくわからないので、フィードを丸ごと配列に保存しておくという強引なやりくちを用いています……。
    インストール: ldr_feed_history.user.js

    // ==UserScript==
    // @name          LDR Feed History
    // @namespace     http://antipop.gs/ns/greasemonkey/ldr_feed_history
    // @include       http://reader.livedoor.com/reader/*
    // ==/UserScript==
    (function(){
    var historyMaxLength = 5;
    var w = unsafeWindow;
    var _onload = w.onload;
    var onload  = function(){with (w) {
    State.GM_now_reading  = null;
    State.GM_feed_index   = 0;
    State.GM_feed_history = [];
    register_hook('after_printfeed', function (feed) {
    var filtered = State.GM_feed_history.filter(function (iter) {
    return (iter.subscribe_id == feed.subscribe_id);
    });
    if (!filtered.length) {
    State.GM_feed_history.unshift(feed);
    while (State.GM_feed_history.length > (historyMaxLength + 1)) {
    State.GM_feed_history.pop();
    }
    State.GM_now_reading = State.now_reading;
    State.GM_feed_index  = 0;
    }
    });
    Keybind.add('P', function () {
    if (State.GM_feed_index < (State.GM_feed_history.length - 1)) {
    print_feed(State.GM_feed_history[++State.GM_feed_index]);
    State.now_reading = State.GM_now_reading;
    }
    });
    KeyConfig.history_up = 'P';
    KeyHelp.history_up   = '\u5C65\u6B74\u3092\u904E\u53BB\u306B\u5411\u304B\u3063\u3066\u79FB\u52D5\u3059\u308B';
    Keybind.add('N', function () {
    if (State.GM_feed_index > 0) {
    print_feed(State.GM_feed_history[--State.GM_feed_index]);
    State.now_reading = State.GM_now_reading;
    }
    });
    KeyConfig.history_down = 'N';
    KeyHelp.history_down   = '\u5C65\u6B74\u3092\u73FE\u5728\u306B\u5411\u304B\u3063\u3066\u79FB\u52D5\u3059\u308B';
    }};
    w.onload = function(){
    _onload();
    onload();
    };
    })();

    ライブドアの技術面に関する特集が掲載されています。

    JavaScriptビジュアル・リファレンス
    シーズ
    エムディエヌコーポレーション (2004/11)
    売り上げランキング: 29,745

    非常に評判の高い JavaScript リファレンス。

  • Update: LDR で最速動画ウォッチング + YouTube Anywhere

    , ,

    “どこでも YouTube” を実現する Greasemonkey スクリプト YouTube Anywhere」で公開したスクリプトを、せっかくなので、LDR にも対応してみました。「livedoor Reader + YouTube + はてなブックマークで最速動画ウォッチング」と「“どこでも YouTube” を実現する Greasemonkey スクリプト YouTube Anywhere」を足して 2 で割らない感じ。つってもまぁ、最低限 LDR 上で動くようにしただけなのがアレ。それなりに動くので、まぁいいや。あと、ついでにnirvashの日記に触発されて、Qooqle Video Clippers!HATENA-TUBE のフィードにも対応。
    使いかたを再度説明。
    LDR 上では、YouTube, Qooqle, HATENA-TUBE の動画エントリを見てる時に、ショートカットキー “y” を押すとプレイヤ表示、さらに “y” を押すとプレイヤを隠します。その他のサイト(デフォルトでは del.icio.usはてなブックマーク)では、YouTube の動画ページのリンクの脇にアイコンが表示されるので、クリックするとプレイヤが表示されます。
    プレイヤに表示されているアイコンをあれこれ押してみればわかりますが、動画ダウンロードや、各種クリッピングサービスへのリンク等が配置されています。
    インストールは以下に示すリンクから。このスクリプトをインストールしたら、以前「livedoor Reader + YouTube + はてなブックマークで最速動画ウォッチング」で公開した YouTube Player on LDR は必要ありませんので、そっはアンインストールしちゃってください。
    インストール: youtube_anywhere.user.js

    // ==UserScript==
    //
    // @name          YouTube Anywhere
    // @namespace     http://antipop.gs/ns/greasemonkey/youtube_anywhere
    // @include       http://reader.livedoor.com/reader*
    // @include       http://b.hatena.ne.jp/*
    // @include       http://del.icio.us/*
    //
    // ==/UserScript==
    //
    // ==Configuration==
    //
    // add other domains to @include for more use
    //
    // - include YouTube.
    // @include       *youtube.com/*
    //
    // - include whole the web
    // @include       *
    //
    //==/Configuration==
    //
    //==Acknowledgments==
    //
    // Bitcons >> SOME RANDOM DUDE
    //  - http://somerandomdude.net/srd-projects/bitcons/
    //
    //==/Acknowledgments==
    //
    // ==Copyright==
    //
    // Copyright (C) 2006 by Kentaro Kuribayashi
    //
    // This script is distributed under the CCPL by-sa
    //  - See: http://creativecommons.org/licenses/by-sa/2.5/
    //
    (function(){
    var playerContainerId = 'GM_youtube_player';
    var playerWidth  = 425;
    var playerHeight = 350;
    var overlayId    = 'GM_overlay';
    var regexp = [
    new RegExp('^http://(?:www\\.)?youtube\\.com/(?:watch)?\\?.*v=([^&]+).*$', 'i'),
    new RegExp('^http://clippers\\.qooqle\\.jp/video/([^/]+).*$', 'i'),
    new RegExp('^http://www\\.fladdict\\.net/app/hatenatube/#v=([^&]+).*$', 'i'),
    ];
    if (location.href.match('^http://reader\\.livedoor\\.com/reader.*$', 'i')) {
    var w = unsafeWindow;
    var _onload = w.onload;
    var onload  = function(){with (w) {
    Keybind.add('y', function () {
    if ($(playerContainerId)) {
    hidePlayer();
    }
    else {
    var item = get_active_item(true);
    if (item) {
    regexp.forEach(function (r) {
    if (item.link.match(r)) {
    showPlayer(RegExp.$1, item.title);
    }
    });
    }
    }
    });
    }};
    w.onload = function(){
    _onload();
    onload();
    };
    }
    else {
    $A(document.links).forEach(function (link) {
    if (link.href.match(regexp[0])) {
    var videoId    = RegExp.$1;
    var videoTitle = link.innerHTML.replace(/<.+?>/g, '');
    var icon = $C('img', {
    'src'   : 'http://www.youtube.com/favicon.ico',
    'alt'   : 'YouTube',
    'title' : 'watch this movie',
    'style' : {
    'marginRight' : '0.5em',
    'cursor'      : 'pointer',
    },
    'event' : [{
    'name'     : 'click',
    'callback' : function () { showPlayer(videoId, videoTitle); },
    'flag'     : false,
    }],
    });
    link.parentNode.insertBefore(icon, link);
    }
    });
    }
    function $ (id) { return document.getElementById(id); };
    function $A (arg) {
    var array = [];
    for (var i = 0; i < arg.length; i++) {
    array.push(arg[i]);
    }
    return array;
    }
    function $C (tag, prop) {
    var element = document.createElement(tag);
    for (var i in prop) {
    if (i == 'style') {
    for (var p in prop[i]) {
    element.style[p] = prop[i][p];
    }
    }
    else if (i == 'event') {
    prop[i].forEach(function (e) {
    element.addEventListener(e.name, e.callback, e.flag);
    });
    }
    else {
    element[i] = prop[i];
    }
    }
    return element;
    };
    function createPlayerContainer (videoId, videoTitle) {
    var playerContainer = $C('div', {
    'id'     : playerContainerId,
    'style'  : {
    'position'        : 'fixed',
    'zIndex'          : '100',
    'backgroundColor' : '#ffffff',
    'padding'         : '0.5em 1.5em',
    },
    });
    var playerHeader = createPlayerHeader(videoTitle);
    var player       = createPlayer(videoId);
    var playerFooter = createPlayerFooter(videoId, videoTitle, player);
    [playerHeader, player, playerFooter].forEach(function (e) {
    playerContainer.appendChild(e);
    });
    return playerContainer;
    }
    function createPlayerHeader (videoTitle) {
    var playerHeader = $C('p', {
    'style' : {
    'fontWeight' : 'bold',
    'margin'     : '0.5em 2em 0.5em 0',
    }
    });
    var closeButton = $C('img', {
    'id'    : 'GM_close_utton',
    'src'   : getImageUrl('close'),
    'title' : 'Hide this player',
    'style' : {
    'display'         : 'block',
    'position'        : 'absolute',
    'top'             : '5px',
    'right'           : '5px',
    'cursor'          : 'pointer',
    'backgroundColor' : '#00cc00',
    },
    'event' : [
    {
    'name'     : 'click',
    'callback' : function () { hidePlayer(); },
    'flag'     : false,
    },
    {
    'name'     : 'mouseover',
    'callback' : function () { $('GM_close_utton').style.backgroundColor = '#ffd700'; },
    'flag'     : false,
    },
    {
    'name'     : 'mouseout',
    'callback' : function () { $('GM_close_utton').style.backgroundColor = '#00cc00'; },
    'flag'     : false,
    },
    ],
    });
    [document.createTextNode(videoTitle), closeButton,].forEach(function (e) {
    playerHeader.appendChild(e);
    });
    return playerHeader;
    }
    function createPlayerFooter (videoId, videoTitle, player) {
    var playerFooter = $C('div', {
    'style' : {
    'padding' : '0.5em 0',
    }
    });
    var linkContainer = $C('p', {style : { 'textAlign' : 'center', 'margin' : '0', }});
    var youtubeUri    = ['http://www.youtube.com/watch?v=', videoId].join('');
    [
    {
    'id'       : 'GM_download',
    'title'    : 'download this video',
    'getUri'   : ['http://youtubech.com/test/read.cgi?dl=', videoId].join(''),
    'label'    : 'Download',
    'image'    : 'download',
    },
    {
    'id'       : 'GM_post_to_hatena',
    'title'    : 'post to Hatena::Bookmark',
    'getUri'   : ['http://b.hatena.ne.jp/add?mode=confirm&url=', encodeURIComponent(youtubeUri)].join(''),
    'label'    : 'Hatena',
    'image'    : 'arrow',
    },
    {
    'id'       : 'GM_post_to_delicious',
    'title'    : 'post to del.icio.us',
    'getUri'   : ['http://del.icio.us/post?v=4;url=', encodeURIComponent(youtubeUri), ';title=', encodeURIComponent(videoTitle)].join(''),
    'label'    : 'del.icio.us',
    'image'    : 'arrow',
    },
    {
    'id'       : 'GM_post_to_qooqle',
    'title'    : 'post to qooqle',
    'getUri'   : ['http://clippers.qooqle.jp/post?url=', encodeURIComponent(youtubeUri)].join(''),
    'label'    : 'Qooqle',
    'image'    : 'arrow',
    },
    ].forEach(function (i) {
    var link = $C('span', {
    'id'    : i.id,
    'title' : i.title,
    'style' : {
    'color'         : '#00cc00',
    'textIndent'    : '20px',
    'verticalAlign' : 'middle',
    'marginRight'   : '0.5em',
    'cursor'        : 'pointer',
    },
    'event' : [
    {
    'name'     : 'click',
    'callback' : function () { window.open(i.getUri); },
    'flag'     : false,
    },
    {
    'name'     : 'mouseover',
    'callback' : function () { $(i.id).style.color = '#ffc125'; },
    'flag'     : false,
    },
    {
    'name'     : 'mouseout',
    'callback' : function () { $(i.id).style.color = '#00cc00'; },
    'flag'     : false,
    },
    ],
    });
    var icon = $C('img', {
    'src'   : getImageUrl(i.image),
    'style' : {
    'marginRight'     : '0.5em',
    'backgroundColor' : '#00cc00',
    },
    });
    [icon, document.createTextNode(i.label)].forEach(function (e) {
    link.appendChild(e);
    });
    linkContainer.appendChild(link);
    });
    playerFooter.appendChild(linkContainer);
    [
    {
    'label' : 'URI:',
    'id'    : 'youtube_uri',
    'value' : ['http://www.youtube.com/watch?v=', videoId].join(''),
    },
    {
    'label' : 'Player:',
    'id'    : 'youtube_embed',
    'value' : player.innerHTML,
    },
    {
    'label' : 'Hatena:',
    'id'    : 'hatena_notation',
    'value' : ['[http://youtubech.com/test/read.cgi', encodeURIComponent(['?dl=', videoId, '&.flv'].join('')), ':movie]'].join(''),
    },
    ].forEach(function (i) {
    var inputContainer = $C('p', { 'style' : { 'margin': '0.2em 0 0 0'} });
    var label = $C('label', {
    'for'   : i.id,
    });
    label.innerHTML = i.label;
    var input = $C('input', {
    'id'    : i.id,
    'style' : {
    'border'   : 'solid 1px #333333',
    'width'    : '80%',
    'position' : 'absolute',
    'right'    : '1.5em',
    },
    'event'   : [
    {
    'name'     : 'focus',
    'callback' : function () { $(i.id).select(); },
    'flag'     : false,
    },
    {
    'name'     : 'click',
    'callback' : function () { $(i.id).select(); },
    'flag'     : false,
    },
    ]
    });
    input.value = i.value;
    [label, input].forEach(function (e) {
    inputContainer.appendChild(e);
    });
    playerFooter.appendChild(inputContainer);
    });
    return playerFooter;
    }
    function createPlayer (videoId) {
    var videoSrc = ['http://www.youtube.com/v/', videoId].join('');
    var div    = $C('div', {});
    var object = $C('object', {
    'width'  : playerWidth,
    'height' : playerHeight,
    });
    var param  = $C('param',  {
    'name'   : 'movie',
    'value'  : videoSrc,
    });
    var embed  = $C('embed',  {
    'width'  : playerWidth,
    'height' : playerHeight,
    'type'   : 'application/x-shockwave-flash',
    'src'    : videoSrc,
    });
    [param, embed].forEach(function (e) { object.appendChild(e); });
    div.appendChild(object);
    return div;
    }
    function showPlayer (videoId, videoTitle) {
    var playerContainer  = createPlayerContainer(videoId, videoTitle);
    var overlay = $C('div', {
    id     : overlayId,
    style  : {
    'position'        : 'fixed',
    'top'             : '0%',
    'left'            : '0%',
    'width'           : '100%',
    'height'          : '100%',
    'zIndex'          : '99',
    'backgroundImage' : ['url("', getImageUrl('overlay'), '")'].join(''),
    },
    event  : [{
    'name'     : 'click',
    'callback' : function () { hidePlayer(); },
    'flag'     : false,
    }]
    });
    [overlay, playerContainer].forEach(function (e) {
    document.body.appendChild(e);
    });
    centering($(playerContainerId), 0, 0);
    }
    function hidePlayer () {
    [$(playerContainerId), $(overlayId)].forEach(function (e) {
    e.parentNode.removeChild(e);
    });
    }
    function centering (element, x, y) {
    with (element.style) {
    left = ((window.innerWidth  - element.offsetWidth)  / 2 + (x)) + 'px';
    top  = ((window.innerHeight - element.offsetHeight) / 2 + (y)) + 'px';
    }
    }
    function getImageUrl (name) {
    var images = {
    'close'    : "data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%01%03%00%00%00%25%3Dm%22%00%00%00%03sBIT%08%08%08%DB%E1O%E0%00%00%00%06PLTE%FF%FF%FF%FF%FF%FFU%7C%F5l%00%00%00%02tRNS%FF%00%E5%B70J%00%00%00%09pHYs%00%00%0B%12%00%00%0B%12%01%D2%DD~%FC%00%00%00!tEXtSoftware%00Macromedia%20Fireworks%204.0%EA%26'u%00%00%00%16tEXtCreation%20Time%0006%2F02%2F06%3Eg%BF%E4%00%00%00%22IDATx%9Cc%F8%FF%9F%01%8E%3E%9Fg%F8%D8%CF%F0C%9E%E1%8F%3D%08%01%19%40.P%10I%0D%00%8C%AA%1B%19%A3%7D%C5%A0%00%00%00%00IEND%AEB%60%82",
    'download' : "data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%01%03%00%00%00%25%3Dm%22%00%00%00%03sBIT%08%08%08%DB%E1O%E0%00%00%00%06PLTE%FF%FF%FF%FF%FF%FFU%7C%F5l%00%00%00%02tRNS%FF%00%E5%B70J%00%00%00%09pHYs%00%00%0B%12%00%00%0B%12%01%D2%DD~%FC%00%00%00!tEXtSoftware%00Macromedia%20Fireworks%204.0%EA%26'u%00%00%00%16tEXtCreation%20Time%0006%2F02%2F06%3Eg%BF%E4%00%00%00'IDATx%9Cc%F8%FF%9F%01%82%FE%D5C%D1%07~%86%1F%F2%0C%7F%EC%19%BE%E53%FC%BE%CF%F0w%3FH%10%A6%0C%00p%88%1A5%81%FD%3F%D0%00%00%00%00IEND%AEB%60%82",
    'arrow'    : "data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%01%03%00%00%00%25%3Dm%22%00%00%00%03sBIT%08%08%08%DB%E1O%E0%00%00%00%06PLTE%FF%FF%FF%FF%FF%FFU%7C%F5l%00%00%00%02tRNS%FF%00%E5%B70J%00%00%00%09pHYs%00%00%0B%12%00%00%0B%12%01%D2%DD~%FC%00%00%00!tEXtSoftware%00Macromedia%20Fireworks%204.0%EA%26'u%00%00%00%16tEXtCreation%20Time%0006%2F02%2F06%3Eg%BF%E4%00%00%00%26IDATx%9Cc%F8%FF%9F%01%8E%3E%F0%83%D0%7F~%86%7F%FC%0C%7F%FC%19~%9Cg%F8x%9E%E1%F3y%06%245%00p%20%1A%9E%26%CAE%0A%00%00%00%00IEND%AEB%60%82",
    'overlay'  : "data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%01%00%00%00%01%01%03%00%00%00%25%DBV%CA%00%00%00%03sBIT%08%08%08%DB%E1O%E0%00%00%00%06PLTE%FF%FF%FF%00%00%00U%C2%D3~%00%00%00%02tRNS%00%BB*%20%A7%3C%00%00%00%09pHYs%00%00%1B%BC%00%00%1B%BC%01%BA%B7%A0%BB%00%00%00!tEXtSoftware%00Macromedia%20Fireworks%204.0%EA%26'u%00%00%00%0AIDATx%9Cch%00%00%00%82%00%81w%CDr%B6%00%00%00%00IEND%AEB%60%82",
    };
    return images[name];
    }
    })();
  • livedoor Reader + YouTube + はてなブックマークで最速動画ウォッチング

    , , ,

    YouTube のタグによる検索結果の feed アイコンを表示する Greasemonkey スクリプト」で述べた通り、YouTube の検索結果による feed を利用できることがわかったので、早速 livedoor Reader に登録してみました。それはそれでまぁいいんだけど、「これはよさげ?」という動画をいちいちタブを開いて観るのめんどくさい!feed のチェックから視聴、はたまた気に入った動画のブックマークまでの全てを、LDR 内で完結させたい!!!という思いがむくむくと湧き起こってきました。
    というわけで、上記要求を満たすのに必要なもののうち、欠けていた LDR 内で YouTube の動画を観られるようにする greasemonkey スクリプトを書いた(詳細は後述)ので、なかなか快適な YouTube ヲチ生活を送れそうです。百聞は一見に如かずというわけで、とりあえずデモンストレーション動画をご覧ください。
    YouTube – Mashup livedoor Reader, YouTube and Hatena::Bookmark
    http://ktr.s101.xrea.com/pg6mxOCCxnM.flv
    つか、初めて YouTube に動画をうpってみたのですが、画質が激しく劣化するんですな。。。↑のプレイヤじゃぁ小さ過ぎて、なにをやってるのかよくわかんないかも。詳しくは、リンク先の YouTube にてご覧ください(それでもなんかばっちい画質になっちゃってるけど……)。
    見ればおおむねわかると思うけど、デモ動画の流れを順を追って説明します。

    1. YouTube で「中川翔子」を検索
    2. 中川翔子の検索結果が表示される
    3. 検索語入力欄の左に feed アイコンが表示されているのが確認できる
    4. feed をブラウザで表示、ブックマークレットにより、その feed を LDR に登録
    5. LDR に画面が遷移
    6. とりあえずデモなので、上で登録した feed だけ表示されるように、条件絞り込み欄に「中川翔子」と入力
    7. YouTube :: Tag // 中川翔子」が表示される
    8. ショートカット “y” キー押下により、ブーンをやっている映像がその場で YouTube のプレイヤーにより表示される
    9. ブーン閉じる
    10. 次のエントリへ移動
    11. 「Brilliant Dream PV (試聴バージョン)」を開く
    12. 気に入ったので、動画を観ながらショートカット “b” キーを押下し、はてなブックマークにぶくまする
    13. PV 閉じる
    14. 終了

    ここでは YouTube の feed を見ている時にその場で動画を観るデモを見せましたが、エントリの URL が YouTube のものでありさえすればいいので、たとえばはてなブックマーク等でブックマークした YouTube 動画等も観ることができます。
    なんか緊張してとちったりしてるところがあって、いまいち速い感じを演出できなかったのですが、まぁなかなか快適です。LDR 内で feed をチェックしながら YouTube のプレイヤを表示、動画を観られるようにする greasemonkey スクリプトは以下からインストールできます。使い方は、フォーカスされているエントリが YouTube の動画である時に、ショートカット “y” キーを押すだけです。どうぞご利用ください。

    追記。
    このスクリプトは「antipop – Update: LDR で最速動画ウォッチング + YouTube Anywhere」で更新されています。そちらのエントリも合せてご覧ください。

    インストール: ldr_youtube_player.user.js

    // ==UserScript==
    // @name          YouTube Player on LDR
    // @namespace     http://antipop.gs/ns/greasemonkey/ldr_youtube_player
    // @include       http://reader.livedoor.com/reader*
    // ==/UserScript==
    (function(){
    var w       = unsafeWindow;
    var _onload = w.onload;
    var onload  = function(){
    with (w) {
    var playerId = 'GM_youtube_player';
    Keybind.add('y', function () {
    if ($('overlay')) {
    hidePlayer();
    }
    else {
    showPlayer();
    }
    });
    function showPlayer () {
    var item = get_active_item(true);
    if (item) {
    var regexp = new RegExp('^http://(?:www\\.)?youtube\\.com/(?:watch)?\\?.*v=([^&]+).*$', 'i');
    if (item.link.match(regexp)) {
    var overlay = $N("div", {id : 'overlay'});
    var player  = createPlayer(RegExp.$1);
    [overlay, player].forEach(function(e){document.body.appendChild(e)});
    centering(player.id, 0, 50);
    }
    }
    }
    function hidePlayer () {
    [playerId, 'overlay'].forEach(function(id){DOM.remove(id);});
    }
    function createPlayer (videoId) {
    var videoSrc = ['http://www.youtube.com/v/', videoId].join('');
    var object = $N('object', {
    id     : playerId,
    width  : 425,
    height : 350,
    style  : {position : 'absolute'}
    });
    var param  = $N('param',  {
    name   : 'movie',
    value  : videoSrc
    });
    var embed  = $N('embed',  {
    width  : 425,
    height : 350,
    type   : 'application/x-shockwave-flash',
    src    : videoSrc
    });
    [param, embed].forEach(function(e){object.appendChild(e);});
    return object;
    }
    }
    };
    w.onload = function(){
    _onload();
    onload();
    };
    })();