كان أحد المشاريع منذ بعض الوقت هو تطوير برامج تعليمية صوتية. في الأساس، بعد استيراد المستندات والصور والموارد الأخرى، تصبح الصفحة تخطيطًا يشبه PPT، ومن ثم يمكن تحديد صورة لإدراج الصوت. هناك نوعان من تحرير الصفحة الواحدة ونموذج التحرير العالمي. هناك طريقتان لاستيراد الصوت، إحداهما هي الاستيراد من مكتبة الموارد، والأخرى هي ذكر التسجيل.
لأكون صادقًا، لم أتعرض مطلقًا لواجهة برمجة التطبيقات الصوتية لـ HTML5 في البداية، وعلينا تحسينها بناءً على الكود قبل تولينا المسؤولية. بالطبع، هناك أيضًا العديد من المخاطر المتضمنة هذه المرة، سأتحدث أيضًا عن مشاعري حول هذه المخاطر (سيتم حذف التهيئة والحصول على بعض الكائنات الأساسية لأن هذه المحتويات ليست محور التركيز هذه المرة. يمكن للطلاب المهتمين البحث في MDN). التوثيق بأنفسهم):
قبل بدء التسجيل، يجب عليك أولاً معرفة ما إذا كان الجهاز الحالي يدعم Audio API أم لا. تم استبدال الطريقة السابقة navigator.getUserMedia بالأسلوب navigator.mediaDevices.getUserMedia. عادةً، تدعم معظم المتصفحات الحديثة استخدام navigator.mediaDevices.getUserMedia بالطبع، توفر MDN أيضًا معلومات التوافق.
const promisifiedOldGUM = function(constraints) { // احصل أولاً على getUserMedia، إذا كان موجودًا const getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||. navigator.mozGetUserMedia; مع وجود خطأ // للحفاظ على واجهة متسقة if (!getUserMedia) { return Promise.reject( new Error('getUserMedia لم يتم تنفيذه في هذا المتصفح') } // بخلاف ذلك، قم بلف المكالمة إلى navigator.getUserMedia القديم بوعد return new Promise(function(resolve,reject) { getUserMedia.call (navigator,strictions,resolve,reject });}; // قد لا تقوم المتصفحات القديمة بتنفيذ أجهزة الوسائط على الإطلاق، لذلك قمنا بتعيين كائن فارغ firstif (navigator.mediaDevices === undefice) { navigator.mediaDevices = {};} // تقوم بعض المتصفحات بتنفيذ mediaDevices جزئيًا. لا يمكننا فقط تعيين كائن // باستخدام getUserMedia لأنه سيحل محل الخصائص الموجودة.// هنا، نحن سيضيف فقط خاصية getUserMedia إذا كانت مفقودة.if (navigator.mediaDevices.getUserMedia === uncategorized) { navigator.mediaDevices.getUserMedia = promisifiedOldGUM;}
نظرًا لأن هذه الطريقة غير متزامنة، يمكننا تقديم مطالبات سهلة للأجهزة غير المتوافقة.
navigator.mediaDevices.getUserMedia(constraints).then( function(mediaStream) { // Success }, function(error) { // فشل const { name } = error; Let errorMessage; Switch (name) { // المستخدم يرفض الحالة ' NotAllowedError': case 'PermissionDeniedError': errorMessage = 'لقد منع المستخدم صفحة الويب من الاتصال بجهاز التسجيل'; // جهاز التسجيل غير متصل case 'NotFoundError': case 'DevicesNotFoundError': errorMessage = 'لم يتم العثور على جهاز التسجيل'؛ استراحة؛ // حالات الخطأ الأخرى 'NotSupportedError': errorMessage = 'وظيفة التسجيل غير مدعومة'؛ سجل (خطأ } إرجاع رسالة الخطأ });
إذا سارت الأمور على ما يرام، يمكننا الانتقال إلى الخطوة التالية.
(تم حذف طريقة الحصول على السياق هنا، لأنها ليست محور التركيز هذه المرة)
بدء التسجيل، إيقاف التسجيل مؤقتًاهناك نقطة خاصة هنا، وهي أنه يجب إضافة متغير وسيط لتحديد ما إذا كان التسجيل قيد التنفيذ حاليًا. لأنه في متصفح Firefox وجدنا مشكلة، وكانت عملية التسجيل طبيعية، ولكن عندما نقرنا على الإيقاف المؤقت، وجدنا أنه لا يمكن إيقافه مؤقتًا، واستخدمنا طريقة قطع الاتصال في ذلك الوقت. هذه الطريقة غير ممكنة تتطلب هذه الطريقة قطع كافة الاتصالات. اكتشفت لاحقًا أنه يجب إضافة متغير وسيط this.isRecording لتحديد ما إذا كان التسجيل يتم حاليًا أم لا. عند النقر على البداية، اضبطه على صواب، وعند الإيقاف المؤقت، اضبطه على خطأ.
عندما نبدأ التسجيل، سيكون هناك حدث استماع للتسجيل في العملية الصوتية. إذا تم إرجاع صحيح، فسيتم كتابة الدفق. إذا تم إرجاع خطأ، فلن تتم كتابته. لذلك، احكم على this.isRecording، وإذا كان خاطئًا، فارجع مباشرة
// بعض التهيئة const audioContext = new AudioContext(); const sourceNode = audioContext.createMediaStreamSource(mediaStream); const scriptNode = audioContext.createScriptProcessor( BUFFER_SIZE, INPUT_CHANNELS_NUM, OUPUT_CHANNELS_NUM);sourceNode.connect(this.scriptNode);scriptNode.connect(this.audioContext.destination); // مراقبة عملية التسجيل scriptNode.onaudioprocess = events => { if (!this.isRecording) return; التسجيل المنتظم this.buffers.push(event.inputBuffer.getChannelData(0)); // احصل على بيانات القناة الحالية واكتبها في المصفوفة};
بالطبع، سيكون هناك مأزق هنا، وهو أنه لم يعد من الممكن استخدامه لأنه يأتي مع طريقة للحصول على مدة التسجيل الحالية، لأنه ليس في الواقع توقفًا حقيقيًا، ولكن الدفق غير مكتوب. لذلك نحتاج أيضًا إلى الحصول على مدة التسجيل الحالي، والتي يجب الحصول عليها من خلال صيغة.
const getDuration = () => { return (4096 * this.buffers.length) / this.audioContext.sampleRate // 4096 هو طول الدفق، وsampleRate هو معدل أخذ العينات}
بهذه الطريقة يمكنك الحصول على مدة التسجيل الصحيحة.
نهاية التسجيللإنهاء التسجيل، أقوم بإيقافه مؤقتًا أولاً، ثم أقوم بإجراء الاستماع أو عمليات أخرى إذا لزم الأمر، ثم قم بتعيين طول مصفوفة دفق التخزين على 0.
الحصول على الترددgetVoiceSize = Analysis => { const dataArray = new Uint8Array(analyser.frequencyBinCount);analyser.getByteFrequencyData(dataArray); أ + ب)؛ مبلغ الإرجاع؛}؛
للحصول على التفاصيل، يرجى الرجوع إلى https://developer.mozilla.org/zh-CN/docs/Web/API/AnalyserNode/frequencyBinCount
آخر
معظم المشاكل التي واجهتني هذه المرة كانت مشاكل التوافق، لذلك واجهت الكثير من المزالق، خاصة على جانب الهاتف المحمول، في البداية كانت هناك مشكلة حيث تم كتابة مدة التسجيل بشكل غير صحيح، مما أدى إلى تجميده مباشرة. لقد عوضت هذه التجربة أيضًا بعض الثغرات في واجهة برمجة تطبيقات HTML5. بالطبع، الشيء الأكثر أهمية هو تذكير الجميع بأن هذا النوع من وثائق واجهة برمجة التطبيقات الأصلية يتم الحصول عليه ببساطة وبشكل فظ من خلال عرض MDN مباشرة!
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.