【シルクスクリーン】自宅で本格シルクスクリーンをやってみた 〜プリント〜

2014年10月20日

Pocket

silkscreen2

『自宅で本格シルクスクリーンをやってみた 〜版制作〜』に引き続き、今回はシルクスクリーンの本命プリントをしていきます!
今回はシルクスクリーンでポストカードを作ります。
 
 
 

準備物

バインダー(水性インク)
サンカラー
スキージ
プリントしたいもの(ポストカード)
zyunbi4
 
 
 

インクを作る

もともと色付きのバインダーも売っているのですが、お値段が少し高くなるので透明のバインダーに色を付けるインクを混ぜます。
今回使用しているバインダーは田中直染料店で”バインダーCS”と”サンカラー10色セット”を購入しました。”バインダーCS”は一番一般的なインクです。主に白色の物にプリントするときに使用します。黒色や濃い色にプリントした場合は、マットバインダー、又はホワイトバインダーを使用します。
 
プリントするのに必要な分量のバインダー器にとり、そのバインダーにサンカラーを入れ、よく混ぜ合わせます。
インク制作はこれだけです。
 
 

版にインクをのせる

プリントしたいものの上に版を置きます。
今回は、ポストカードにプリントします。
プリントしたい位置に柄を合わせて、柄にかぶらない場所にインクをのせます。
このとき柄部分にのせると、インクが染み込んでしまうかもしれないので、柄の外にのせます!
インクが固い場合は、柄の上にのせても大丈夫です。
今回使用しているバインダーは少し柔らかいので、もし、固めが良い場合はバインダーの粘度を上げる増粘剤が売っているので、増粘剤を使用すると良いです。
ink
 
 

プリントする

インクを置いたところから少し上にスキージを置き、45度くらい手前に傾けます。
そこから、一気に手前までスキージを引きます。
引くスピードがゆっくりだとにじむので素早く引きましょう。
print
版を上げるとプリントされていると思います。
版は何回かプリントできるのですが、できるだけこまめに水で洗ってインクを洗い流してください。
水性インクは、インクが乾きやすいので、インクが付いたまま版を放置しているとインクが固まって目詰まりお引き起こしてしまいます。
 
 

完成

これでオリジナルポストカードの完成です!
他の版も作って2色でやってみました!
postcardpostcard2
 
 
 
けっこう大変でしたけど、家でも本格的なシルクスクリーンを楽しめます!
オリジナルグッズの制作に役立てて頂ければ光栄です。
 
1.自宅で本格シルクスクリーンをやってみた 〜版制作〜

続きを読む

【シルクスクリーン】自宅で本格シルクスクリーンをやってみた 〜版制作〜

2014年10月10日

Pocket

silkscreen

本格的なシルクスクリーンが自宅でできたら良いと思いませんか?
ホームセンターで売ってる物で露光機を作って、オリジナルの版を作ってみました。
シルクスクリーンプリントができれば、オリジナルTシャツやトートバッグ、ポスターなどオリジナルグッズを格安で作れます!
 
 
 

準備物

感光乳剤(SD-04)
バケット
版(紗を張っているもの)
プリントしたい柄を書いたトレーシングペーパー
蛍光灯(露光機)
nyuzaizyunbirokouki
露光機はホームセンターで売っている木で枠を作って、中に蛍光灯を入れてアクリル板を乗せています。
蛍光灯の灯具もホームセンターで売っているコンセントで簡単に付けれる物です。
 
 
 
※今回説明する行程は、全て紫外線の当たらない場所で行ってください!!
だからといって暗闇で作業するのは無理ですよね!
一番良いのは、写真を現像する部屋についてる赤いライトのような光がいいのですが、けっこうお値段しますし、使う機会がなさすぎるのでわざわざ買うのはちょっと・・・だと思うので、代用にLEDのライトでも大丈夫です。
LEDの光は、紫外線が少ないらしいので、100円ショップで売っているLEDライトで照らしながらやってもいいと思います!
 
 

版制作に大事な感光のしくみ

