اذهب إلى المحتوى
  • 0

كيف يمكن ارسال التسجيل الصوتي إلى السيرفر في لغة جافا سكربت

علي الكاسر

السؤال

السلام عليكم ورحمة الله وبركاته 

لدي كود جافا سكربت يقوم بفتح الميكرفون والتسجيل الصوتي ولكن يقوم بعمل رابط لتحميل الصوت المسجل. 

أنا اريد تعديل ذلك الكود ليقوم برفع وارسال الصوت الى السيرفر لاقوم بعد ذلك بتخزينه في قاعدة البيانات والتحكم فيه 

الكود

<html>

<body>
  <button onclick="samah();">تسجيل صوتي</button>
  <button onclick="stops();">stop</button>
  <a id="a"></a>

  <script>
    var audioChunks = []; // بيانات الصوت
    var mediaRecorder = null;
    var audioBlob = null;
    var audioUrl = null;
    var mainStream = null;

    function samah() {
      navigator.mediaDevices.getUserMedia({audio: true})
        .then(stream => {
          mainStream = stream;
          mediaRecorder = new MediaRecorder(stream);
          mediaRecorder.start(); // بدء التسجيل
          mediaRecorder.addEventListener("dataavailable", event => {
            audioChunks.push(event.data);
          });
        });
    }
    function stops() {
      mediaRecorder.addEventListener("stop", () => {
        audioBlob = new Blob(audioChunks, {type: mediaRecorder.mimeType});
        audioUrl = URL.createObjectURL(audioBlob);

        mainStream.getTracks() // get all tracks from the MediaStream
          .forEach(track => track.stop()); // stop each of them

        // تحميل ملف الصوت
        let a = document.getElementById("a");
        a.href = audioUrl;
        a.download = "recording.webm";
        a.innerText = 'click me to save file';
        //document.body.appendChild(a);
        //a.click();
      });

      mediaRecorder.stop();


    }

  </script>

</body>

</html>

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0

بما أنك تقوم بتجاوز عنصر audioBlob، فما عليك إلا ارسال الـ Blob الخاص بملف الأوديو وسيتم التعامل معه بشكل اعتيادي جدا، لنقم مثلا بإنشاء وظيفة جديدة هي وظيفة uploadAudio بحيث تقوم بـ:

  • إنشاء formData نقوم بإضافة عنصر الأوديو إليه. 
  • ارسال ملف الصورة إلى الخادم.
function uploadAudio() {
      // إرسال الصوت إلى الخادم هنا
      var formData = new FormData();
      formData.append("audio", audioBlob, "recording.webm");

      fetch("URL_TO_SERVER_ENDPOINT", {
        method: "POST",
        body: formData
      })
        .then(response => response.json())
        .then(data => {
          console.log("تم رفع الصوت بنجاح!", data);
          // استجابة من الخادم تحتوي على معلومات الصوت المرفوع ومعالجتها وتخزينها في قاعدة البيانات هنا
        })
        .catch(error => {
          console.error("حدث خطأ أثناء رفع الصوت", error);
        });
    }

بعد هذا سيمكنك التعامل مع الملف من خلال الباك اند بشكل عادي جدا.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

ستحتاج إلى تعديل الكود كالتالي:

<html>
<body>
  <button onclick="samah();">تسجيل صوتي</button>
  <button onclick="stops();">stop</button>
  <a id="a"></a>

  <script>
    let audioChunks = [];
    let mediaRecorder = null;
    let audioBlob = null;
    let mainStream = null;

    function samah() {
      navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
          mainStream = stream;
          mediaRecorder = new MediaRecorder(stream);
          mediaRecorder.start();
          mediaRecorder.addEventListener("dataavailable", event => {
            audioChunks.push(event.data);
          });
        });
    }

    async function stops() {
      mediaRecorder.addEventListener("stop", async () => {
        audioBlob = new Blob(audioChunks, { type: mediaRecorder.mimeType });

        mainStream.getTracks().forEach(track => track.stop());

        // إنشاء كائن FormData لإرسال البيانات إلى السيرفر
        const formData = new FormData();
        formData.append("audio", audioBlob, "recording.webm");

        try {
          // إرسال البيانات إلى السيرفر باستخدام Fetch API و async/await
          const response = await fetch("URL_TO_SERVER_ENDPOINT", {
            method: "POST",
            body: formData
          });
          const data = await response.json();
          console.log("تم رفع التسجيل الصوتي بنجاح!", data);
          // هنا يمكنك التحكم في البيانات المرتدة من السيرفر
        } catch (error) {
          console.error("حدث خطأ أثناء رفع التسجيل الصوتي:", error);
        }
      });

      mediaRecorder.addEventListener("stop", stops);

      mediaRecorder.stop();
    }
  </script>
</body>
</html>

