mplayer

مشغل الصوتيات باستخدام JavaScript

هل سبق لك أن تساءلت عن كيفية عمل مشغلات الصوتيات التي تستخدمها يوميًا على هاتفك أو حاسوبك؟ هل تريد أن تتعلم كيفية بناء واحد بنفسك؟ برمجة مشغل الصوتيات هو مشروع ممتع وتعليمي يقدم فرصة رائعة لاستكشاف العديد من جوانب البرمجة الحديثة.

في هذا الدرس، سنغوص في بناء مشغل صوتيات باستخدام JavaScript، HTML، وCSS. سنبدأ من الصفر، بإنشاء واجهة مستخدم بسيطة تتيح للمستخدم اختيار ملفات الصوت من جهازه وتشغيلها. سنتعلم كيفية التعامل مع الملفات الصوتية، كيفية التحكم في التشغيل (مثل الانتقال إلى الأغنية التالية أو السابقة، والتبديل بين التشغيل الترتيبي والعشوائي)، وكيفية تحديث واجهة المستخدم لتعكس الأغنية الحالية المشغلة.

دعونا نبدأ هذه الرحلة المثيرة في عالم برمجة مشغلات الصوتيات، حيث ستحصل على الأدوات والمعرفة التي ستساعدك في بناء مشاريع أكثر تعقيدًا وتفاعلية في المستقبل. هل أنت مستعد؟ لننطلق

مشغل الصوتيات باستخدام JavaScript

ملف index.html

				
					<!DOCTYPE html>
<html lang="ar">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>مشغل الصوتيات</title>
    <link data-asynced="1" as="style" onload="this.onload=null;this.rel='stylesheet'"  rel="preload" href="styles.css">
