WeChat などのソーシャル アプリの台頭により、音声チャットは、音声チャットを主な機能として使用するソーシャル アプリから、音声カスタマー サービスや店舗ウェイター機能を備えた e コマース アプリに至るまで、多くのアプリで必須の機能になりました。チャットは欠かせないものになっています。
しかし、多くの人は Web 側の音声は私たちとは縁遠いものであり、むしろローカル アプリケーションの仕事であると感じています。実際には、そうではありません。HTML5 の開発により、音声機能は徐々にその機能の 1 つになりました。フロントエンドに必須の機能。
なぜ HTML5 音声を学ぶ必要があるのでしょうか?1. HTML5 の仕様は進化しており、携帯電話のアップデートによりオペレーティング システムのアップデートが加速され、音声機能は現在のキャンバスと同様にフロントエンドの主要なタスクの 1 つになります。音声機能開発のフロントエンド実装はより速く、より多くの人的資源を節約します (これは上司のためにお金を節約することを意味し、上司のためにお金を節約することは自分の給料を増やすことになります)
2. ローカル アプリケーションに音声機能が搭載されたとしても、フロントエンドの音声対話のさまざまな落とし穴をよく理解しておくと、同僚同士が争うのではなく、より調和のとれた関係を築き、よりスムーズなコラボレーションを実現できるようになります。
3. 新しいテクノロジーを理解すると、面接を回避できます。第二に、テクノロジーの傾向を予測できるため、ドラゴン退治のスキルを大量に習得したり、ルールに固執したりする必要がなく、知識と専門的なコア競争力を維持するのに役立ちます。食物連鎖の頂点。
4. フロントエンドのほとんどの人は、音声機能について誤解を持っています。彼らは、音声機能が単なる HTML5 の audio タグであると考えています。実際には、それほど単純ではありません。
あまりインクを使わずに、小さなプロジェクトを開発してみましょう。最初にレンダリングを見てみましょう。
クリップボード.png
ビジネスロジックは非常にシンプルで、
これは、WeChat の方法とまったく同じです。押すと単語が放されて終了し、放すと音声が録音されます。同時に相手も。
段階的にやってみましょう。まず、HTML ページを完成させましょう。
<!DOCTYPE html><html lang=ja><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 Voice</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>Old girl 息子よ、あなたは私に恋をしたのですか... <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; パディング: 0;}ul li{ リストスタイル: なし;}html,body{ 高さ: 100%; 幅: 100%; }ボディ{ 背景: #ebebeb;}@font -face { フォントファミリー: 'マテリアルアイコン'; フォントスタイル: 通常; src: url(../css/iconfont/マテリアルアイコン-レギュラー.eot); /* IE6-8 の場合 */ src: local('マテリアルアイコン'), local('マテリアルアイコン-レギュラー'), url(../css/ iconfont/マテリアルアイコン-レギュラー.woff) フォーマット('woff2'), url(../css/iconfont/マテリアルアイコン-レギュラー.woff2) フォーマット('woff'), url(../css/iconfont/マテリアルアイコン-レギュラー.ttf) フォーマット('truetype'); } .material-icons {フォントファミリー: 'マテリアルアイコン'; フォントスタイル: 通常; 32px; /* 推奨されるアイコンのサイズ */ 表示: インラインブロック; /* 行の高さ: 0.01rem; 文字間隔: 通常; direct:ltr; /* すべての WebKit ブラウザのサポート */ -webkit-font-smoothing: /* Safari と Chrome のサポート。 optimizeLegibility; /* Firefox のサポート */ -moz-osx-font-smoothing: greyscale; /* font-feature-settings: 'liga'; flex-direction : 列; コンテンツ間のスペース; 高さ: 100%; 行の高さ: 46 ピクセル; #363539; 表示: 項目を揃える: 色: #fff; 内容を揃える: フォントサイズ: 14 ピクセル; 100px;}#header #right{ 表示: flex; align-items: width: 100px;}#header #right i{パディング右: 6px;}#header #mid{ text-align: center; flex: 1;}#contentWrap{ flex: 1; overflow-y:auto;}.item_me,.item_audio{ 表示: flex; : flex-start; justify-content:flex-end; パディング: 8px;}.item_you{ 表示: flex-start; justify-content:flex-start; パディング: 8px;}.avatar{幅: 40px; 高さ: 40px;}.item_me .chatContent{ パディング: 10px; : 1px ソリッド #6fb44d; マージン右: 15px; 5px; 位置: 相対; }.chatContent スパン{幅: 0; フォントサイズ: 0; 位置: 絶対; }スタイル:実線 破線 境界線の色:透明 透明 #6fb44d; 上:-10px;} .chatContentspan.top{ border-width:8px; border-style:solid 破線 破線; border-color:transparent 透明 #a0e75a; right:-15px; .item_you .chatContent{ パディング: 10px; #a0e75a; 境界線: 1px 実線 #6fb44d; 15px; 境界線の半径: 5px; 位置: 相対; .item_you .chatContent spam.bot{ 境界線の幅: 実線の破線; 境界線の色: 透明 #6fb44d 透明 左:-17px; top:10px;}.item_you .chatContentspan.top{ border-width:8px;破線 破線; 透明 #a0e75a 透明; 左:-15px; } #フッター{ 高さ: 0 4ピクセル; 境界上: 1px 表示: フレックス; 項目を揃える: 色: #7f8389;スペースアラウンド;}#sayBtn{ フレックス: 1; マージン: 0 5px; フォントの太さ: 1 ピクセル; } #f4f5f6; ボーダー: 1px ソリッド #bec2c1; テキスト整列:センター;}.activeBtn{ 表示: ブロック; フレックス: 1; 背景: #c6c7ca; ボーダー半径: 5 ピクセル; }.item_audio .chatContent{ 6px; 背景: #fff; 境界線: 1px 境界線の半径: 5px;マージン右: 15 ピクセル; 位置: 相対; 幅: 120 ピクセル; }.item_audio .chatContent spam.bot{ ボーダー スタイル: 実線 透明 破線; #999; 右:-17px; トップ:10px;}.item_audio .chatContentspan.top{ボーダー幅:8px; ボーダースタイル:実線 破線; ボーダーカラー:透明 透明 #fff; 右:-10px;} .material-icons_wifi{ 変換: 回転(90度); ; フォントサイズ: 22px;}.redDot{ 背景: #f45454; 境界線の半径: 50%; 8px; 高さ: 8px; 右マージン: 10px;}ここで注意点を2つ挙げたいと思います。
1.html部分:
トラブルを避けるために、私は svg アイコンを直接使用しました。
https://material.io/tools/icons/?style=outline
2.CSS部分:フレックスレイアウトを使用します。 Html5の機能を説明したいだけなので、flexでは互換性のある記述方法は書いていません。また、よく使われるAppヘッダ部分の記述方法にも注目してください。
重要な js 部分について話しましょう。
<!DOCTYPE html><html lang=ja><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 Voice</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('チャットリスト'); 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 { } 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.ondataavailable = 関数 (e) { var ClipContainer = document.createElement('li'); var audio = document.createElement('audio'); ClipContainer.classList.add('item_audio'); redDot></div> <div class=chatContent> <i class=material-iconsmaterial-icons_wifi>wifi</i> <span class=bot></span> <span class=top></span> </div> <div class=avatar> <img src=images/ava1.png </div>`; , ''); 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]) }, 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>Old girl 息子よ、あなたは私に恋をしたのですか... <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 のゲームをプレイしたほうがよいでしょう。これだけで十分です。 2 つの違いはわかりませんが、この 2 つのゲームは楽しいはずです)まあ、プレイしたことがないのでわかりません)。
中身を理解する必要はありません。プロミスとは何か、メディア ストリームとは何かを知る必要はありません。
上記のコードは蛇口をひねる(またはレコーダーの録音ボタンを押す)ことと同じですが、その場合は水をキャッチするための炊飯器(またはレコーダーの場合はテープ)を使用する必要があります。それを蛇口の下に置いて、それが入っていくのを見てください。 ci (私たちの故郷で撃つという意味)、次のコード
mediaRecorder = new MediaRecorder(stream);
次のステップは、ボタンを押すことです。対応するレコーダーは、録音後にボタンを押して再生することを意味します。ただし、プログラムで再生するには、テープだけでなくレコーダーも必要です。 . レコーダーはaudioタグですので、簡単なものがない場合は新規作成します。この世界には、プログラマーがあえて新しくしないオブジェクトはありません。新しいオブジェクトが 1 つだけでは不十分な場合、新しいオブジェクトは 2 つだけです。コードの残りの部分には、恐ろしい以外に欠点はなく、単にとんでもないものです。
mediaRecorder.ondataavailable = function (e) { var ClipContainer = document.createElement('li'); var audio = document.createElement('audio'); ClipContainer.classList.add('item_audio'); div class = 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('コントロール', ''); oChatList.appendChild(clipContainer); window.URL.createObjectURL(e.data); audio.src = audioURL; oChatList.addEventListener('touchstart', function (ev) { if (ev.srcElement.parentNode.className!== 'item_audio') return; オーディオ。 play(); ev.srcElement.parentNode.removeChild(ev.srcElement.parentNode.children[0]) },間違い); };
実は録画して放送されているんです。
プロジェクト全体についていくつかの点についてお話しさせてください。
1. 切断図に合理的な構造を持たせることは、後で機能を実行するための前提条件です。構造がうまくできていれば、駆け出しの頃に HTML5 構造を構築した諸葛亮のことを思い出してください。 3 つのセクションがあります。
2. ネイティブ JS と ES6 の強固な基盤により、さまざまなアイデアが得られます。たとえば、ここではイベント委任と ES6 テンプレート エンジンを使用します。特にイベントデリゲーションは使わないとノードを探すのが面倒ですし、繰り返すとコードがめちゃくちゃになりやすくなります。
3. 新しい知識や技術は実際には複雑ではなく、実際には非常に単純です。新しい技術が機能を向上させたり、問題を解決したりするためのものでなければ、なぜ新しい技術を開発する必要があるのでしょうか。ひげを生やした大男たちは、何もすることがないのに上司から「仕事量が足りない」と言われるのを心配しているからでしょうか?テクノロジーは問題を解決し、私たちの生活をより良くするために存在します。
4. このプロジェクトは、IOS 11.2 以前ではサポートされておらず、IOS ローカル アプリケーション開発者がサポートを提供する必要があるため、IOS 11 以下では機能しませんが、Android では問題ありません。また、数年以内に、IOS はサポートを提供しなくてもネイティブにサポートされるようになることが予想されるため、開発効率は大幅に向上します。これらのテクノロジーが商用化されるまであと 15 年かかるとは考えないでください (vue、react、angular が大規模に使用されるようになるには何年かかるでしょうか?)。準備ができている人。
プロジェクト全体にはまだ詳細や注意すべき点がたくさんありますが、私の記事とこのテクノロジーを使用する能力は別のものであることを理解していただければ幸いです。さらにフロントエンドへの道を進んでください (頻繁に戻って読んでください ^_^ を参照してください)。
要約する上記は、Html5 マルチメディアを使用して WeChat 音声機能を実装する方法についての編集者による紹介です。ご質問があれば、メッセージを残してください。編集者がすぐに返信します。また、VeVb武道サイトを応援してくださった皆様、誠にありがとうございました!
この記事が役立つと思われる場合は、転載していただいてかまいませんので、出典を明記してください。ありがとうございます。