وآلية عمل الكود هي:

  1. عند النقر على زر "تسجيل صوتي"، تستدعى الدالة samah().
  2. تتم مطالبة المستخدم بالإذن للوصول إلى الميكروفون باستخدام navigator.mediaDevices.getUserMedia().
  3. بمجرد الحصول على الإذن، يتم تشغيل التسجيل باستخدام MediaRecorder، وتبدأ المكونات الصوتية في الاحتفاظ بالبيانات المسجلة في المصفوفة audioChunks.
  4. عند النقر على زر "stop"، يتم استدعاء الدالة stops().
  5. استدعاء حدث "stop" على mediaRecorder باستخدام mediaRecorder.addEventListener("stop", stops) للتأكد من استدعاء الدالة عند إيقاف التسجيل.
  6. إنشاء كائن Blob من المكونات الصوتية المسجلة.
  7. يتم إيقاف جميع المسارات في mainStream باستخدام mainStream.getTracks().forEach(track => track.stop()).
  8. إنشاء كائن FormData لتكوين بيانات الصوت المراد إرسالها إلى السيرفر.
  9. استخدام fetch لإرسال بيانات الصوت إلى السيرفر بطريقة غير متزامنة باستخدام طريقة POST.
  10. التعامل مع الاستجابة من السيرفر باستخدام response.json() ومن ثم استخدام البيانات المرتجعة كما تحتاج.
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 7 دقائق مضت قال Adnane Kadri:

بما أنك تقوم بتجاوز عنصر audioBlob، فما عليك إلا ارسال الـ Blob الخاص بملف الأوديو وسيتم التعامل معه بشكل اعتيادي جدا، لنقم مثلا بإنشاء وظيفة جد

شكرا لك اخي 

بتاريخ 5 دقائق مضت قال Mustafa Suleiman:

ستحتاج إلى تعديل الكود كالتالي:

<html>
<body>
  <button onclick="samah();">تسجيل صوتي</button>
  <button onclick="stops();">stop</button>
  <a id="a"></a>

  <script>
    let audioChunks = [];
    let mediaRecorder = null;
    let audioBlob = null;
    let mainStream = null;

    function samah() {
      navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
          mainStream = stream;
          mediaRecorder = new MediaRecorder(stream);
          mediaRecorder.start();
          mediaRecorder.addEventListener("dataavailable", event => {
            audioChunks.push(event.data);
          });
        });
    }

    async function stops() {
      mediaRecorder.addEventListener("stop", async () => {
        audioBlob = new Blob(audioChunks, { type: mediaRecorder.mimeType });

        mainStream.getTracks().forEach(track => track.stop());

        // إنشاء كائن FormData لإرسال البيانات إلى السيرفر
        const formData = new FormData();
        formData.append("audio", audioBlob, "recording.webm");

        try {
          // إرسال البيانات إلى السيرفر باستخدام Fetch API و async/await
          const response = await fetch("URL_TO_SERVER_ENDPOINT", {
            method: "POST",
            body: formData
          });
          const data = await response.json();
          console.log("تم رفع التسجيل الصوتي بنجاح!", data);
          // هنا يمكنك التحكم في البيانات المرتدة من السيرفر
        } catch (error) {
          console.error("حدث خطأ أثناء رفع التسجيل الصوتي:", error);
        }
      });

      mediaRecorder.addEventListener("stop", stops);

      mediaRecorder.stop();
    }
  </script>
</body>
</html>

وآلية عمل الكود هي:

  1. عند النقر على زر "تسجيل صوتي"، يتم استدعاء الدالة samah().
  2. تتم مطالبة المستخدم بالإذن للوصول إلى الميكروفون باستخدام navigator.mediaDevices.getUserMedia().
  3. بمجرد الحصول على الإذن، يتم تشغيل التسجيل باستخدام MediaRecorder، وتبدأ المكونات الصوتية في الاحتفاظ بالبيانات المسجلة في المصفوفة audioChunks.
  4. عند النقر على زر "stop"، يتم استدعاء الدالة stops().
  5. استدعاء حدث "stop" على mediaRecorder باستخدام mediaRecorder.addEventListener("stop", stops) للتأكد من استدعاء الدالة عند إيقاف التسجيل.
  6. إنشاء كائن Blob من المكونات الصوتية المسجلة.
  7. يتم إيقاف جميع المسارات في mainStream باستخدام mainStream.getTracks().forEach(track => track.stop()).
  8. إنشاء كائن FormData لتكوين بيانات الصوت المراد إرسالها إلى السيرفر.
  9. استخدام fetch لإرسال بيانات الصوت إلى السيرفر بطريقة غير متزامنة باستخدام طريقة POST.
  10. التعامل مع الاستجابة من السيرفر باستخدام response.json() ومن ثم استخدام البيانات المرتجعة كما تحتاج.

شكرا جزيلا لك اخي اصبح الكود مفهوم بعد شرحك المفصل تسلم

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