</head>
<body>
    <h1>مشغل الصوتيات</h1>
    <div class="container">
        <div class="playlist">
            <input type="file" id="fileInput" webkitdirectory mozdirectory multiple>
            <ul id="fileList"></ul>
        </div>
        <div class="player">
            <div id="currentSong">  لا توجد</div>
            <audio id="audioPlayer" controls></audio>
            <div class="controls">
                <button id="prevBtn" title="السابق">&#x21E6;</button>
                <button id="nextBtn" title="التالي">&#x21E8;</button>
                <button id="shuffleBtn">عشوائي</button>
            </div>
        </div>
    </div> <script type="litespeed/javascript" data-src="script.js"></script> <script data-no-optimize="1">!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-no-optimize="1">var litespeed_vary=document.cookie.replace(/(?:(?:^|.*;\s*)_lscache_vary\s*\=\s*([^;]*).*$)|^.*$/,"");litespeed_vary||fetch("/wp-content/plugins/litespeed-cache/guest.vary.php",{method:"POST",cache:"no-cache",redirect:"follow"}).then(e=>e.json()).then(e=>{console.log(e),e.hasOwnProperty("reload")&&"yes"==e.reload&&(sessionStorage.setItem("litespeed_docref",document.referrer),window.location.reload(!0))});</script><script data-optimized="1" type="litespeed/javascript" data-src="https://onemoka.com/wp-content/litespeed/js/1dd10d9ae6f3e88e8bee2397ec62f1b2.js?ver=54b1f"></script><script>const litespeed_ui_events=["mouseover","click","keydown","wheel","touchmove","touchstart"];var urlCreator=window.URL||window.webkitURL;function litespeed_load_delayed_js_force(){console.log("[LiteSpeed] Start Load JS Delayed"),litespeed_ui_events.forEach(e=>{window.removeEventListener(e,litespeed_load_delayed_js_force,{passive:!0})}),document.querySelectorAll("iframe[data-litespeed-src]").forEach(e=>{e.setAttribute("src",e.getAttribute("data-litespeed-src"))}),"loading"==document.readyState?window.addEventListener("DOMContentLoaded",litespeed_load_delayed_js):litespeed_load_delayed_js()}litespeed_ui_events.forEach(e=>{window.addEventListener(e,litespeed_load_delayed_js_force,{passive:!0})});async function litespeed_load_delayed_js(){let t=[];for(var d in document.querySelectorAll('script[type="litespeed/javascript"]').forEach(e=>{t.push(e)}),t)await new Promise(e=>litespeed_load_one(t[d],e));document.dispatchEvent(new Event("DOMContentLiteSpeedLoaded")),window.dispatchEvent(new Event("DOMContentLiteSpeedLoaded"))}function litespeed_load_one(t,e){console.log("[LiteSpeed] Load ",t);var d=document.createElement("script");d.addEventListener("load",e),d.addEventListener("error",e),t.getAttributeNames().forEach(e=>{"type"!=e&&d.setAttribute("data-src"==e?"src":e,t.getAttribute(e))});let a=!(d.type="text/javascript");!d.src&&t.textContent&&(d.src=litespeed_inline2src(t.textContent),a=!0),t.after(d),t.remove(),a&&e()}function litespeed_inline2src(t){try{var d=urlCreator.createObjectURL(new Blob([t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1")],{type:"text/javascript"}))}catch(e){d="data:text/javascript;base64,"+btoa(t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1"))}return d}</script></body>
</html>

				
			

شرح HTML

  • <!DOCTYPE html>: تحدد نوع الوثيقة وتستخدم HTML5.
  • <html lang="ar">: تحدد لغة الوثيقة بالعربية.
  • <head>: يحتوي على بيانات وصفية وعناصر الربط.
    • <meta charset="UTF-8">: تحدد ترميز النصوص.
    • <meta name="viewport" content="width=device-width, initial-scale=1.0">: تجعل الصفحة متوافقة مع جميع الأجهزة.
    • <title>مشغل الصوتيات</title>: تحدد عنوان الصفحة.
    • <link rel="stylesheet" href="styles.css">: تربط ملف CSS لتنسيق الصفحة.
  • <body>: يحتوي على محتوى الصفحة.
    • <h1>مشغل الصوتيات</h1>: عنوان الصفحة.
    • <div class="container">: حاوية رئيسية تحتوي على قائمة التشغيل ومشغل الصوت.
      • <div class="playlist">: قسم قائمة التشغيل.
        • <input type="file" id="fileInput" webkitdirectory mozdirectory multiple>: عنصر لاختيار الملفات، يمكن اختيار مجلد كامل.
        • <ul id="fileList"></ul>: قائمة غير مرتبة لعرض الملفات الصوتية.
      • <div class="player">: قسم مشغل الصوت.
        • <div id="currentSong">الأغنية الحالية: لا توجد</div>: لعرض اسم الأغنية الحالية.
        • <audio id="audioPlayer" controls></audio>: مشغل الصوت.
        • <div class="controls">: أزرار التحكم.
          • <button id="prevBtn">السابق</button>: زر للأغنية السابقة.
          • <button id="nextBtn">التالي</button>: زر للأغنية التالية.
          • <button id="shuffleBtn">عشوائي</button>: زر للتبديل بين التشغيل العشوائي والترتيبي.
    • <script src="script.js"></script>: ربط ملف JavaScript.

ملف styles.css

				
					body {
    font-family: Arial, sans-serif;
    background-color: #f0f0f0;
    margin: 0;
    padding: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
}

h1 {
    color: #333;
}

.container {
    display: flex;
    width: 100%;
    max-width: 900px;
    margin: 20px 0;
    background-color: #fff;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.playlist {
    width: 30%;
    border-right: 1px solid #ccc;
    padding: 20px;
    box-sizing: border-box;
}

#fileInput {
    margin-bottom: 20px;
}

#fileList {
    list-style-type: none;
    padding: 0;
    max-height: 300px;
    overflow-y: auto;
}

#fileList li {
    margin: 5px 0;
    padding: 10px;
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    cursor: pointer;
    transition: background-color 0.3s;
}

#fileList li:hover {
    background-color: rgb(212, 0, 255);
    color: white;
}

#prevBtn,#nextBtn{
    font-size: 20px;
}
#shuffleBtn{
    background-color: rgb(212, 0, 255);
    font-size: 20px;
}
#currentSong{
    color: #089905;
}
.player {
    width: 70%;
    padding: 20px;
    box-sizing: border-box;
    text-align: center;
}

#currentSong {
    margin: 20px 0;
    font-weight: bold;
}

audio {
    width: 100%;
    margin: 20px 0;
}

.controls {
    margin: 20px 0;
}

.controls button {
    margin: 0 5px;
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #089905;
    color: #fff;
    transition: background-color 0.3s;
}

.controls button:hover {
    background-color: #555;
}
    


				
			

