ด้วยการเพิ่มขึ้นของแอปโซเชียล เช่น WeChat การแชทด้วยเสียงจึงกลายเป็นฟีเจอร์ที่ต้องมีสำหรับแอปจำนวนมาก ตั้งแต่แอปโซเชียลที่ใช้การแชทด้วยเสียงเป็นฟังก์ชันหลักไปจนถึงแอปอีคอมเมิร์ซที่มีการบริการลูกค้าด้วยเสียงและฟังก์ชันพนักงานเสิร์ฟในร้านค้า แชทกลายเป็นสิ่งที่ขาดไม่ได้
อย่างไรก็ตาม หลายๆ คนรู้สึกว่าเสียงบนเว็บอยู่ไกลจากเรา และสิ่งเหล่านี้เป็นงานของแอปพลิเคชันในท้องถิ่นมากกว่า ที่จริงแล้ว นี่ไม่ใช่กรณี ด้วยการพัฒนาของ Html5 ฟังก์ชันเสียงจึงค่อยๆ กลายเป็นหนึ่งในนั้น ฟังก์ชั่นที่ต้องมีในส่วนหน้า
ทำไมเราควรเรียนรู้เสียง HTML5?1. ข้อกำหนด Html5 กำลังก้าวหน้า และการอัพเดตโทรศัพท์มือถือได้เร่งการอัพเดตระบบปฏิบัติการ ฟังก์ชันเสียงจะกลายเป็นหนึ่งในงานหลักของส่วนหน้าเช่นเดียวกับผืนผ้าใบปัจจุบัน การใช้งานฟรอนต์เอนด์ของการพัฒนาฟังก์ชันเสียงทำได้รวดเร็วยิ่งขึ้นและช่วยประหยัดกำลังคนได้มากขึ้น (ซึ่งหมายถึงการประหยัดเงินสำหรับเจ้านาย และการประหยัดเงินสำหรับเจ้านายคือการทำให้ตัวเองได้รับเงินเดือนเพิ่มขึ้น)
2. แม้ว่าแอปพลิเคชันในเครื่องจะมีฟังก์ชันเสียงแล้วก็ตาม การทำความคุ้นเคยกับข้อผิดพลาดต่างๆ ของการโต้ตอบด้วยเสียงส่วนหน้าจะทำให้เพื่อนร่วมงานของคุณมีความสัมพันธ์ที่กลมกลืนกันมากขึ้น และการทำงานร่วมกันราบรื่นขึ้น แทนที่จะต้องทะเลาะกันเอง
3. การทำความเข้าใจเทคโนโลยีใหม่ ๆ สามารถป้องกันการสัมภาษณ์ได้ และประการที่สอง คุณสามารถคาดการณ์แนวโน้มทางเทคโนโลยีได้ เพื่อที่คุณจะได้ไม่ต้องเรียนรู้ทักษะการฆ่ามังกรมากมายหรือยึดติดกับกฎเกณฑ์ จะเอื้อต่อการรักษาความรู้และความสามารถในการแข่งขันหลักระดับมืออาชีพของคุณไว้มากกว่า ด้านบนของห่วงโซ่อาหาร
4. คนส่วนใหญ่ในส่วนหน้ามีความเข้าใจผิดเกี่ยวกับฟังก์ชันเสียง พวกเขาคิดว่าฟังก์ชันเสียงเป็นเพียงแท็กเสียง HTML5 จริงๆ แล้วมันไม่ง่ายอย่างนั้น
หมึกไม่เยอะ ขอแค่พัฒนาโปรเจ็กต์เล็กๆ แล้วทุกอย่างจะชัดเจนก่อน
คลิปบอร์ด.png
ตรรกะทางธุรกิจนั้นง่ายมาก
มันเหมือนกับวิธี WeChat ของเราทุกประการ เมื่อคุณกดลง คำนั้นจะถูกปล่อยเพื่อสิ้นสุด และเสียงพูดจะถูกบันทึกไว้ อีกฝ่ายในเวลาเดียวกัน
มาทำทีละขั้นตอนกันก่อน เรามาทำหน้า html กันก่อน
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, Initial-scale=1.0> <meta http-equiv=X-UA - เนื้อหาที่เข้ากันได้=ie=edge> <title>เสียง WeChat</title> <link rel=stylesheet href=css/record.css></head><body> <div id=wrap> <header id=header> <div id=left> <i class=material-icons> chevron_left </i> WeChat(184) </div> <div id=mid>Aida·Wang</div > <div id=right> <i class=material-icons> more_horiz </i> </div> </header> <div id=contentWrap> <ul id=chatList> <li class=item_me> <div class=chatContent>ฉันคือคนที่คุณรักมากที่สุดหรือไม่ <span class=bot></span> <span class=top></span> </div> <div class=avatar > <img src=images/ava1.png </div> </li> <li class=item_you> <div class=avatar> <img src=images/ava2.jpg </div> <div class=chatContent>ลุยเลยพี่! (น่องกลิ้ง) <span class=bot></span> <span class=top></span> </div> </li> <li class=item_me> <div class=chatContent>จะไม่พูดอะไรมาก เอาล่ะ โค้ดมาเพียบ... <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1. PNG </div> </li> <li class=item_you> <div class=avatar> <img src=images/ava2.jpg </div> <div class=chatContent>พี่ดาบิน ทำไมพี่เก่งจังล่ะ? ฉันรู้สึกเหมือนมหาสมุทรเมื่อเห็นคุณ<span class=bot></span> <span class=top></span> </div> </li> <li class=item_me> <div class=chatContent>เก่า สาวน้อย หลงรักฉันแล้วเหรอ... <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1.png </div> </li> <li class=item_you> <div class=avatar> <img src=images/ava2.jpg </div> <div class=chatContent>ไม่ ฉัน เมาเรือ ฉันรู้สึกอยากจะอาเจียนเมื่อเห็นคุณ... <span class=bot></span> <span class=top></span> </div> </li> </ul> </div> <ส่วนท้าย id=footer> <div id=keyboard> <i class=material-icons> แป้นพิมพ์ </i> </div> <div id=sayBtn> <span id=sendBtn class=sendBtn>กดเพื่อพูด</span> < /div> <div id=icon><i class=material-icons> รู้สึกพอใจ </i></div> <div id=add><i class=material-icons> add_circle_outline </i></div> </ส่วนท้าย> </div></body></html>
ส่วน CSS,
*{ ระยะขอบ: 0; ช่องว่างภายใน: 0;}ul li{ list-style: none;}html,body{ height: 100%; width: 100%; overflow: Hidden;}body{ background: #ebebeb;}@font -face { ตระกูลแบบอักษร: 'ไอคอนวัสดุ'; url(../css/iconfont/MaterialIcons-Regular.eot); /* สำหรับ IE6-8 */ src: local('Material Icons'), local('MaterialIcons-Regular'), url(../css/ iconfont/MaterialIcons-Regular.woff) รูปแบบ ('woff2') url (../css/iconfont/MaterialIcons-Regular.woff2) รูปแบบ ('woff'), url (../css/iconfont/MaterialIcons-Regular.ttf) รูปแบบ ('truetype'); } .material-icons { ตระกูลแบบอักษร: 'ไอคอนวัสดุ'; 32px; /* ขนาดไอคอนที่ต้องการ */ display: inline-block; /* line-height: 0.01rem; */ text-spaceing: none; ทิศทาง: ltr; /* รองรับเบราว์เซอร์ WebKit ทั้งหมด */ การแสดงผลข้อความ: ปรับให้เหมาะสม; /* รองรับ Firefox. */ -moz-osx-font-smoothing: greyscale; /* รองรับ IE : column; justify-content: space-between; height: 100%;}#header{ ความสูง: 46px; #363539; display: flex; align-items: center; color: #fff; justify-content: space-between; 100px;}#header #right{ จอแสดงผล: flex; align-items: center; width: 100px; justify-content: flex-end;}#header #right i{ padding-right: 6px;}#header #mid{ text-align: center; flex: 1;}#contentWrap{ flex: 1; overflow-y:auto;}.item_me,.item_audio{ จอแสดงผล: ดิ้น; : flex-start; justify-content: flex-end; padding: 8px;}.item_you { จอแสดงผล: flex-start; justify-content:flex-start; padding: 8px;}.avatar{ ความกว้าง: 40px; ความสูง: 40px;}.avatar img{ความกว้าง: 100%;}.item_me .chatContent{ : 1px ทึบ #6fb44d; ขอบขวา: 15px; 5px; ตำแหน่ง: สัมพันธ์;}.chatContent span{width:0; height:0; Font-size:0; overflow:hidden;}.item_me .chatContent span.bot สไตล์: ทึบประประ; เส้นขอบสี: โปร่งใส โปร่งใส โปร่งใส #6fb44d; ขวา: -17px; ด้านบน: 10px;}.item_me .chatContent span.top{ border-width:8px; border-style:solid dashed; border-color:transparent transparent #a0e75a ; ขวา:-10px;} .item_you .chatContent{ padding: 10px; #a0e75a; เส้นขอบ: 1px solid #6fb44d; 15px; border-radius: 5px; ตำแหน่ง: สัมพันธ์กัน;} .item_you .chatContent span.bot{ border-width:8px; border-style:solid dashed; ด้านบน: 10px;} .item_you .chatContent span.top { border-width:8px; border-style:solid เส้นประ; เส้นขอบสี: โปร่งใส # a0e75a โปร่งใส ; ซ้าย: -15px; ด้านบน: 10px;} #footer; การขยาย: 0 4px; : ดิ้น; จัดรายการ: ตรงกลาง; สี: #7f8389; space-around;}#sayBtn{ แสดงผล: ดิ้น; ระยะขอบ: 0 5px; #f4f5f6; border:1px solid #bec2c1; border-radius: 5px; center;}.activeBtn{ จอแสดงผล: บล็อก; ดิ้น: 1; การขยาย: 8px; พื้นหลัง: #c6c7ca; เส้นขอบ: 1px ทึบ #bec2c1; 6px; พื้นหลัง: #fff; เส้นขอบ: 1px ทึบ #999; ขอบขวา: 15px; ตำแหน่ง: ญาติ; ความกว้าง: 120px; ความสูงขั้นต่ำ: 20px;}.item_audio .chatContent span.bot{ border-width:8px; border-style:solid dashed; #999; ขวา:-17px; top:10px;}.item_audio .chatContent span.top{ border-width:8px; border-style:solid dashed; border-color:transparent โปร่งใส โปร่งใส #fff; ด้านบน:10px;} .material-icons_wifi{ ; ขนาดตัวอักษร: 22px;}.redDot{ พื้นหลัง: #f45454; ความกว้างของเส้นขอบ: 50%; 8px; ความสูง: 8px; ขอบขวา: 10px;}ที่นี่ฉันอยากจะพูดถึงประเด็นสำคัญสองประการ:
1.html ส่วน:
เพื่อบันทึกปัญหา ฉันไม่ได้ตัดภาพในระดับพิกเซล เพื่อบันทึกปัญหา ฉันใช้ไอคอน svg โดยตรง
https://material.io/tools/icons/?style=outline
ส่วน 2.css: ใช้รูปแบบดิ้น ฉันแค่อยากจะอธิบายฟังก์ชัน Html5 ดังนั้น flex จึงไม่เขียนวิธีการเขียนที่เข้ากันได้ นอกจากนี้ โปรดใส่ใจกับวิธีการเขียนของส่วนหัวของ App ซึ่งใช้กันทั่วไปมาก
มาพูดถึงส่วนคีย์ js กันดีกว่า
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, Initial-scale=1.0> <meta http-equiv=X-UA - เนื้อหาที่เข้ากันได้=ie=edge> <title>เสียง WeChat</title> <link rel=stylesheet href=css/record.css> <script> document.addEventListener('DOMContentLoaded', function () { var oSendBtn = document.getElementById('sendBtn'); var soundClips = document.querySelector('.sound-clips'); var mediaRecorder; var oChatList = document.getElementById(' chatList'); navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia( // ข้อ จำกัด - เฉพาะเสียงที่จำเป็นสำหรับแอปนี้ { เสียง: จริง }) // โทรกลับสำเร็จ .then(function (สตรีม) { rec(สตรีม); }) // เกิดข้อผิดพลาดในการเรียกกลับ .catch(function (err) { } ); } else { } function rec(stream) { mediaRecorder = new MediaRecorder(stream); oSendBtn.addEventListener('touchstart ', function (ev) { ev.preventDefault(); this.innerHTML = 'ปล่อยเพื่อสิ้นสุด'; this.classList.add('activeBtn'); mediaRecorder.start(); }, false); oSendBtn.addEventListener('touchend', function (ev) { ev.preventDefault(); this.innerHTML = 'กดเพื่อพูด' ; this.classList.remove('activeBtn'); mediaRecorder.stop( }, เท็จ); = ฟังก์ชั่น (e) { var clipContainer = document.createElement('li'); var audio = document.createElement('audio'); clipContainer.classList.add('item_audio'); clipContainer.innerHTML = ` redDot></div> <div class=chatContent> <i class=material-icons วัสดุ-icons_wifi>wifi</i> <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1.png </div>`; audio.setAttribute('การควบคุม' , ''); oChatList.appendChild(clipContainer); var audioURL = window.URL.createObjectURL(e.data); oChatList.addEventListener ('touchstart', ฟังก์ชั่น (ev) { ถ้า (ev.srcElement.parentNode.className! == 'item_audio') return; audio.play (); ev.srcElement.parentNode.removeChild (ev.srcElement.parentNode .children[0]) }, false); } }, false); id=wrap> <header id=header> <div id=left> <i class=material-icons> chevron_left </i> WeChat(184) </div> <div id=mid>Aida·Wang</div > <div id=right> <i class=material-icons> more_horiz </i> </div> </header> <div id=contentWrap> <ul id=chatList> <li class=item_me> <div class=chatContent>ฉันคือคนที่คุณรักมากที่สุดหรือไม่ <span class=bot></span> <span class=top></span> </div> <div class=avatar > <img src=images/ava1.png </div> </li> <li class=item_you> <div class=avatar> <img src=images/ava2.jpg </div> <div class=chatContent>ลุยเลยพี่! (น่องกลิ้ง) <span class=bot></span> <span class=top></span> </div> </li> <li class=item_me> <div class=chatContent>จะไม่พูดอะไรมาก เอาล่ะ โค้ดมาเพียบ... <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1. PNG </div> </li> <li class=item_you> <div class=avatar> <img src=images/ava2.jpg </div> <div class=chatContent>พี่ดาบิน ทำไมพี่เก่งจังล่ะ? ฉันรู้สึกเหมือนมหาสมุทรเมื่อเห็นคุณ<span class=bot></span> <span class=top></span> </div> </li> <li class=item_me> <div class=chatContent>เก่า สาวน้อย หลงรักฉันแล้วเหรอ... <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1.png </div> </li> <li class=item_you> <div class=avatar> <img src=images/ava2.jpg </div> <div class=chatContent>ไม่ ฉัน เมาเรือ ฉันรู้สึกอยากจะอาเจียนเมื่อเห็นคุณ... <span class=bot></span> <span class=top></span> </div> </li> </ul> </div> <ส่วนท้าย id=footer> <div id=keyboard> <i class=material-icons> แป้นพิมพ์ </i> </div> <div id=sayBtn> <span id=sendBtn class=sendBtn>กดเพื่อพูด</span> < /div> <div id=icon><i class=material-icons> รู้สึกพอใจ </i></div> <div id=add><i class=material-icons> add_circle_outline </i></div> </ส่วนท้าย> </div></body></html>
มีหลายประเด็นที่ต้องคำนึงถึงเมื่อใช้ฟังก์ชันบันทึกวิดีโอที่นี่ เรามาพูดถึงทีละประเด็นกันดีกว่า
สิ่งแรกคือ
navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); ถ้า (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia ( { เสียง: จริง }) // โทรกลับสำเร็จ .then(function (stream) { rec(stream); }) // เกิดข้อผิดพลาดในการเรียกกลับ .catch(function (err) { } } else { }
เมื่อคุณดูอินเทอร์เฟซ HTML5 สำหรับการบันทึก คุณจะเห็นสิ่งนี้
Navigator.getUserMedia()
ระวัง นี่เป็นมาตรฐานเก่าและถูกยกเลิกไปแล้ว
navigator.mediaDevices.getUserMedia
ลักษณะเสียงในมัลติมีเดีย HTML5 มีการเปลี่ยนแปลงหลายครั้ง และมันก็ยุ่งมาก บางแท็กยังไม่ได้ถูกนำมาใช้ในเบราว์เซอร์ และพวกเขาก็เหี่ยวเฉาก่อนที่จะเบ่งบาน คุณไม่จำเป็นต้องดูแลและไม่จำเป็นต้องเสียสิ่งนั้นไป เวลา คุณแค่ต้องรู้ว่าฉันพูดอะไร ก็พอแล้ว เพราะคุณรู้ว่าอดีตที่ถูกทอดทิ้งนั้นไม่มีประโยชน์ ถ้าคุณมีเวลา คุณก็สามารถเล่นเกม LOL หรือ King of Glory ได้เช่นกัน (แม้ว่าฉันจะไม่ได้ ไม่เข้าใจความแตกต่างระหว่างสองเกมนี้แต่สองเกมนี้น่าจะสนุก) คือผมไม่เคยเล่นเลยไม่เข้าใจ)
คุณไม่จำเป็นต้องเข้าใจว่ามีอะไรอยู่ข้างใน คุณไม่จำเป็นต้องรู้ว่าอะไรคือคำมั่นสัญญาและกระแสสื่อคืออะไร คุณเพียงแค่ต้องรู้สิ่งนี้
โค้ดด้านบนนี้เทียบเท่ากับการเปิด faucet (หรือกดปุ่มบันทึกของเครื่องบันทึก) จากนั้นเราก็ต้องมีสิ่งจับน้ำไว้เราสามารถใช้หม้อหุงข้าว (หรือเทป ในกรณีเครื่องบันทึก) มาใส่ได้ มันอยู่ใต้ faucet แล้วดูมันเข้าไป ci (หมายถึงการยิงในบ้านเกิดของเรา) รหัสต่อไปนี้
mediaRecorder = new MediaRecorder(stream);
ขั้นตอนต่อไปคือการกดปุ่มและทุกอย่างจะพร้อม เครื่องบันทึกที่เกี่ยวข้องหมายความว่าหลังจากบันทึกแล้ว ให้กดปุ่มเพื่อเล่น อย่างไรก็ตาม เพื่อที่จะเล่นในโปรแกรมของเรา คุณไม่เพียงต้องมีเทปเท่านั้น แต่ยังต้องมีเครื่องบันทึกด้วย . เครื่องบันทึกคือแท็กเสียง หากไม่มีสิ่งใดทำได้ง่าย เราจะสร้างใหม่ ไม่มีวัตถุใดในโลกนี้ที่โปรแกรมเมอร์ไม่กล้าสร้างใหม่ ถ้าวัตถุใหม่อันเดียวไม่พอ ก็มีเพียงสองวัตถุใหม่เท่านั้น โค้ดที่เหลือไม่มีข้อบกพร่องใดๆ เลยนอกจากความน่ากลัว แต่มันแย่มาก
mediaRecorder.ondataavailable = function (e) { var clipContainer = document.createElement('li'); var audio = document.createElement('audio'); clipContainer.classList.add('item_audio'); clipContainer.innerHTML = ` < คลาส div = redDot></div> <div class=chatContent> <i class=material-icons วัสดุ-icons_wifi>wifi</i> <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1.png </ div>`; audio.setAttribute('การควบคุม', ''); oChatList.appendChild(clipContainer); var audioURL = window.URL.createObjectURL (e.data); audio.src = audioURL; oChatList.addEventListener ('touchstart', function (ev) { if (ev.srcElement.parentNode.className!== 'item_audio') กลับ; เสียง เล่น(); ev.srcElement.parentNode.removeChild(ev.srcElement.parentNode.children[0]) }, เท็จ); };
ในความเป็นจริงมันถูกบันทึกและออกอากาศ
โอเค มันง่ายมากใช่ไหม ให้ฉันพูดถึงบางประเด็นเกี่ยวกับโครงการทั้งหมด:
1. การมีโครงสร้างที่เหมาะสมในแผนภาพการตัดเป็นข้อกำหนดเบื้องต้นสำหรับคุณในการทำงานต่างๆ ในภายหลัง หากโครงสร้างทำได้ดี ก็จะช่วยลดปัญหาในภายหลังได้ . มีสามส่วน.
2. รากฐานที่มั่นคงของ Native js และ ES6 สามารถให้แนวคิดที่แตกต่างแก่คุณได้ ตัวอย่างเช่น ฉันใช้การมอบหมายกิจกรรมและกลไกเทมเพลต ES6 ที่นี่ โดยเฉพาะอย่างยิ่งสำหรับการมอบหมายกิจกรรม การค้นหาโหนดจะเป็นเรื่องยากหากไม่ได้ใช้ นอกจากนี้ หากถูกทำซ้ำจะทำให้โค้ดเสียหายได้ง่าย
3. ความรู้และเทคโนโลยีใหม่ๆ จริงๆ แล้วไม่ซับซ้อน จริงๆ แล้วมันก็ง่ายมาก เพราะผู้ชายตัวใหญ่ๆ ไว้เคราใหญ่ๆ มักจะกังวลว่าเจ้านายจะบอกว่างานของพวกเขายังไม่เพียงพอเมื่อพวกเขาไม่มีอะไรทำ? เทคโนโลยีอยู่ที่นั่นเพื่อแก้ปัญหาและทำให้ชีวิตของเราดีขึ้น
4. โปรเจ็กต์นี้จะไม่ทำงานภายใต้ IOS 11 หรือต่ำกว่า เนื่องจากวิธีการนี้ไม่รองรับก่อน IOS 11.2 และคุณต้องให้นักพัฒนาแอปพลิเคชันท้องถิ่นของ IOS ให้การสนับสนุน แต่ภายใต้ Android ก็สามารถทำได้ และคาดการณ์ได้ว่าในอีกไม่กี่ปีข้างหน้า IOS จะได้รับการสนับสนุนโดยกำเนิดโดยไม่ต้องให้การสนับสนุนแก่คุณ ดังนั้นประสิทธิภาพการพัฒนาของคุณจะสูงขึ้นมาก อย่าคิดว่าเทคโนโลยีเหล่านี้อยู่ห่างไกล HTML5 จะวางจำหน่ายในเชิงพาณิชย์เป็นเวลาประมาณ 15 ปีเท่านั้น (จะต้องใช้เวลากี่ปีจึงจะสามารถใช้ vue, ตอบสนอง และเชิงมุมในวงกว้างได้) ผู้ที่เตรียมพร้อม
ยังมีรายละเอียดและประเด็นอีกมากมายที่ต้องใส่ใจในโครงการทั้งหมด ฉันหวังว่าคุณจะพิมพ์มันออกมาได้ด้วยตัวเองจริงๆ เพราะคุณเข้าใจบทความของฉันและความสามารถของคุณในการใช้เทคโนโลยีนี้เป็นสองสิ่งที่แตกต่างกัน ฉันหวังว่าคุณทุกคนจะไปไกลกว่านี้ ต่อไปบนถนนข้างหน้า (อย่าลืมกลับมาอ่านบ่อยๆ See ^_^)
สรุปข้างต้นคือคำแนะนำของบรรณาธิการเกี่ยวกับการใช้มัลติมีเดีย Html5 เพื่อใช้งานฟังก์ชันเสียง WeChat ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใดๆ โปรดฝากข้อความถึงฉัน แล้วบรรณาธิการจะตอบกลับคุณทันเวลา ฉันอยากจะขอบคุณทุกคนที่ให้การสนับสนุนเว็บไซต์ศิลปะการต่อสู้ VeVb!
หากคุณคิดว่าบทความนี้มีประโยชน์สำหรับคุณ คุณสามารถพิมพ์ซ้ำได้ โปรดระบุแหล่งที่มา ขอขอบคุณ!