感光液は、紫外線に当たると硬化します。
ですので、露光することによって、紗に塗った感光液を固めています。
柄の部分は黒色で光を通さないので、柄の部分だけ感光液が固まらないので、洗い流すと柄の部分だけ抜け落ちます。
黒で光を通さなければいいので、トレーシングペーパーでなく黒の画用紙とかでも大丈夫ですよ。
このしくみを理解していれば、失敗してもなんとなく失敗の原因がつかめると思います。
もし、柄が抜けない場合は、露光し過ぎ又は露光するまでに紫外線に当たってしまい感光液が硬化してしまっている可能性が高いです。
逆に柄以外のところまで抜け落ちるときは、露光時間が足りなくて感光液が硬化しきっていなかったということがあります。
他にも、失敗の原因は、感光液を分厚く塗りすぎたやしっかり乾燥していなかったということもあります。

 
 
 

1. 感光液を塗る

オススメの乳剤はSD-04です。
この乳剤なら露光時間がアバウトでも割ときれいに柄が抜けるので、自宅でやるようなきちんとした設備が整ってない場合でも使いやすいです。
http://premiumt.jp/item/detail/SD40.html
乳剤をバケットに入れて裏表薄く塗ります。
ポイントは、紗に乳剤がピッタリつくまで、バケットを傾けてから上にスライドさせます。傾けすぎると垂れてしまうので、垂れない程度に。
バケットも買ったら、大きさによりますが安くて1000円はするので、浅いタッパーとかでも代用できます。
nuru
 
 

2. 乾かす

暗所でしっかり乾かします。
このとき、絶対に日光や蛍光灯のような光に当てないでください!!!
完全に乾いてないと失敗の原因になります。
布団乾燥機など使って乾かすと乾きが早くてオススメです!
私は、8時間くらい乾かしています。
kawakita
乾いたらこんな感じの色になります。

 
 

3. 露光する

いよいよ柄を版に焼き付けます。
アクリル版の上に<トレーシングペーパー → 版>の順に置きます。
光が漏れない為にその上に黒い画用紙を置いて一番上に重しを乗せます。
露光機のスイッチを入れます。
この露光機の場合、約10分露光します。
露光機によって露光時間が変わってきます。
この場合は、蛍光灯2本ですが、蛍光灯をもっと増やし光を強くするなら露光時間を減らした方がよいでしょう。
逆に蛍光灯1本の場合は露光時間を長くした方が良いかもしれません。
乳剤と露光機によって露光時間は変動するので、最初は失敗するかもしれません。
今回ご紹介した乳剤は割と露光時間が長めなので、他の乳剤をお使いの方は、その乳剤の露光時間に則り露光してください。
シルクスクリーンの版制作で一番難しいところは露光だと思います。
一度、ピッタリの時間を見つけたら次からは、楽チンなので頑張ってください。
rokou2
rokou

 
 

4. 洗い流す

露光が終わったら、版を洗います。
結構強い水圧で洗い流して大丈夫です。
シャワーの水を最大にして洗い流すのがオススメです。
洗っていると柄の部分が抜けていくと思います。
もし抜けにくいところがあった場合は、歯ブラシやスポンジで少しこすると抜けやすくなります。

 
 

版 完成

これで版は、完成です!
もう紫外線に当てても大丈夫ですよ。
むしろ、版を強くする為に日光に少し当てた方が、版が長持ちします。
han

 
 

次回は作った版でいよいよ印刷します!

2.自宅で本格シルクスクリーンをやってみた 〜版制作〜

続きを読む

【Web Audio API入門】音楽プレイヤー作成 第3弾

2014年9月19日

Pocket

PLANTILLA_FREEPIK

今回は、音楽データを視覚化します。
SoundCloudなど、音楽サイトなんかでよく見かけるアレを作ります。
これを作るとグッとプレイヤー感が上がりますよ。

波形を描画

波形を描画するには、canvasを使います。
なので、まずはhtmlにcanvasタグを記述しましょう。
HTML

<body>
    <p class="botton" onClick="play()">PLAY</p>
    <p class="botton" onClick="stop()">STOP</p>
    <p>Volume</p>
    <input id="volume" type="range" value="50" onChange="volumeChange()">
</body>
<canvas width="650" height="200"></canvas>

 
波形のデータを得るにはgetChannelDataメソッドを使います。
 
