26/7/2008

YouTube動画を簡単に1行で貼るスクリプト

※この内容は古くなっており、その後のYouTubeの仕様変更で不要になりました。

ここには似合わないネタなのでボツにしてたんですが、YouTube動画の貼り付け方がよくわからんという身内のために書いたスクリプトがもしかしたら誰かの役に立つかも?ということでコードを載せます。

どんな人のためのもの?

  • サイトやブログにとにかく簡単に一行でYouTube動画を貼りたい人(header内にscriptリンクする必要無し)
  • IEの場合1回クリックしてからでないとFlashオブジェクトが操作を受け付けない問題を回避したい人
  • W3CのHTML Validatorチェックをパスさせないと気が済まないこだわりの人
  • objectタグが使えないTypepadみたいなブログを使っている人
  • Nucleusとか記事中に複数行のjavascriptコード書きにくいCMS使っている人
  • たまにしか貼らない動画のために常にHeader内にAC_RunActiveContent.jsみたいなの置いとくのが何となくイヤだ、というキレイ好きな人

…ストライクゾーン狭いですね、該当しない方は華麗にスルーしてください。あらかじめYouTube機能のある日記系サービスでは普通自前script使えないです。

使い方

1. 後述のコードを例えば youtube.js という名称で保存し、サーバの好きな場所にFTP等で転送*します。
以下の例ではサーバトップの/jvs/というディレクトリ内に置いたと仮定します。

2. 貼り付けたいYouTube動画のページのアドレスの最後、v=以降の文字列をコピー。(赤字の部分)

https://www.youtube.com/watch?v=Kg1FsVeoEUQ

3. それを記事中にこのようにペーストします。

<script type="text/javascript" src="/jvs/youtube.js?v=Kg1FsVeoEUQ"></script>

終了。
こんな感じに表示されます。

オプション

もしブログのカラムが狭い場合とかは、下記のようにwidth,heightを指定できます。

<script type="text/javascript" src="/jvs/youtube.js?v=Kg1FsVeoEUQ&width=360&height=295">

幅360ピクセルだとこんなかんじ。

でもいちいち幅や高さを指定するのは面倒なのでyoutube.jsの41〜42行目の数値を自分のブログに合わせて直接変えちゃうのもありでしょう。
あとwmodeも指定できます。例:&wmode=opaque

高画質版に対応しました。例:&fmt=6 &fmt=18 &fmt=22(HDソースのみ)
高画質版の貼り付け方法について詳しくはこちらをご覧ください。

再生開始秒数指定に対応しました。例:&start=120(120秒のところからスタートしたい場合)
詳しくはこちらをご覧ください。

&autoplay=1 を付けると自動的に再生開始します。

保存してFTPとかよくわかんなかったり自由にファイルを置けるサーバがない場合は下記の1行を貼れば手っ取り早く試すことができます。

WordPressの場合は『ビジュアルエディタ』ではなく『コード』の状態で貼ってくださいね。同じくMovableTypeの場合は『リッチテキスト』以外のフォーマットで。
直リンの場合は、常に存在し続ける保証がないことを一応念頭に置きつつよろしくです。

なぜこんなものを?

以前は簡単にPHPファイルをjavascriptファイルとして使用することで引数を渡していました。でもjavascriptだけで書けば僅かながらサーバの負荷軽減になるだろうということで、javascriptファイルへのリンク部分にクエリストリング付けてPHPでなくjavascriptで処理させたかったんです。
あとよく知られた事ですがYouTubeの提供するコードをそのまま貼ってしまうとHTML Validation Serviceのチェックを通らないというのがあります。
YouTubeもobjectタグだけでなくiframeでコード提供してくれるといいんですが。

行番号付コードと簡単解説

