WeChat과 같은 소셜 앱의 등장으로 음성 채팅을 주요 기능으로 사용하는 소셜 앱부터 음성 고객 서비스 및 매장 웨이터 Voice 기능을 갖춘 전자상거래 앱에 이르기까지 음성 채팅은 많은 앱의 필수 기능이 되었습니다. 채팅은 필수가 되었습니다.
그러나 많은 사람들은 웹 측 음성이 우리와 거리가 멀다고 느끼고 있으며 이는 로컬 애플리케이션의 작업에 더 가깝습니다. 실제로 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> 위챗(184) </div> <div id=mid>아이다·왕</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>Old 여자 아들아, 나랑 사랑에 빠졌니... <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> </footer> </div></body></html>
CSS 부분,
*{ 여백: 0; ul li{ 목록 스타일: 없음;}html,body{ 높이: 100% 너비: 100%; 오버플로: 숨겨진;}body{ 배경: #ebebeb;}@font -face { 글꼴 계열: '재료 아이콘'; 글꼴 스타일: 일반; src: url(../css/iconfont/MaterialIcons-Regular.eot); /* IE6-8의 경우 */ src: 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-spacing: Normal; 방향: ltr; /* 모든 WebKit 브라우저 지원 */ -webkit-font-smoothing: antialiased */ 텍스트 렌더링: /* Firefox 지원 */ -moz-osx-font-smoothing: greyscale; /* IE 지원 */font-feature-settings: 'liga'; : 열; 정당화-내용: 간격: 100%;}#header{ 높이: 46px; #363539; 디스플레이: flex-items: center; 색상: #fff; space-between;}#header #left{ 디스플레이: flex-items: 14px; 100px;}#header #right{ 디스플레이: flex; align-items: center; 너비: 100px: flex-end;}#header #right i{ 패딩 오른쪽: 6px;}#header #mid{ text-align: flex: 1;}#contentWrap{ flex: 1; Overflow-y:auto;}.item_me,.item_audio{ 디스플레이: flex-items; : flex-start; justify-content:flex-end; 패딩: 8px;}.item_you{ 디스플레이: align-items: flex-start; justify-content:flex-start; 패딩: 8px;}.avatar{ 너비: 40px; 높이: 40px;}.avatar img{폭: 100%;}.item_me .chatContent{ 패딩: 10px; : 1px 솔리드 #6fb44d; 오른쪽 여백: 15px; 5px; 위치: 상대;}.chatContent 범위{너비:0; 글꼴 크기:0; 위치:절대값;}.item_me .chatContent 범위.bot{ 테두리-너비:8px; 스타일:실선 점선; 테두리 색상: 투명 투명 투명 #6fb44d 오른쪽:-17px;}.item_me .chatContentspan.top{ border-width:8px; border-style:solid dashed dashed; border-color:transparent transparent #a0e75a; top:10px;} .item_you .chatContent{ 패딩: 10px; #a0e75a; 테두리: 1px 솔리드 #6fb44d; 왼쪽 여백: 15px; border-radius: 5px; position:relative;} .item_you .chatContentspan.bot{ border-style:solid dashed dashed; 투명 #6fb44d 투명 왼쪽:-17px; top:10px;}.item_you .chatContent span.top{ border-width:8px; 점선 점선:투명 #a0e75a 투명 투명 ; 왼쪽:-15px; 상단: 10px;} #footer{ 높이: 46px; 배경: #f4f5f6; 테두리 상단: 1px : 플렉스; 항목 정렬: 색상: #7f8389; space-around;}#sayBtn{ 플렉스: 1; 디스플레이: 플렉스; 색상:#565656; 글꼴-가중치: }.sendBtn{ 디스플레이: 블록: 8px; #f4f5f6; 테두리:1px 솔리드 #bec2c1; 테두리 반경: 5px; 센터;}.activeBtn{ 디스플레이: 블록; 플렉스: 8px; 배경: 1px 솔리드 #bec2c1; 텍스트 정렬: 센터;}.item_audio .chatContent 6px, 배경: #fff; 테두리: 1px 테두리 반경: 5px; margin-right: 15px; 위치: 상대; 너비: 120px; 최소 높이: 20px;}.item_audio .chatContentspan.bot{ border-width:8px; border-style:solid dashed dashed; #999; 오른쪽:-17px; 상단:10px;}.item_audio .chatContent 스팬.top{ border-width:8px; border-style:solid dashed dashed; border-color:transparent 투명 투명 #fff; top:10px;} .material-icons_wifi{ 변환: 회전(90deg); ; 글꼴 크기: 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( // 제약 조건 - 이 앱에는 오디오만 필요함 { audio: true }) // 성공 콜백 .then(함수 (stream) { rec(stream); }) // 오류 콜백 .catch(function (err) { } ); } else { } function rec(stream) { mediaRecorder = new MediaRecorder(stream); ', 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() }, false); = function (e) { varclipContainer = document.createElement('li'); var audio = document.createElement('audio');clipContainer.classList.add('item_audio'); redDot></div> <div class=chatContent> <i class=material-icons Material-icons_wifi>wifi</i> <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1.png </div>`; audio.setAttribute('controls' , ''); oChatList.appendChild(clipContainer); var audioURL = window.URL.createObjectURL(e.data); oChatList.addEventListener('touchstart', function (ev) { if (ev.srcElement.parentNode.className!== 'item_audio') return; audio.play(); ev.srcElement.parentNode.removeChild(ev.srcElement.parentNode .children[0]) }, 거짓); } }, 거짓) </script></head><body> <div id=wrap> <header id=header> <div id=left> <i class=material-icons> chevron_left </i> 위챗(184) </div> <div id=mid>아이다·왕</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>Old 여자 아들아, 나랑 사랑에 빠졌니... <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> </footer> </div></body></html>
여기서는 영상녹화 기능을 구현할 때 주의할 점이 많습니다.
가장 먼저,
navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia( { audio: true }) // 성공 콜백 .then(function (stream) { rec(stream); }) // 오류 콜백 .catch(function (err) { } ) } else { }
녹화를 위한 일부 HTML5 인터페이스를 보면 다음과 같은 내용이 표시됩니다.
Navigator.getUserMedia()
주의하세요. 이것은 오래된 표준이며 새로운 표준입니다.
navigator.mediaDevices.getUserMedia
HTML5 멀티미디어의 음성 측면은 여러 번 변경되었으며 매우 지저분합니다. 일부 태그는 브라우저에 구현되지도 않았으며 꽃이 피기 전에 시들었습니다. 시간이 있으면 내가 말하는 것을 알면 충분합니다. 버려진 과거는 쓸모가 없다는 것을 알고 있기 때문에 LOL이나 King of Glory 게임을 하는 것이 좋습니다. 둘의 차이점을 잘 모르겠는데, 이 두 게임은 재미있을 것 같아요) 글쎄요, 한 번도 해본 적이 없어서 이해가 안 돼요.
그 안에 무엇이 있는지 이해할 필요는 없습니다. 약속이 무엇인지, 미디어 스트림이 무엇인지 알 필요는 없습니다.
위의 코드는 수도꼭지를 켜는 것과 같습니다(또는 녹음기의 녹음 버튼을 누르는 것). 그러면 밥솥(녹음기의 경우 테이프)을 사용하여 물을 받을 수 있습니다. 수도꼭지 아래에 넣고 들어가는 것을 지켜보세요. ci(고향에서 촬영한다는 의미), 다음 코드
mediaRecorder = new MediaRecorder(stream);
다음 단계는 버튼을 누르면 모든 것이 준비됩니다. 해당 레코더는 녹음 후 버튼을 눌러 재생한다는 것을 의미합니다. 그러나 우리 프로그램에서 재생하려면 테이프뿐만 아니라 레코더도 있어야 합니다. .녹음기는 오디오 태그입니다.쉽게 할 수 없는 경우 새로 만듭니다. 이 세상에 프로그래머가 감히 새롭지 않은 개체는 없습니다. 하나의 새로운 개체로 충분하지 않으면 새로운 개체는 두 개뿐입니다. 나머지 코드에는 무서운 것 외에는 단점이 없으며 단순히 터무니없습니다.
mediaRecorder.ondataavailable = function (e) { varclipContainer = document.createElement('li'); var audio = document.createElement('audio');clipContainer.classList.add('item_audio'); div 클래스 = redDot></div> <div class=chatContent> <i class=material-icons Material-icons_wifi>wifi</i> <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1.png </div> div>`; audio.setAttribute('controls', ''); oChatList.appendChild(clipContainer); window.URL.createObjectURL(e.data); audio.src = audioURL; oChatList.addEventListener('touchstart', function (ev) { if (ev.srcElement.parentNode.className!== 'item_audio') return; 오디오. 플레이(); ev.srcElement.parentNode.removeChild(ev.srcElement.parentNode.children[0]) }, 거짓); };
실제로는 녹화되어 방송되기도 합니다.
좋습니다. 매우 간단합니까? 전체 프로젝트에 대한 몇 가지 사항에 대해 이야기하겠습니다.
1. 절단 다이어그램에 합리적인 구조를 갖는 것은 나중에 기능을 수행하기 위한 전제 조건입니다. 구조가 잘 완성되면 나중에 문제가 발생하지 않을 것입니다. 그가 아직 초보이기 전에 HTML5 구조를 구축한 Zhuge Liang에 대해 생각해 보십시오. 세 개의 섹션이 있습니다.
2. 기본 js와 ES6의 탄탄한 기반은 다양한 아이디어를 제공할 수 있습니다. 예를 들어 여기서는 이벤트 위임과 ES6 템플릿 엔진을 사용합니다. 특히 이벤트 위임의 경우 사용하지 않으면 노드를 찾는 것이 번거로울 뿐만 아니라, 반복되면 코드가 엉망이 되기 쉽습니다.
3. 새로운 지식과 기술은 실제로는 복잡하지 않습니다. 사실, 새로운 기술이 기능을 향상시키고 문제를 해결하는 것이 아니라면 왜 새로운 기술을 개발해야 할까요? 턱수염이 큰 덩치 큰 남자들은 할 일이 없는데 업무량이 부족하다는 상사의 말을 걱정하기 때문일까요? 기술은 문제를 해결하고 우리의 삶을 더 좋게 만들기 위해 존재합니다.
4. 이 프로젝트는 IOS 11 이하에서는 작동하지 않습니다. 왜냐하면 이 방법은 IOS 11.2 이전에는 지원되지 않으며 지원을 제공하려면 IOS 로컬 애플리케이션 개발자가 필요하지만 Android에서는 괜찮습니다. 그리고 몇 년 안에 IOS는 지원을 제공하지 않고 기본적으로 지원될 것이므로 개발 효율성이 훨씬 높아질 것으로 예상됩니다. 이러한 기술이 멀리 있다고 생각하지 마십시오. HTML5는 약 15년 동안만 상용화될 것입니다(vue, React 및 Angle이 대규모로 사용되려면 몇 년이 걸릴까요?). 준비된 자.
전체 프로젝트에는 아직 주의해야 할 세부 사항과 사항이 많이 있습니다. 제 기사를 이해하는 것과 이 기술을 사용하는 능력은 서로 다르기 때문에 직접 입력해 보시길 바랍니다. 프런트 엔드로 향하는 길에서 더 나아가세요(자주 돌아와서 읽어보세요 ^_^ 참조).
요약위는 HTML5 멀티미디어를 사용하여 WeChat 음성 기능을 구현하는 방법에 대한 편집자의 소개입니다. 질문이 있는 경우 메시지를 남겨주시면 편집자가 제 시간에 답변해 드리겠습니다. 또한 VeVb 무술 웹사이트를 지원해 주신 모든 분들께 감사드립니다!
이 글이 도움이 되셨다면 재인쇄하셔도 좋고, 출처를 밝혀주시면 감사하겠습니다!