هل سبق لك أن تساءلت عن كيفية عمل مشغلات الصوتيات التي تستخدمها يوميًا على هاتفك أو حاسوبك؟ هل تريد أن تتعلم كيفية بناء واحد بنفسك؟ برمجة مشغل الصوتيات هو مشروع ممتع وتعليمي يقدم فرصة رائعة لاستكشاف العديد من جوانب البرمجة الحديثة.
في هذا الدرس، سنغوص في بناء مشغل صوتيات باستخدام JavaScript، HTML، وCSS. سنبدأ من الصفر، بإنشاء واجهة مستخدم بسيطة تتيح للمستخدم اختيار ملفات الصوت من جهازه وتشغيلها. سنتعلم كيفية التعامل مع الملفات الصوتية، كيفية التحكم في التشغيل (مثل الانتقال إلى الأغنية التالية أو السابقة، والتبديل بين التشغيل الترتيبي والعشوائي)، وكيفية تحديث واجهة المستخدم لتعكس الأغنية الحالية المشغلة.
دعونا نبدأ هذه الرحلة المثيرة في عالم برمجة مشغلات الصوتيات، حيث ستحصل على الأدوات والمعرفة التي ستساعدك في بناء مشاريع أكثر تعقيدًا وتفاعلية في المستقبل. هل أنت مستعد؟ لننطلق
مشغل الصوتيات باستخدام JavaScript
ملف index.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
، وتنسيق قائمة التشغيل ومشغل الصوت لتبدو احترافية مع حدود وظلال خفيفة. الأزرار مصممة لتكون سهلة الاستخدام ومرئية بشكل جيد مع تأثيرات تحويم لتفاعل أفضل مع المستخدم.
ملف 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
.
ملخص الاستخدام
- عند اختيار الملفات، يتم تحميلها وعرضها في قائمة.
- يمكن للمستخدم تشغيل أي ملف من القائمة بالنقر عليه.
- يتم تشغيل الأغنية التالية أو السابقة بالضغط على الأزرار المناسبة.
- عند انتهاء الأغنية الحالية، يتم تشغيل الأغنية التالية تلقائيًا.
- يمكن للمستخدم التبديل بين التشغيل العشوائي والترتيبي بالنقر على زر “عشوائي”.
موارد إضافية:
- JavaScript for Beginners: https://www.freecodecamp.org/news/learn-javascript-for-beginners/ – دورة مجانية لتعلم جافا سكريبت من موقع freeCodeCamp.