ملف CSS هذا يقوم بتنسيق مشغل الصوتيات بشكل جذاب وواضح. يتم تنسيق الجسم والحاويات الداخلية بشكل منظم باستخدام flex، وتنسيق قائمة التشغيل ومشغل الصوت لتبدو احترافية مع حدود وظلال خفيفة. الأزرار مصممة لتكون سهلة الاستخدام ومرئية بشكل جيد مع تأثيرات تحويم لتفاعل أفضل مع المستخدم.

مشغل الصوتيات باستخدام JavaScript
Result

ملف script.js

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

إضافة مستمعات الأحداث DOM

				
					document.getElementById('fileInput').addEventListener('change', handleFileSelect, false);
document.getElementById('prevBtn').addEventListener('click', playPrevious);
document.getElementById('nextBtn').addEventListener('click', playNext);
document.getElementById('shuffleBtn').addEventListener('click', toggleShuffle);
document.getElementById('audioPlayer').addEventListener('ended', playNext);

				
			

إضافة مستمعات الأحداث:

    • fileInput: عند تغيير الملفات المختارة، يتم استدعاء الدالة handleFileSelect.
    • prevBtn: عند النقر على زر “السابق”، يتم استدعاء الدالة playPrevious.
    • nextBtn: عند النقر على زر “التالي”، يتم استدعاء الدالة playNext.
    • shuffleBtn: عند النقر على زر “عشوائي”، يتم استدعاء الدالة toggleShuffle.
    • audioPlayer: عند انتهاء تشغيل الملف الصوتي، يتم استدعاء الدالة playNext.

المتغيرات veriables

				
					const fileList = document.getElementById('fileList');
const audioPlayer = document.getElementById('audioPlayer');
const currentSong = document.getElementById('currentSong');
let audioFiles = [];
let currentIndex = 0;
let isShuffle = false;

				
			

تعريف المتغيرات:

    • fileList: يمثل العنصر HTML الذي يحتوي على قائمة الملفات.
    • audioPlayer: يمثل عنصر مشغل الصوت في HTML.
    • currentSong: يمثل العنصر الذي يعرض اسم الأغنية الحالية.
    • audioFiles: مصفوفة لتخزين الملفات الصوتية المختارة.
    • currentIndex: يخزن الفهرس الحالي للأغنية المشغلة.
    • isShuffle: متغير لتحديد ما إذا كان التشغيل عشوائيًا أم لا.

دالة handleFileSelect

				
					function handleFileSelect(event) {
    fileList.innerHTML = '';
    audioFiles = [];

    const files = event.target.files;
    for (const file of files) {
        if (file.type === 'audio/mpeg' || file.name.endsWith('.mp3')) {
            const listItem = document.createElement('li');
            listItem.textContent = file.name;
            listItem.addEventListener('click', () => playAudioFile(file, audioFiles.indexOf(file)));
            fileList.appendChild(listItem);
            audioFiles.push(file);
        }
    }
    if (audioFiles.length > 0) {
        playAudioFile(audioFiles[0], 0); // تشغيل أول ملف بشكل افتراضي
    }
}

				
			
  • إفراغ القائمة والمصفوفة:
    • fileList.innerHTML = '';: يتم إفراغ قائمة الملفات المرئية.
    • audioFiles = [];: يتم إفراغ المصفوفة التي تخزن الملفات الصوتية.
  • التعامل مع الملفات المختارة:
    • const files = event.target.files;: الحصول على الملفات المختارة.
    • for (const file of files) { ... }: حلقة تمر على كل ملف مختار.
    • if (file.type === 'audio/mpeg' || file.name.endsWith('.mp3')) { ... }: يتحقق من نوع الملف للتأكد من أنه ملف صوتي MP3.
  • إنشاء عناصر القائمة:
    • const listItem = document.createElement('li');: إنشاء عنصر قائمة جديد.
    • listItem.textContent = file.name;: تعيين اسم الملف كنص للعنصر.
    • listItem.addEventListener('click', () => playAudioFile(file, audioFiles.indexOf(file)));: إضافة مستمع للنقر على العنصر لتشغيل الملف عند النقر عليه.
    • fileList.appendChild(listItem);: إضافة العنصر إلى القائمة المرئية.
    • audioFiles.push(file);: إضافة الملف إلى المصفوفة.
  • تشغيل أول ملف بشكل افتراضي:
    • if (audioFiles.length > 0) { playAudioFile(audioFiles[0], 0); }: إذا كانت هناك ملفات، يتم تشغيل أول ملف بشكل افتراضي.

