Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Web Musicでは何ができるのか / Web Music latest information
Search
OKUNOKENTARO
November 24, 2018
Technology
2
1.4k
Web Musicでは何ができるのか / Web Music latest information
FRONTEND CONFERENCE 2018の登壇にて使用した資料です。
OKUNOKENTARO
November 24, 2018
Tweet
Share
More Decks by OKUNOKENTARO
See All by OKUNOKENTARO
トレタO/X アーキテクチャ移行記 Next.js App Router化への道のり / TORETA TECH UPDATE 1
okunokentaro
5
11k
Podcastを継続する技術 / refactoradio-240119
okunokentaro
1
190
Webアプリケーション設計の第一歩は ディレクトリの整理から / Encraft 1
okunokentaro
34
10k
JSONとJSON Schemaを改めて理解する / tokyo_study
okunokentaro
9
2.4k
それでもどうしてRecoilを使うのか / Harajuku.ts Meetup Recoil
okunokentaro
19
5.5k
TypeScriptは10年でこんなに進化しました / TechFeed Experts Night 11
okunokentaro
6
1.7k
Hasura.io RDBをサクサク作る方法はARやO/RMだけじゃなくなりました/hasura-io
okunokentaro
5
670
コードには型アノテーションよりも要件アノテーションを増やせ!/harajukuts2
okunokentaro
14
6.4k
10年と3ヶ月でWebサービスを作った話 / Piyogrammer Conference 2021
okunokentaro
2
1.1k
Other Decks in Technology
See All in Technology
ビギナーであり続ける/beginning
ikuodanaka
3
350
20250625 Snowflake Summit 2025活用事例 レポート / Nowcast Snowflake Summit 2025 Case Study Report
kkuv
1
370
Tech-Verse 2025 Keynote
lycorptech_jp
PRO
0
1.4k
AIとともに進化するエンジニアリング / Engineering-Evolving-with-AI_final.pdf
lycorptech_jp
PRO
0
140
2025-06-26_Lightning_Talk_for_Lightning_Talks
_hashimo2
2
110
mrubyと micro-ROSが繋ぐロボットの世界
kishima
2
380
生成AI開発案件におけるClineの業務活用事例とTips
shinya337
0
190
Tech-Verse 2025 Global CTO Session
lycorptech_jp
PRO
0
1.2k
How Community Opened Global Doors
hiroramos4
PRO
1
130
Flutter向けPDFビューア、pdfrxのpdfium WASM対応について
espresso3389
0
100
FOSS4G 2025 KANSAI QGISで点群データをいろいろしてみた
kou_kita
0
280
rubygem開発で鍛える設計力
joker1007
2
270
Featured
See All Featured
Speed Design
sergeychernyshev
32
1k
Making Projects Easy
brettharned
116
6.3k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
How to Think Like a Performance Engineer
csswizardry
24
1.7k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
The Cost Of JavaScript in 2023
addyosmani
51
8.5k
Site-Speed That Sticks
csswizardry
10
670
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
Building Applications with DynamoDB
mza
95
6.5k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
17
950
Bash Introduction
62gerente
614
210k
Transcript
8FC.VTJDͰԿ͕Ͱ͖Δͷ͔ /PW '30/5&/%$0/'&3&/$& !PLVOPLFOUBSP
୭ w Ԟݡଠ!PLVOPLFOUBSP w ΫϨεΣΞද w ΞϓϦέʔγϣϯ ɾ ΤϯδχΞ
ԿΛ͢Δਓ w ԻָۀքͰ੍࡞ελδΦۈ w ઐֶߍͰ%5.Պߨࢣ ʢ.*%*ݕఆڃࢿ֨ॴ࣋ʣ w "OHVMBSΛ༻͍ͨେن։ൃͷઃܭίϯαϧςΟ ϯάͳͲ
w "OHVMBSϢʔβίϛϡχςΟOHLZPUPͷΦʔΨφΠβ w 8FC.VTJDΛѻ͏αʔϏεͷ্ཱͪ͛ͱ։ൃ
w ԻָۀքͰ੍࡞ελδΦۈ w ઐֶߍͰ%5.Պߨࢣ ʢ.*%*ݕఆڃࢿ֨ॴ࣋ʣ w "OHVMBSΛ༻͍ͨେن։ൃͷઃܭίϯαϧςΟ ϯάͳͲ w
"OHVMBSϢʔβίϛϡχςΟOHLZPUPͷΦʔΨφΠβ w 8FC.VTJDΛѻ͏αʔϏεͷ্ཱͪ͛ͱ։ൃ ԿΛ͢Δਓ ࠓ͜͜ͷ͠·ͤΜ
8FC.VTJDͱ
8FC.VTJD w 8FC ʢϒϥβʣ ͰԻΛѻ͏ٕज़શମʹ͍ͭͯͷ௨শ w 8FC.VTJDͱ͍͏໊শͷ༷͕ଘࡏ͢ΔΘ͚Ͱͳ͍ w ओʹɺ ͍͔ͭ͘ͷԻָ
ɾ Իؔ࿈ػثΛѻ͏"1*Λࢦ͢
8FC.VTJDϋοΧιϯ
8FC.VTJDϋοΧιϯ
8FC.VTJDϋοΧιϯ w 8FC.VTJD%FWFMPQFST+1ͱ͍͏։ൃऀίϛϡχςΟ͕ओ࠵ w ෆఆظʹ։࠵ w ".&* ʢҰൠࣾஂ๏ਓԻָిࢠࣄۀڠձʣ ͕ڠࢍ͢Δྫ͋Γ w
8FC.VTJDʹؔ͢Δٕज़Λۦͯ͠࡞Λ։ൃ͢ΔϋοΧιϯ
8FC.VTJDʹؔ͢Δٕज़ w 8FCඪ४ͷओཁͳͷͱ ͯ࣍͠ͷͭ w 8FC"VEJP"1* ʢΣϒΦʔσΟ Φ"1*ʣ w
8FC্ͰԻΛѻ͏ͨΊͷ"1* w 8FC.*%*"1* ʢΣϒϛσΟ"1*ʣ w 8FC্Ͱ.*%*ϓϩ τίϧΛ੍ޚ͢ΔͨΊͷ"1*
8FC.VTJDʹؔ͢Δٕज़ w 8FCඪ४Ͱͳ͍֤ࣾఏڙͷٕज़ͱ ͯ͠ྫ͑ʜ w ϠϚϋגࣜձࣾ70$"-0%6$&3 w ࣗಈ࡞ۂ"1* w גࣜձࣾ/55υίϞEPDPNP%FWFMPQFSTVQQPSU
w Իೝࣝ"1*ɺ Ի߹"1*ͳͲ
ͲΜͳͷ͕࡞ΕΔ ʁ w εϚʔ τσόΠεͷ͖ηϯαʔΛָͬͨثͷ։ൃ w ෳਓ͕ಉ࣌ʹૢ࡞Ͱ͖ΔԻ੍ָ࡞ΞϓϦέʔγϣϯ w ՎࢺΛೖྗͨ͠Βɺ ͦͷՎࢺʹ߹ͬͨۂΛੜͯ͘͠ΕΔπʔϧ
w Իָͱແؔͷ*P5σόΠεΛ.*%*ίϯ τϩʔϥʔͰ੍ޚ
.*%*ίϯ τϩʔϥʔͱ
8FC.*%*"1*
8FC.*%*"1* w 8$ʹͯ8% ʢ࡞ۀߘʣ ͱͳ͍ͬͯΔ"1* w ࣮ϒϥβ$ISPNFͷΈ ʢ݄࣌ʣ w
https://www.w3.org/TR/webmidi/ w 51"$"VEJP8(ʹͯ 'JSFGPY͕ରԠΛද໌ w ෳϒϥβʹΑΔ࣮ࣄྫ͕ੜ·ΕΔͷͰ ࠓޙ$3 ʢקࠂީิʣ ʹਐΉݟࠐΈ
.*%*ͱ w .VTJD*OTUSVNFOU%JHJUBM*OUFSGBDF w ిࢠָثͷԋσʔλΛػثؒͰσδλϧసૹ͢ΔͨΊͷੈքڞ௨ن֨ w ʹ·ͱΊΒΕɺ ʹൃද͞Ε༷ͨ w ϩʔϥϯ
υɺ ϠϚϋɺ ίϧάɺ ΧϫΠͳͲͷຊࠃָثϝʔΧʔΛத৺ʹ ࠃ֎ͷָثϝʔΧʔʹΑͬͯࡦఆ w ָثؒͷ௨৴Ҏ֎ʹɺ ΧϥΦέɺ ίϯαʔ τͷর໌ө૾ػثͷ੍ޚʹ ༻͞ΕΔ
.*%*ͷ࠷৽ࣄ w 5IF.*%*.BOVGBDUVSFST"TTPDJBUJPO .." ݄ɺ .*%*ن֨ͷେ෯Ξοϓσʔ τͷܭըΛൃද w ԼҐޓੑΛ࣋ͨͤͭͭɺ
Α Γݱతʹɺ ؆୯ʹར༻Ͱ͖ΔΑ ͏ͳ༷ʹ w .."ʹָثϝʔΧʔΒʹՃ͑ͯ (PPHMF "QQMFͱ͍ͬͨϒϥβϕϯμʔ "CMFUPO /BUJWF*OTUSVNFOUTͱ͍ͬͨιϑ τΣΞϝʔΧʔՃໍ
w .*%*ن্֨ͰΓ ͱ Γ ͞ΕΔσʔλͰɺ ओʹ.*%*ϝ οηʔδ͕ѻΘΕΔ w .*%*ϝ οηʔδͯ͢όΠ
τྻͰѻΘΕΔ w ϚʔΫΞοϓݴޠ+40/ͷΑ ͏ͳɺ ਓؒʹͱͬͯཧղ͍͢͠σʔλͰͳ͍ w ,CQTγϦΞϧసૹΛ࣮ݱ͢ΔͨΊͷޮԽΛ࠷༏ઌʹͨ͠ܗࣜ .*%*ϝ οηʔδͱ
.*%*ϝ οηʔδ௨৴ͷΈ .*%*ίϯ τϩʔϥʔ γϯηαΠβʔ
ʮυͷԻΛͷڧ͞Ͱ໐Βͯ͘͠Ε ʂ ʯ .*%* ϝ οηʔδ .*%*ϝ οηʔδ௨৴ͷΈ
.*%*ϝ οηʔδ௨৴ͷΈ ʮ0, ʂ ʯ ̇ ʙ
8FC.*%*"1*ͷͭͷ ଓ͞Ε͍ͯΔ.*%*ೖग़ྗͷཧ w ཧతͳػث͚ͩͰͳ͘ɺ ԾతͳσόΠεΛؚΊͯ ͦͷೖग़ྗʹର͢Δɺ .*%*ϝ οηʔδͷૹड৴
w .*%*ҰछͷΠϕϯ τۦಈͳͷͰ .*%*ϝ οηʔδΛड৴ͨ͠ͱ͖ඞָͣ͠ثΛ໐Β͢ඞཁͳ͍ w ͜ΕΛ׆༻ͯ͠.*%*ίϯ τϩʔϥʔͰඇԻָͷ*P5σόΠε੍ޚͰ͖Δ
8FC.*%*"1*ͷ͍ํ
.*%*ೖग़ྗσόΠεͷऔಘ w window.navigator.requestMIDIAccess()Λ͏ w Promise͕ฦ٫͞ΕΔ w ඇಉظղܾޙͷʹ.*%*ೖྗݩͷMapͱ.*%*ग़ྗઌͷMapؚ͕·ΕΔ (async () =>
{ const midi = await window.navigator.requestMIDIAccess(); console.log(midi.inputs); console.log(midi.outputs); })();
.*%*ग़ྗઌσόΠεͷऔಘ w .*%*ϝ οηʔδͷѼઌͱͳΔ.*%*ग़ྗઌσόΠεΛऔಘ͢Δ w outputsϓϩύςΟIterableܕͱͳ͍ͬͯΔ w Array.from(midi.outputs.values())[0]ͱ͢Ε ઌ಄ͷ.*%*ग़ྗઌ͕औಘͰ͖Δ
.*%*ϝ οηʔδΛૹ৴͢Δ w औಘͨ͠.*%*ग़ྗઌʹ.*%*ϝ οηʔδΛૹ৴͢Δʹ send()ϝ ιο υΛ༻͢Δ (async ()
=> { const midi = await window.navigator.requestMIDIAccess(); const output = Array.from(midi.outputs.values())[0]; output.send([0x90, 0x45, 0x7f]); })();
.*%*ϝ οηʔδΛड৴͢Δ (async () => { const midi = await
window.navigator.requestMIDIAccess(); const input = Array.from(midi.inputs.values())[0]; input.onmidimessage = midiEvent => { // do something }; })(); w ϒϥβͰड৴͢Δͱ͖.*%*ೖྗݩʹରͯ͠ input.onmidimessageϋϯ υϥΛ༻͢Δ
w .*%*ϝ οηʔδଟ͘ͷ߹ ϝ οηʔδ͝ͱʹόΠ τ༻͍Δ w 0x90 νϟϯωϧͷԻΛग़ͤ 0x45
ϥͷԻͰ 0x7f ͷڧ͞Ͱ w ৄ͠ ͘ ʰ8FC.*%*"1*Λѻ͏ͨΊͷ.*%*جૅࣝʱ Ͱݕࡧ https://qiita.com/okunokentaro/items/efaeb1124591e84fe9d3 .*%*ϝ οηʔδͷҙຯ
8FC"VEJP"1*
8FC"VEJP"1* w 8$ʹͯ$3 ʢקࠂީิʣ ͱͳ͍ͬͯΔ"1* w Ϟμϯϒϥβͷશ͕࣮ͯ w https://www.w3.org/TR/webaudio/ w
3&$ ʢקࠂʣ ʹ͚ͯͷ࡞ۀ͕ଓ͘
ϒϥβͰԻΛѻ͏ϨΠϠʔ"1* w ࠓޙɺ 8FC35$ 8FC93ͱ͍ͬͨଞͷ"1*ͱ࿈ܞ͠ɺ Իʹؔ͢ΔϨΠϠʔΛ୲͢Δ"1*ʹͳΔݟࠐΈ w 8FC"TTFNCMZ XBTN
ͱ࿈ܞ͢Δ༷ͷࡦఆ༧ఆ ʢਪଌʣ w 6OJUZͳͲͷήʔϜʹ͓͍ͯɺ ϛ υϧΣΞΛհͣ͞ʹ ωΠςΟ ϒ"1*Λ༻Ͱ͖ΔΑ ͏ʹ͢Δɺ ͳͲ w <audio>λάͱͷ༷ࡦఆ໘Ͱͷ࿈ܞෆे w ࠓޙɺ ԻपΓͷػೳ֦ு8FC"VEJP"1*Λલఏʹ͞Εͦ͏ ʢਪଌʣ
ϒϥβͰԻϑΝΠϧΛϩʔ υ͢Δ const reader = new FileReader(); const audioCtx =
new AudioContext(); // Web Audio API reader.onload = async readEvent => { const arrayBuffer = readEvent.target.result; const audio = await audioCtx.decodeAudioData(arrayBuffer); console.log(audio); }; window.addEventListener('drop', dragEvent => { const file = dragEvent.dataTransfer.files[0]; reader.readAsArrayBuffer(file); });
8FC"VEJP"1*ͷΠϯλϑΣʔε w 8FC"VEJP"1*ͰΧςΰϦɺ ͷΠϯλϑΣʔε͕نఆ͞Ε͍ͯΔ ͦͷҰ෦Λհ w OscillatorNode पΛࢦఆͯ͠ܗΛग़ྗɺ γϯηαΠβʔͳͲʹ͏ w
BiquadFilterNode ԻͷՃʹ༻ɺ άϥϑΟ οΫ ɾ ΠίϥΠβͷ։ൃͳͲʹ͏ w PannerNode ۭؒͰͷԻͷৼΔ͍ΛऔΓѻ͏ɺ 8FC93%ήʔϜͳͲͰ༻
"VEJP8PSLMFU w 8FC"VEJP"1*͕ఆٛ͢Δඪ४ͷΠϯλϑΣʔεͷΈ߹ΘͤͰ ࣮ݱࠔͳॲཧʹ͍ͭͯɺ αϯ υσʔλʹΞΫηεͯ͠ԋࢉ͢ΔͨΊͷΈ w ϝΠϯεϨο υͰѻͬͯ͠·
͏ ͱɺ ඳըॲཧΛ݉ͶΔεϨο υͷͨΊ ൃԻʹ͕ى͖Δ w ΦʔσΟ Φ༻ͷεϨο υͰಈ࡞͢ΔAudioWorkletΛ༻͢Δ w ͢ͰʹXBTNͱΈ߹ΘͤΔऀ͕ੈքʹଟ
%FNP http://g200kg.github.io/WebAudioDesigner/
8FC.*%*"1* ͱ 8FC"VEJP"1*
%FNP http://ryoyakawai.github.io/x-webmidi/src/hx_webmidi_01.html https://korilakkuma.github.io/X-Sound/
$44Ͱѻ͏Իͷ֓೦
ʻBVEJPʼཁૉͱͷ࿈ܞ const audioCtx = new AudioContext(); const audioEl = document.querySelector('audio');
const filter = audioCtx.createBiquadFilter(); const mediaSourceNode = audioCtx.createMediaElementSource(audioEl); mediaSourceNode.connect(filter); filter.connect(audioCtx.destination); w createMediaElementSource()Λ͏ ͜ͱͰ <audio>ཁૉͱ࿈ܞͰ͖Δ
4FMFDUPST-FWFMٙࣅΫϥε w 3FTPVSDF4UBUF1TFVEPT w ಈըԻͷ࠶ੜঢ়ଶʹؔ͢ΔٖࣅΫϥεͷ༷ w :playing :paused w 5JNFEJNFOTJPOBM1TFVEPDMBTTFT
w ࣌ܥྻΛѻ͏ٖࣅΫϥεͷ༷ w 8FC755 8FC7JEFP5FYU5SBDLT Ͱͷɺ ಡΈ্͛ಈըࣈນͰͷར༻Λఆ w :current :past :future
8FC.VTJDͷ͜Ε͔Β w 8FC"VEJP"1*ʹΑΔ ήʔϜ8FC93ʹ͓͚Δ#(.ޮՌԻͷදݱɺ 8FC35$ͰͷԻ௨৴ w 8FC.*%*"1*ʹΑΔ ଟ࠼ͳػث੍ޚɺ ԕִૢ࡞ɺ ԋͷಉظ
w ؔ࿈αʔϏεαʔ υύʔςΟ"1*ͱͷ࿈ܞͰ 8FCͰͷԻָ͞Βʹ͓͠Ζ͘ ͳΔ ʂ
·ͣ༡ΜͰΈͯ ͍ͩ͘͞ 5IBOLZPV