パラメータ出力部分はyoutube.jsでググったら出て来たコードをベースに簡単に手を加えています。
クエリストリングを連想配列化するスクリプトはgroundwalker.comさんの記事を参考にさせていただきました。
下のコードをFirefoxでコピペすると行頭に#や行番号が付いちゃったりするので、コピーしにくい場合はこちらからどうぞ。
追記:高画質モードで貼れるようにパラメータを追加しました。

  1. /*ver:3.2*/
  2. var body=document.getElementsByTagName("body")[0];
  3. var scripts=body.getElementsByTagName("script");
  4.  
  5. for(var i=0; i<scripts.length; i++){
  6.     var query=scripts[i].src;
  7. }
  8.  
  9. var params=getQueryParams();
  10. var v=params.v;
  11. var fmt=params.fmt;
  12. var width=params.width;
  13. var height=params.height;
  14. var wmode=params.wmode;
  15. var start=params.start;
  16. var end=params.end;
  17. var autoplay=params.autoplay;
  18. var fs=params.fs;
  19. var hd=params.hd;
  20.  
  21. if(v) video(v,width,height,wmode,fmt,hd,start,end,fs,autoplay);
  22.  
  23. function getQueryParams(){
  24.     var qs=query.slice(query.indexOf("?"));
  25.     if(qs){
  26.         var qsa=qs.substring(1).split('&');
  27.         var params={};
  28.         for(var i=0; i<qsa.length; i++){
  29.             var pair=qsa[i].split('=');
  30.             if(pair[0]){
  31.                 params[pair[0]]=/*decodeURIComponent*/(pair[1]);
  32.             }
  33.         }
  34.         return params;
  35.     }
  36.     return null;
  37. }
  38.  
  39. function video(id,width,height,wmode,fmt,hd,start,end,fs,autoplay){
  40.     if(!id.match(/^[a-zA-Z0-9_\-]+$/)){
  41.         alert('Your query string may be incorrect. https://www.youtube.com/v/'+id);
  42.         return;
  43.     }
  44.     if(!wmode) wmode='transparent';
  45.     if(hd==1 && !width && !height){width=853;height=505;}
  46.     if(!width) width=0; else width=parseInt(width);
  47.     if(!height) height=0; else height=parseInt(height);
  48.     if(width<=0 || width>1280) width=425;
  49.     if(height<=0 || height>745) height=344;
  50.     if(start) id += '&start='+parseInt(start); else if(fmt){
  51.         id += '&ap=%2526fmt%3D'+fmt;
  52.         id += '&fs=1';
  53.     }
  54.     if(hd){
  55.         id += '&hd='+parseInt(hd);
  56.         id += '&fs=1';
  57.     }
  58.     if(end) id += '&end='+parseInt(end);
  59.     if(autoplay==1) id += '&autoplay='+autoplay;
  60.     var html = '<object width="'
  61.         + width
  62.         + '" height="'
  63.         + height
  64.         + '"><param name="wmode" value="'
  65.         + wmode
  66.         + '"><param name="movie" value="https://www.youtube.com/v/'
  67.         + id
  68.         + '"></param><param name="allowFullScreen" value="true"><embed src="https://www.youtube.com/v/'
  69.         + id
  70.         + '" type="application/x-shockwave-flash" allowfullscreen="true" width="'
  71.         + width
  72.         + '" height="'
  73.         + height
  74.         + '" wmode="'
  75.         + wmode
  76.         + '"></embed></object>';
  77.     document.write(html);
  78. }

2,3行目でbodyタグ内のscript要素を取得して、URLアドレスからではなくscriptタグのquery stringを取得できるようにしています。

31行目のdecodeURIComponentは今回の目的には必要ないのでコメントアウトしています。この処理を省くことで古いMac版IE5でも動作しますが、さすがにもう使ってませんよね??
ブログがきちんと表示できないブラウザは対象外ということで。

41行目の引数の文字列に使用不可な文字が入っていた場合のアラート英作文はテキトー(汗)ですので好きに変えてください。ちなみに日本語のアラートももちろん出せますが、ブログとスクリプトの文字コードが違う場合にはscriptタグ内での文字コード指定が必要なのをお忘れなく。
例:<script type="text/javascript" src="/jvs/youtube.js?v=Kg1FsVeoEUQ" charset="euc-jp"></script>
アラートは一切出さない、というのもありですね。

44行目 wmodeのデフォルトがtransparentなのは当サイトの都合です。レイヤーの重なりがなければパフォーマンスを追求してwindowやopaqueをデフォルトにしてもいいでしょう。

48,49行目でそれぞれ幅・高さの最大サイズ(左)と何も指定しなかった場合のサイズ(右)を決めています。自分のブログに合わせてあらかじめ小さいサイズにしたり、最大サイズを640×505(縦480ピクセル+メニューの高さ25ピクセル)とかにしてみるのも面白いかも。

19,21,39,45,54〜57行目 HD対応で追加した部分です。

ある意味きわどいこのやり方が期待通りに動くのは20行目の最初の5文字 if(v) があるからです。
もちろん1ページ中に他のスクリプトがあったり異なる複数の動画を読み込んでも問題ないですが、何か不具合があった場合や、もっと良い書き方あるよ!とか教えていただけたら嬉しいです。


Comments (0) Filed under: tips Tags: , , , — Kyo ICHIDA @ 10:45 PM