JavaScript

xml.onload = function() {
    if (xml.status === 200) {
        //引数を受け取る
        var arrayBuffer = xml.response;
        if (arrayBuffer instanceof ArrayBuffer) {
            var successCallback = function(audioBuffer) {
                //AudioBufferインスタンスを変数へ格納
                buffer = audioBuffer;

                var channelLs = new Float32Array(audioBuffer.length);

                //オーディオデータのチャンネル数が0以上のとき
		if (audioBuffer.numberOfChannels > 0) {
		    //getChannelDataメソッドで波形データ取得
		    channelLs.set(audioBuffer.getChannelData(0));
		}

                //10ミリ秒
                var n10msec = Math.floor(10 * Math.pow(10, -3) * context.sampleRate);

                //canvas
                var canvas = document.querySelector('canvas');
                var canvasContext = canvas.getContext('2d');
                //canvasをクリアにする
                canvasContext.clearRect(0, 0, canvas.width, canvas.height);

                //channelLsの長さだけループ
                for (var i = 0, len = channelLs.length; i < len; i++) {
                    //10ミリ秒ごとに描画
                    if((i % n10msec) === 0){
                        var x = (i / len) * canvas.width;
                        var y = ((1 - channelLs[i]) / 2) * canvas.height;
                        if(i === 0){
                            //canvasの描画初期位置
                            canvasContext.moveTo(x, y);
                        }else{
                            canvasContext.lineTo(x, y);
                        }
                    }
                }
                canvasContext.stroke();
            };

            var errorCallback = function() {
                window.alert('読み込みに失敗しました');
            };
 
            //ArrayBufferデコードする
            context.decodeAudioData(arrayBuffer, successCallback, errorCallback);
 
        }
    }
};

getChannelDataでチャンネルデータを配列で取得します。
その配列の数だけループさせ、10ミリ秒単位のところで、canvasを描画していきます。
1ミリ秒にすればさらに細かい波形になっていきます。
配列に格納されている数値(−1〜1)がY軸になります。
canvasの高さを1として考えます。
Y軸は下へ伸びるので、この波形では真ん中を0にしたいので、1からチャンネルの数値を引いて、
さらに波形は上下に動くので、canvasの高さが1なので割る2をします。
 
こんな感じの波形が描かれています。
スクリーンショット 2014-09-03 16.43.55
 
 

グリッド描画

次は、波形のグリッドを描いていきます。

xml.onload = function() {

    //〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜〜

    //曲の秒数
    soundtime = Math.floor(audioBuffer.length / context.sampleRate);

    //1秒あたりのX軸へ動く数値
    xRate = canvas.width / soundtime;
    for(var i = 0; i < soundtime; i++){
	var x = xRate * i;
	if (i === 0) {
	    canvasContext.moveTo(x, canvas.height);
	} else {
	    if( i % 10 === 0 ){
		//10秒毎にグリッドを描画
		    canvasContext.fillRect(x, 0, 0.5, canvas.height);
	    }
        }
    }
    canvasContext.stroke();

    //〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜〜
}

audioBuffer.lengthで曲の長さを取得できます。
でもそのままだと、値が違うので秒数にわかりやすく秒数にします。
そのためにはsampleRateでaudioBuffer.lengthを割ります。
sampleRateはオーディオの1秒あたりのサンプルフレーム数です。
あとは、秒数分ループさせてグリッドを入れたい秒数で描画していきます。
 
グリッドを足しました。
スクリーンショット 2014-09-03 16.43.29
 
 
 

DEMO

最後にデザインをちょっと入れて自作音楽プレイヤーの完成です。
 
DEMO
 
スクリーンショット 2014-09-03 16.50.57
 
HTML

<!DOCTYPE html>
<html>
<head>
    <!--jQueryを使用する-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<div class="contents">
    <div class="audio_contents">
	<p id="playBotton" class="botton play" onClick="play()">PLAY</p>
	<p class="botton" onClick="stop()">STOP</p>
	<input id="volume" type="range" value="50" onChange="volumeChange()">
    </div>
    <canvas width="650" height="200"></canvas>
</div>
</body>
</html>

 
Javascript