هناك طريقة وهي استخدام WebSockets بدلاً من إرسال الطلبات عبر Fetch API. ما يحدث هو:

 عند الضغط على زر التسجيل، نقوم بإنشاء WebSocket connection مع السيرفر.
 عندما تصبح أجزاء الصوت متاحة عبر dataavailable event، نرسلها مباشرة عبر الـ WebSocket connection دون الانتظار حتى يكتمل التسجيل.
في السيرفر، نتلقى أجزاء الصوت من خلال نفس الـ WebSocket connection ونخزنها في قاعدة البيانات كما نتلقاها.

هذه الطريقة أفضل لأن:

  • ترسل البيانات مباشرة كلما أصبحت متاحة، بدون انتظار حتى ينتهي التسجيل.  
  • تقلل من حجم البيانات المرسلة مرة واحدة لأنها ترسل جزءًا بعد آخر كما يتم إنتاجه.  
  • تستخدم الـ WebSocket الذي هو أفضل من Fetch API في مثل هذه الحالات لأنه يوفر اتصالًا مستمرًا.

لذا سيكون الكود تقريبًا كالتالي:

let ws;

function samah() {  
  // إنشاء واير سوكات
  ws = new WebSocket("YOUR_WEBSOCKET_ENDPOINT");
  
  // ... باقي كود التسجيل نفسه
}

function stops() {
  mediaRecorder.addEventListener("dataavailable", event => {
    
    // إرسال الصوت عبر ذا واير سوكات
    ws.send(event.data); 
  });
    
  // ... بقية الكود نفسه
}

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 10 ساعة قال عبدالباسط ابراهيم:

هناك طريقة وهي استخدام WebSockets بدلاً من إرسال الطلبات عبر Fetch API. ما يحدث هو:

 عند الضغط على زر التسجيل، نقوم بإنشاء WebSocket connection مع السيرفر.
 عندما تصبح أجزاء الصوت متاحة عبر dataavailable event، نرسلها مباشرة عبر الـ WebSocket connection دون الانتظار حتى يكتمل التسجيل.
في السيرفر، نتلقى أجزاء الصوت من خلال نفس الـ WebSocket connection ونخزنها في قاعدة البيانات كما نتلقاها.

هذه الطريقة أفضل لأن:

  • ترسل البيانات مباشرة كلما أصبحت متاحة، بدون انتظار حتى ينتهي التسجيل.  
  • تقلل من حجم البيانات المرسلة مرة واحدة لأنها ترسل جزءًا بعد آخر كما يتم إنتاجه.  
  • تستخدم الـ WebSocket الذي هو أفضل من Fetch API في مثل هذه الحالات لأنه يوفر اتصالًا مستمرًا.

لذا سيكون الكود تقريبًا كالتالي:

let ws;

function samah() {  
  // إنشاء واير سوكات
  ws = new WebSocket("YOUR_WEBSOCKET_ENDPOINT");
  
  // ... باقي كود التسجيل نفسه
}

function stops() {
  mediaRecorder.addEventListener("dataavailable", event => {
    
    // إرسال الصوت عبر ذا واير سوكات
    ws.send(event.data); 
  });
    
  // ... بقية الكود نفسه
}

 

بس يا اخي الخوادم المحليه الخاصه للتجريب واغلب الاستضافات واخاصه الرخيصه ماتدعم الويب سوكيت، وانا استخدم php في الخلفيه وهذه اللغه لا تدعم الويب سوكيت بشكل جيد وليس هناك مصدر لتعلم الويب سوكيت فيها 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ On ١١‏/٧‏/٢٠٢٣ at 19:19 قال Adnane Kadri:

بما أنك تقوم بتجاوز عنصر audioBlob، فما عليك إلا ارسال الـ Blob الخاص بملف الأوديو وسيتم التعامل معه بشكل اعتيادي جدا، لنقم مثلا بإنشاء وظيفة جديدة هي وظيفة uploadAudio بحيث تقوم بـ:

  • إنشاء formData نقوم بإضافة عنصر الأوديو إليه. 
  • ارسال ملف الصورة إلى الخادم.
function uploadAudio() {
      // إرسال الصوت إلى الخادم هنا
      var formData = new FormData();
      formData.append("audio", audioBlob, "recording.webm");

      fetch("URL_TO_SERVER_ENDPOINT", {
        method: "POST",
        body: formData
      })
        .then(response => response.json())
        .then(data => {
          console.log("تم رفع الصوت بنجاح!", data);
          // استجابة من الخادم تحتوي على معلومات الصوت المرفوع ومعالجتها وتخزينها في قاعدة البيانات هنا
        })
        .catch(error => {
          console.error("حدث خطأ أثناء رفع الصوت", error);
        });
    }

بعد هذا سيمكنك التعامل مع الملف من خلال الباك اند بشكل عادي جدا.

اخي لقد نجحت في رفع الملف للسيرفر ولكن الملف مافيه صوت يعني لما اشغل الملف مايطلع الصوت 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...