دالة playAudioFile

				
					function playAudioFile(file, index) {
    const fileURL = URL.createObjectURL(file);
    audioPlayer.src = fileURL;
    audioPlayer.play();
    currentSong.textContent = `الأغنية الحالية: ${file.name}`;
    currentIndex = index;
}

				
			
  • إنشاء رابط للملف الصوتي:
    • const fileURL = URL.createObjectURL(file);: يتم إنشاء رابط URL مؤقت للملف الصوتي باستخدام URL.createObjectURL.
  • تشغيل الملف الصوتي:
    • audioPlayer.src = fileURL;: تعيين الرابط لمشغل الصوت.
    • audioPlayer.play();: بدء تشغيل الملف الصوتي.
  • تحديث واجهة المستخدم:
    • currentSong.textContent = الأغنية الحالية: ${file.name};: تحديث النص لعرض اسم الأغنية الحالية.
    • currentIndex = index;: تحديث الفهرس الحالي في المصفوفة.

دالة playNext

				
					function playNext() {
    if (isShuffle) {
        currentIndex = Math.floor(Math.random() * audioFiles.length);
    } else {
        currentIndex = (currentIndex + 1) % audioFiles.length;
    }
    playAudioFile(audioFiles[currentIndex], currentIndex);
}

				
			
  • التشغيل العشوائي أو الترتيبي:
    • if (isShuffle) { currentIndex = Math.floor(Math.random() * audioFiles.length); }: إذا كان التشغيل عشوائيًا، يتم اختيار فهرس عشوائي.
    • else { currentIndex = (currentIndex + 1) % audioFiles.length; }: إذا كان التشغيل ترتيبيًا، يتم تحديث الفهرس إلى الفهرس التالي بشكل دائري باستخدام باقي القسمة (%).
  • تشغيل الملف التالي:
    • playAudioFile(audioFiles[currentIndex], currentIndex);: تشغيل الملف الصوتي الموجود في الفهرس الجديد.

دالة playPrevious

				
					function playPrevious() {
    if (isShuffle) {
        currentIndex = Math.floor(Math.random() * audioFiles.length);
    } else {
        currentIndex = (currentIndex - 1 + audioFiles.length) % audioFiles.length;
    }
    playAudioFile(audioFiles[currentIndex], currentIndex);
}

				
			
  • التشغيل العشوائي أو الترتيبي:
    • if (isShuffle) { currentIndex = Math.floor(Math.random() * audioFiles.length); }: إذا كان التشغيل عشوائيًا، يتم اختيار فهرس عشوائي.
    • else { currentIndex = (currentIndex - 1 + audioFiles.length) % audioFiles.length; }: إذا كان التشغيل ترتيبيًا، يتم تحديث الفهرس إلى الفهرس السابق بشكل دائري باستخدام باقي القسمة (%).
  • تشغيل الملف السابق:
    • playAudioFile(audioFiles[currentIndex], currentIndex);: تشغيل الملف الصوتي الموجود في الفهرس الجديد.

دالة toggleShuffle

				
					function toggleShuffle() {
    isShuffle = !isShuffle;
    document.getElementById('shuffleBtn').textContent = isShuffle ? 'ترتيب' : 'عشوائي';
}

				
			
  • تبديل حالة التشغيل العشوائي:
    • isShuffle = !isShuffle;: عكس قيمة isShuffle بين true وfalse.
  • تحديث نص الزر:
    • document.getElementById('shuffleBtn').textContent = isShuffle ? 'ترتيب' : 'عشوائي';: تغيير نص الزر بناءً على حالة isShuffle.

ملخص الاستخدام

  • عند اختيار الملفات، يتم تحميلها وعرضها في قائمة.
  • يمكن للمستخدم تشغيل أي ملف من القائمة بالنقر عليه.
  • يتم تشغيل الأغنية التالية أو السابقة بالضغط على الأزرار المناسبة.
  • عند انتهاء الأغنية الحالية، يتم تشغيل الأغنية التالية تلقائيًا.
  • يمكن للمستخدم التبديل بين التشغيل العشوائي والترتيبي بالنقر على زر “عشوائي”.
mplayer
Result

موارد إضافية:

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

Scroll to Top