window.AudioContext = window.AudioContext || window.webkitAudioContext || mozAudioContext; 
try {
    var context = new AudioContext();
} catch (error) {
    alert('このブラウザは未対応です');
}

 
var xml = new XMLHttpRequest();
//読み込むデータのURLを書く
xml.open('GET', '音楽ファイル', true);
xml.responseType = 'arraybuffer';
xml.onload = function() {
    if (xml.status === 200) {
        //引数を受け取る
        var arrayBuffer = xml.response;
        if (arrayBuffer instanceof ArrayBuffer) {
            var successCallback = function(audioBuffer) {
                //AudioBufferインスタンスを変数へ格納
                buffer = audioBuffer;

                var channelLs = new Float32Array(audioBuffer.length);

		//オーディオデータのチャンネル数が0以上のとき
		if (audioBuffer.numberOfChannels > 0) {
		    //getChannelDataメソッドで波形データ取得
                    channelLs.set(audioBuffer.getChannelData(0));
		}

		//10ミリ秒
		var n10msec = Math.floor(10 * Math.pow(10, -3) * context.sampleRate);

		var canvas = document.querySelector('canvas');
		var canvasContext = canvas.getContext('2d');
		//canvasをクリアにする
		canvasContext.clearRect(0, 0, canvas.width, canvas.height);

		//描画色設定
		canvasContext.strokeStyle='#50EAFF';
		//channelLsの長さだけループ
		for (var i = 0, len = channelLs.length; i < len; i++) {
		    //10ミリ秒ごとに描画
	            if ((i % n10msec) === 0) {
		        var x = (i / len) * canvas.width;
			var y = ((1 - channelLs[i]) / 2) * (canvas.height - 20) + 20;
			if (i === 0) {
			    //canvasの描画初期位置
			    canvasContext.moveTo(x, y);
			} else {
			    canvasContext.lineTo(x, y);
			}
                    }
		}
		//描画
		canvasContext.stroke();

		//曲の秒数
		soundtime = Math.floor(audioBuffer.length / context.sampleRate);

		//目盛り表示欄
		canvasContext.fillStyle = '#6e6e6e';
		canvasContext.fillRect(0, 0, canvas.width, 20);

		//1秒あたりのX軸へ動く数値
		xRate = canvas.width / soundtime;
		canvasContext.fillStyle = '#eee';
		for(var i = 0; i < soundtime; i++){
		    var x = xRate * i;
	            if (i === 0) {
			canvasContext.moveTo(x, canvas.height);
	       	    } else {
			if( i % 10 === 0 ){
                            //10秒毎にグリッドを描画
			    canvasContext.fillRect(x, 10, 0.5, canvas.height - 10);
			    canvasContext.fillText(i, x-7, 10);
			}else if(i % 2 === 0 ){
			    //2秒毎に目盛りを描画
       			    canvasContext.fillRect(x, 15, 0.3, 5);
			}
		    }
		}
		canvasContext.stroke();

            };
            var errorCallback = function() {
                window.alert('読み込みに失敗しました');
            };
 
            //ArrayBufferデコードする
            context.decodeAudioData(arrayBuffer, successCallback, errorCallback);
 
        }
    }
};
xml.send(null);


//始めからスタートのフラグをたてる
var first_flg = true;   

function play(){

    if($('#playBotton').hasClass('pause')){

        pause();

    }else if($('#playBotton').hasClass('play')){

        //AudioBufferSourceNodeを作成する
        source = context.createBufferSource();
        //bufferプロパティにAudioBufferインスタンスを設定
        source.buffer = buffer;
        //ループ
        source.loop = false; 
        //AudioBufferSourceNodeインスタンスをdestinationプロパティに接続
        source.connect(context.destination);

        //GainNodeを作成する
        gainNode = context.createGain();
        //sourceをGainNodeへ接続する
        source.connect(gainNode);
        //GainNodeをAudioDestinationNodeに接続
        gainNode.connect(context.destination);
        gainNode.gain.value = 4;

        source.start = source.start || source.noteOn;
        source.stop  = source.stop  || source.noteOff;

        //始めからの再生の場合
        if(first_flg){
    	    //スタート時間を変数startTimeに格納
    	    startTime = context.currentTime;
    	    replayTime = startTime;
    	    //停止されている時間を初期は0にしておく
    	    pausingTime = 0;
    	    first_flg = false;
        }else{
    	    //再スタート時間を変数replayTimeに格納
	    replayTime = context.currentTime;
	    //再スタートの時間からpauseした時間を引いて、停止されている時間の合計に足していく
	    pausingTime += replayTime - pauseTime;
        }

        //replayTimeからstartTimeとpausingTime引いた時間が曲のスタート時間
        var playTime = replayTime - startTime - pausingTime;

        //再生
        source.start(0,playTime);

        //クラスとテキスト変更
        $('.play').removeClass('play').addClass('pause').html('PAUSE');
    }
}

 
function pause() {	
    //止めた時間を変数pauseTimeに格納
    pauseTime = context.currentTime;
    source.stop(0);

    //クラスとテキスト変更
    $('.pause').removeClass('pause').addClass('play').html('PLAY');
}


function stop(){
    source.stop();
    first_flg = true;
    //クラスとテキスト変更
    $('.pause').removeClass('pause').addClass('play').html('PLAY');
}


function volumeChange(){
    //range属性のvalue取得
    var value = document.getElementById( "volume" ).value;
    //gainNodeの値に変更
    var volume = ( value / 10 ) - 1;

    //gainNodeに代入
    gainNode.gain.value = volume;
} 

 
CSS

.contents{
	width: 1000px;
	margin: 50px;
}
.audio_contents{
	border-radius: 5px 0 0 5px / 5px 0 0 5px;
	background-color: #ccc;
	float: left;
	height: 150px;
	padding: 25px;
	text-align: center;
	width: 300px;
}
.title{
	font-size: 16px;
	color: #4e4e4e;
}
.botton{
	border-radius: 5px;
	background-color: #4e4e4e;
	cursor: pointer;
	color: #eee;
	font-size: 13px;
	float: left;
	height: 45px;
	line-height: 50px;
	margin: 25px 25px 0;
	text-align: center;
	width: 100px;
}
#volume{
	margin-top: 40px; 
	width: 250px;
}
canvas{
	border-radius: 0 5px 5px 0 / 0 5px 5px 0;
	background-color: #4e4e4e;
}

シンプルではありますが、これを応用していけばかなり充実したプレイヤーが作れそうですね。
入門編は3回で終わりましたが、またいつかWeb Audio API中級編を書きたいと思います。
 
 
 
参考:WEB SOUNDER – Web Audio API 解説 -
 
 
 
【Web Audio API入門】音楽プレイヤー作成 第1弾
【Web Audio API入門】音楽プレイヤー作成 第2弾

続きを読む

【Web Audio API入門】音楽プレイヤー作成 第2弾

2014年9月15日

Pocket

aud0002-009 のコピー

音楽プレイヤー作成 第2弾です!
今回は、一時停止、音量調整機能を実装します。
 

音量調節

inputの属性rangeを使用してボリュームを調節するつまみを作ります。
rangeのValueは0から100までです。真ん中の50に初期値を設定します。
rangeが変更されたらvolumeChange()のファンクションが呼び出されます。
 
HTML

<body>
    <p class="botton" onClick="play()">PLAY</p>
    <p class="botton" onClick="stop()">STOP</p>
    <p>Volume</p>
    <input id="volume" type="range" value="50" onChange="volumeChange()">
</body>

 
音量を調整するにはGainNodeを使用します。
gainNodeのValue属性に音量の値を設定することによって音量を設定できます。
 
JavaScript

function play(){
     //〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜〜

     //GainNodeを作成する
     gainNode = context.createGain();

     //sourceをGainNodeへ接続する
          source.connect(gainNode);

     //GainNodeをAudioDestinationNodeに接続
     gainNode.connect(context.destination);

     //音量を表記
     gainNode.gain.value = 3.0;

     //〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜〜
}

function volumeChange(){
    //range属性のvalue取得
    var value = document.getElementById( "volume" ).value;
    //gainNodeの値に変更
    var volume = ( value / 10 ) - 1;

    //gainNodeに代入
    gainNode.gain.value = volume;
} 

range属性からvalueを取得し、gainNodeのvalueに代入します。
rangeのvalueをそのまま代入すると音がでかすぎるので、valueの値を10分の1にします。
gainNodeのvalueは-1で音がなくなるのでrangeが0のとき、gainNodeが-1になるようにvalueから-1をしています。
 
 

一時停止

再生をストップしたら、AudioBufferSourceNodeが削除されるので、次に再生を押しても始めからのスタートになってしまいます。
一時停止ができないプレイヤーは使い勝手が悪いので、一時停止機能を作っていきます。
 
実はstart()関数には、スタートする時間と、曲のどの位置からスタートするかを入れれるのです。
start(スタート時間,曲のスタートする位置の時間)と表記します。
とは言うものの、その時間は自分で計算しなくてはなりません。
 
少し複雑なコードになってきました。
 
HTML

<body>
    <p id="playBotton" class="botton play" onClick="play()">PLAY</p>
    <p class="botton" onClick="stop()">STOP</p>
    <p>Volume</p>
    <input id="volume" type="range" value="50" onChange="volumeChange()">
</body>

 
JavaScript

//始めからスタートのフラグをたてる
var first_flg = true;

function play(){

    if($('#playBotton').hasClass('pause')){

        pause();

    }else if($('#playBotton').hasClass('play')){

         //〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜〜

         //始めからの再生の場合
        if(first_flg){
    	    //スタート時間を変数startTimeに格納
    	    startTime = context.currentTime;
    	    replayTime = startTime;
    	    //停止されている時間を初期は0にしておく
    	    pausingTime = 0;
    	    first_flg = false;
        }else{
    	    //再スタート時間を変数replayTimeに格納
    	    replayTime = context.currentTime;
    	    //再スタートの時間からpauseした時間を引いて、停止されている時間の合計に足していく
    	    pausingTime += replayTime - pauseTime;
        }

        //replayTimeからstartTimeとpausingTime引いた時間が曲のスタート時間
        var playTime = replayTime - startTime - pausingTime;

        //再生
        source.start(0,playTime);

        //クラスとテキスト変更
        $('.play').removeClass('play').addClass('pause').html('PAUSE');
    }
} 

function pause() {	
    //止めた時間を変数pauseTimeに格納
    pauseTime = context.currentTime;
    source.stop(0);

    //クラスとテキスト変更
    $('.pause').removeClass('pause').addClass('play').html('PLAY');
}

function stop(){
    source.stop();
    //初期値に戻す
    first_flg = true;
    //クラスとテキスト変更
    $('.pause').removeClass('pause').addClass('play').html('PLAY');
}

ここで重要なのがcontext.currentTime属性です。
context.currentTimeはcontextが作成された時点からの時間を取得します。
なので、再生ボタンを押した時間ではありません。
これがややこしいのですが、この時間をもとにスタートした時間やストップした時間を変数などに格納し、足したり引いたりして目的の数値を計算します。
再生ボタンにidをふり、play()が呼び出されたとき、id=”playBotton”がplayのクラスを持っていたら再生をpauseのクラスを持っていたら一時停止するように分岐しています。
 
 
 

DEMO

下記は今回の機能を追加したソースです。
 
DEMO
 
 
HTML

<!DOCTYPE html>
<html>
<head>
    <!--jQueryを使用する-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
    <p id="playBotton" class="botton play" onClick="play()">PLAY</p>
    <p class="botton" onClick="stop()">STOP</p>
    <p>Volume</p>
    <input id="volume" type="range" value="50" onChange="volumeChange()">
</body>
</html>

 
JavaScript

window.AudioContext = window.AudioContext || window.webkitAudioContext || mozAudioContext; 
try {
    var context = new AudioContext();
} catch (error) {
    alert('このブラウザは未対応です');
}

 
var xml = new XMLHttpRequest();
//読み込むデータのURLを書く
xml.open('GET', '音楽ファイル', true);
xml.responseType = 'arraybuffer';
xml.onload = function() {
    if (xml.status === 200) {
        //引数を受け取る
        var arrayBuffer = xml.response;
        if (arrayBuffer instanceof ArrayBuffer) {
            var successCallback = function(audioBuffer) {
                //AudioBufferインスタンスを変数へ格納
                buffer = audioBuffer;
            };
            var errorCallback = function() {
                window.alert('読み込みに失敗しました');
            };
 
            //ArrayBufferデコードする
            context.decodeAudioData(arrayBuffer, successCallback, errorCallback);
 
        }
    }
};
xml.send(null);


//始めからスタートのフラグをたてる
var first_flg = true;   

function play(){

    if($('#playBotton').hasClass('pause')){

        pause();

    }else if($('#playBotton').hasClass('play')){

        //AudioBufferSourceNodeを作成する
        source = context.createBufferSource();
        //bufferプロパティにAudioBufferインスタンスを設定
        source.buffer = buffer;
        //ループ
        source.loop = false; 
        //AudioBufferSourceNodeインスタンスをdestinationプロパティに接続
        source.connect(context.destination);

        //GainNodeを作成する
        gainNode = context.createGain();
        //sourceをGainNodeへ接続する
        source.connect(gainNode);
        //GainNodeをAudioDestinationNodeに接続
        gainNode.connect(context.destination);
        gainNode.gain.value = 4;

        source.start = source.start || source.noteOn;
        source.stop  = source.stop  || source.noteOff;

        //始めからの再生の場合
        if(first_flg){
    	    //スタート時間を変数startTimeに格納
    	    startTime = context.currentTime;
    	    replayTime = startTime;
    	    //停止されている時間を初期は0にしておく
    	    pausingTime = 0;
    	    first_flg = false;
        }else{
    	    //再スタート時間を変数replayTimeに格納
	    replayTime = context.currentTime;
	    //再スタートの時間からpauseした時間を引いて、停止されている時間の合計に足していく
	    pausingTime += replayTime - pauseTime;
        }

        //replayTimeからstartTimeとpausingTime引いた時間が曲のスタート時間
        var playTime = replayTime - startTime - pausingTime;

        //再生
        source.start(0,playTime);

        //クラスとテキスト変更
        $('.play').removeClass('play').addClass('pause').html('PAUSE');
    }
}

 
function pause() {	
    //止めた時間を変数pauseTimeに格納
    pauseTime = context.currentTime;
    source.stop(0);

    //クラスとテキスト変更
    $('.pause').removeClass('pause').addClass('play').html('PLAY');
}


function stop(){
    source.stop();
    first_flg = true;
    //クラスとテキスト変更
    $('.pause').removeClass('pause').addClass('play').html('PLAY');
}


function volumeChange(){
    //range属性のvalue取得
    var value = document.getElementById( "volume" ).value;
    //gainNodeの値に変更
    var volume = ( value / 10 ) - 1;

    //gainNodeに代入
    gainNode.gain.value = volume;
} 

 
 
 
今回はコードの量の割には機能がしょぼい感じがしますが、とりあえずオーディオになってきましたね。
次回は、音楽データの視覚化についてリポートします。
 
 
 
【Web Audio API入門】音楽プレイヤー作成 第1弾
【Web Audio API入門】音楽プレイヤー作成 第3弾

続きを読む

【Web Audio API入門】音楽プレイヤー作成 第1弾

2014年9月2日

Pocket

picjumbo.com_HNCK0644 のコピー

色々な機能を盛り込める今あついWeb Audio APIを使って音楽プレイヤーを自作してみましょう!
Web Audio API入門編は三回に分けて、少しづつ作っていこうと思います。
HTML5から<audio>を使えるので、ただ音楽を再生するならそれを使えば一番簡単なのですが、Web Audio APIではエフェクトをかけたり音楽データを視覚化したり、高度な機能を実装できます。
 
 
今回はとりあえず再生するところまでやってみます。
 
 

AudioContextを作成する

AudioContextは構成ブロックであるAudioNodeの集合やそれらの接続を表すインターフェースでオーディオが入力から出力までの流れを定義します。
まずはAudioContextを作成します。

window.AudioContext = window.AudioContext || window.webkitAudioContext || mozAudioContext; 
	try {
	    var context = new AudioContext();
	} catch (error) {
	    alert('このブラウザは未対応です');
	}

作成に成功したら変数contextにAudioContextを代入しています。
作成に失敗したらアラートを出しています。
 

サウンドをロードする

音楽ファイルをWeb Audio APIへロードするには、XMLHttpRequestを使います。

var xml = new XMLHttpRequest();
//読み込むデータのURLを書く
xml.open('GET', '音楽ファイル', true);
xml.responseType = 'arraybuffer';
xml.onload = function() {
    if (xml.status === 200) {
        //引数を受け取る
        var arrayBuffer = xml.response;
        if (arrayBuffer instanceof ArrayBuffer) {
            var successCallback = function(audioBuffer) {
                //AudioBufferインスタンスを変数へ格納
                buffer = audioBuffer;
            };
            var errorCallback = function() {
                window.alert('読み込みに失敗しました');
            };

            //ArrayBufferデコードする
            context.decodeAudioData(arrayBuffer, successCallback, errorCallback);

        }
    }
};
xml.send(null);

AudioBufferSourceNodeを作成する

//AudioBufferSourceNodeを作成する
source = context.createBufferSource();

//bufferプロパティにAudioBufferインスタンスを設定
source.buffer = buffer;

//ループをオフにする
source.loop = false; 

//AudioBufferSourceNodeインスタンスをAudioDestinationNodeに接続
source.connect(context.destination);

AudioDestinationNode(destination)は音の出口です。
ソースを作成したらAudioDestinationNodeにつないで音が出力できるようにします。
※AudioBufferSourceNodeは使い捨てとなっているので、一度曲をストップするともう一度AudioBufferSourceNodeを作成しなくてはいけないです。
 

サウンドを再生する

//スイッチを入れる
source.start = source.start || source.noteOn;
source.stop  = source.stop  || source.noteOff;

//再生する
source.start(0);

停止するには下記のように表記します。

//停止する
source.stop(0);

 
 
 

DEMO

これらを一連の流れで書いたのが下記のソースです
 
DEMO
 

HTML

<!DOCTYPE html>
<html>
<body>
    <p class="botton" onClick="play()">PLAY</p>
    <p class="botton" onClick="stop()">STOP</p>
</body>
</html>

JavaScript

window.AudioContext = window.AudioContext || window.webkitAudioContext || mozAudioContext; 
try {
    var context = new AudioContext();
} catch (error) {
    alert('このブラウザは未対応です');
}

var xml = new XMLHttpRequest();
//読み込むデータのURLを書く
xml.open('GET', '音楽ファイル', true);
xml.responseType = 'arraybuffer';
xml.onload = function() {
    if (xml.status === 200) {
        //引数を受け取る
        var arrayBuffer = xml.response;
        if (arrayBuffer instanceof ArrayBuffer) {
            var successCallback = function(audioBuffer) {
                //AudioBufferインスタンスを変数へ格納
                buffer = audioBuffer;
            };
            var errorCallback = function() {
                window.alert('読み込みに失敗しました');
            };

            //ArrayBufferデコードする
            context.decodeAudioData(arrayBuffer, successCallback, errorCallback);

        }
    }
};
xml.send(null);

function play(){

    //AudioBufferSourceNodeを作成する
    source = context.createBufferSource();

    //bufferプロパティにAudioBufferインスタンスを設定
    source.buffer = buffer;

    //ループをオフにする
    source.loop = false; 

    //AudioBufferSourceNodeインスタンスをAudioDestinationNodeに接続
    source.connect(context.destination);

    source.start = source.start || source.noteOn;
    source.stop  = source.stop  || source.noteOff;

    //再生
    source.start(0);
}

function stop(){
    source.stop(0);
}

 
 
 
ざっくり再生までの流れをリポートしました。
次回は、一時停止や音量などの機能を付けていきます。
 
 
 
【Web Audio API入門】音楽プレイヤー作成 第2弾
【Web Audio API入門】音楽プレイヤー作成 第3弾

続きを読む

このサイトについて


『意識低い系女と高い系男の一年戦争』はクリエイティブ会社エアゼの代表2人が運営するブログです。エアゼは、アプリ・Web・IoT・インタラクティブコンテンツのデザイン・開発を手がけています。

エアゼ ホームページ