دنیای ضبط MediaStream مبتنی بر مرورگر را با استفاده از MediaRecorder API کاوش کنید. یاد بگیرید چگونه صدا و ویدیو را مستقیماً در مرورگر ضبط کنید و اپلیکیشنهای وب غنی را بدون وابستگی به سرور توانمند سازید.
ضبط MediaStream در فرانتاند: ضبط رسانه مبتنی بر مرورگر
توانایی ضبط صدا و ویدیو به طور مستقیم در مرورگر وب، تحولی در توسعه اپلیکیشنهای وب ایجاد کرده است. ضبط MediaStream در فرانتاند، با بهرهگیری از MediaRecorder API، روشی قدرتمند و کارآمد برای پیادهسازی این قابلیت بدون اتکا به پردازشهای پیچیده سمت سرور فراهم میکند. این رویکرد امکان تعامل در لحظه، کاهش تأخیر و بهبود تجربه کاربری را به خصوص در اپلیکیشنهایی مانند جلسات آنلاین، ابزارهای ویرایش ویدیو و آموزشهای تعاملی فراهم میآورد.
درک MediaStream API
در قلب ضبط رسانه مبتنی بر مرورگر، MediaStream API قرار دارد. یک MediaStream نمایانگر جریانی از دادههای رسانهای، مانند ترکهای صوتی یا ویدیویی است. برای دسترسی به یک MediaStream، معمولاً از متد getUserMedia() استفاده میشود.
متد getUserMedia() از کاربر برای دسترسی به میکروفون و/یا دوربین اجازه میخواهد. این متد یک Promise برمیگرداند که در صورت موافقت کاربر با یک شیء MediaStream resolve میشود، یا در صورت عدم موافقت کاربر یا در دسترس نبودن دسترسی، با یک خطا reject میشود.
مثال: درخواست دسترسی به دوربین
در اینجا یک مثال ساده از نحوه درخواست دسترسی به دوربین کاربر آورده شده است:
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then(function(stream) {
// Stream is available, do something with it
console.log("Camera access granted!");
})
.catch(function(error) {
console.error("Error accessing camera: ", error);
});
توضیح:
navigator.mediaDevices.getUserMedia({ video: true, audio: false }): این خط دسترسی به دوربین (video: true) را درخواست کرده و به صراحت صدا (audio: false) را غیرفعال میکند. شما میتوانید این گزینهها را برای درخواست همزمان صدا و ویدیو یا فقط صدا تنظیم کنید..then(function(stream) { ... }): این بلوک در صورتی اجرا میشود که کاربر اجازه دسترسی بدهد. متغیرstreamحاوی شیءMediaStreamاست..catch(function(error) { ... }): این بلوک در صورت بروز خطا، مانند عدم موافقت کاربر، اجرا میشود. مدیریت صحیح خطاها برای ارائه تجربه کاربری خوب بسیار مهم است.
گزینههای پیکربندی برای getUserMedia()
متد getUserMedia() یک شیء قیود (constraints) اختیاری را میپذیرد که به شما امکان میدهد ویژگیهای مورد نظر جریان رسانه را مشخص کنید. این شامل گزینههایی مانند موارد زیر است:
video: مقدار Boolean (true/false) برای درخواست ویدیو، یا یک شیء برای قیود ویدیویی خاصتر (مانند رزولوشن، نرخ فریم).audio: مقدار Boolean (true/false) برای درخواست صدا، یا یک شیء برای قیود صوتی خاصتر (مانند حذف اکو، سرکوب نویز).width: عرض مورد نظر جریان ویدیو.height: ارتفاع مورد نظر جریان ویدیو.frameRate: نرخ فریم مورد نظر جریان ویدیو.
مثال: درخواست رزولوشن خاص دوربین
navigator.mediaDevices.getUserMedia({
video: {
width: { min: 640, ideal: 1280, max: 1920 },
height: { min: 480, ideal: 720, max: 1080 }
},
audio: true
})
.then(function(stream) {
// Stream is available
})
.catch(function(error) {
// Handle errors
});
در این مثال، ما در حال درخواست یک جریان ویدیویی با عرض بین ۶۴۰ تا ۱۹۲۰ پیکسل (ایدهآل ۱۲۸۰) و ارتفاع بین ۴۸۰ تا ۱۰۸۰ پیکسل (ایدهآل ۷۲۰) هستیم. همچنین صدا را نیز درخواست میکنیم.
معرفی MediaRecorder API
هنگامی که یک MediaStream در اختیار دارید، میتوانید از MediaRecorder API برای ضبط دادههای رسانهای استفاده کنید. MediaRecorder API متدهایی برای شروع، توقف، مکث و ازسرگیری ضبط و همچنین برای دسترسی به دادههای ضبط شده فراهم میکند.
ایجاد یک نمونه MediaRecorder
برای ایجاد یک نمونه MediaRecorder، شما شیء MediaStream را به سازنده (constructor) MediaRecorder ارسال میکنید:
const mediaRecorder = new MediaRecorder(stream);
شما همچنین میتوانید گزینههای اضافی را در سازنده مشخص کنید، مانند نوع MIME مورد نظر برای دادههای ضبط شده:
const options = { mimeType: 'video/webm;codecs=vp9' };
const mediaRecorder = new MediaRecorder(stream, options);
انواع MIME پشتیبانی شده:
انواع MIME موجود به مرورگر و کدکهایی که پشتیبانی میکند بستگی دارد. انواع MIME رایج عبارتند از:
video/webm;codecs=vp9video/webm;codecs=vp8video/mp4;codecs=avc1audio/webm;codecs=opusaudio/ogg;codecs=vorbis
شما میتوانید از متد MediaRecorder.isTypeSupported() برای بررسی اینکه آیا یک نوع MIME خاص توسط مرورگر پشتیبانی میشود یا خیر، استفاده کنید:
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
console.log('video/webm;codecs=vp9 is supported');
} else {
console.log('video/webm;codecs=vp9 is not supported');
}
ضبط داده با MediaRecorder
MediaRecorder API چندین رویداد (event) را فراهم میکند که میتوانید برای نظارت بر فرآیند ضبط به آنها گوش دهید:
dataavailable: این رویداد هر زمان که داده برای ذخیره سازی در دسترس باشد، فعال میشود.start: این رویداد هنگام شروع ضبط فعال میشود.stop: این رویداد هنگام توقف ضبط فعال میشود.pause: این رویداد هنگام مکث ضبط فعال میشود.resume: این رویداد هنگام ازسرگیری ضبط فعال میشود.error: این رویداد در صورت بروز خطا در حین ضبط فعال میشود.
مهمترین رویداد dataavailable است. این رویداد یک شیء Blob حاوی دادههای ضبط شده را فراهم میکند. شما میتوانید این اشیاء Blob را جمعآوری کرده و سپس هنگام اتمام ضبط، آنها را در یک Blob واحد ترکیب کنید.
مثال: ضبط و ذخیره ویدیو
let recordedChunks = [];
mediaRecorder.ondataavailable = function(event) {
console.log('data-available: ', event.data.size);
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
mediaRecorder.onstop = function() {
console.log('Recording stopped!');
const blob = new Blob(recordedChunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'recorded-video.webm';
document.body.appendChild(a);
a.click();
setTimeout(() => {
URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 100);
};
mediaRecorder.start();
console.log("Recording started!");
// To stop recording:
// mediaRecorder.stop();
توضیح:
let recordedChunks = [];: آرایهای برای ذخیره قطعات (chunks) دادههای ضبط شده.mediaRecorder.ondataavailable = function(event) { ... }: این تابع هر زمان که داده جدیدی در دسترس باشد فراخوانی میشود. این تابع دادهها را به آرایهrecordedChunksاضافه میکند.mediaRecorder.onstop = function() { ... }: این تابع هنگام توقف ضبط فراخوانی میشود. این تابع یکBlobاز قطعات جمعآوری شده ایجاد میکند، یک URL برایBlobتولید میکند، یک لینک دانلود ایجاد میکند و دانلود را آغاز میکند. همچنین پس از یک تأخیر کوتاه، شیء URL ایجاد شده را پاک میکند.mediaRecorder.start();: این دستور فرآیند ضبط را شروع میکند.mediaRecorder.stop();: این دستور را برای متوقف کردن ضبط فراخوانی کنید.
کنترل فرآیند ضبط
MediaRecorder API متدهایی برای کنترل فرآیند ضبط فراهم میکند:
start(timeslice): ضبط را شروع میکند. آرگومان اختیاریtimesliceبازه زمانی (بر حسب میلیثانیه) را مشخص میکند که رویدادdataavailableباید در آن فعال شود. اگرtimesliceارائه نشود، رویدادdataavailableفقط هنگام توقف ضبط فعال میشود.stop(): ضبط را متوقف میکند.pause(): ضبط را متوقف (مکث) میکند.resume(): ضبط را از سر میگیرد.requestData(): به صورت دستی رویدادdataavailableرا فعال میکند.
سازگاری مرورگر و Polyfillها
APIهای MediaStream و MediaRecorder به طور گسترده در مرورگرهای مدرن پشتیبانی میشوند. با این حال، مرورگرهای قدیمیتر ممکن است به صورت بومی از این APIها پشتیبانی نکنند. اگر نیاز به پشتیبانی از مرورگرهای قدیمیتر دارید، میتوانید از polyfillها برای ارائه قابلیتهای لازم استفاده کنید.
چندین polyfill در دسترس هستند، از جمله:
adapter.js: این polyfill سازگاری بین مرورگرها را برای APIهای WebRTC، از جملهgetUserMedia()، فراهم میکند.recorderjs: یک کتابخانه جاوا اسکریپت که قابلیتMediaRecorderرا برای مرورگرهایی که به صورت بومی از آن پشتیبانی نمیکنند، فراهم میکند.
کاربردهای عملی و موارد استفاده
ضبط MediaStream در فرانتاند طیف گستردهای از امکانات را برای توسعه اپلیکیشنهای وب باز میکند. در اینجا برخی از کاربردهای عملی و موارد استفاده آورده شده است:
- جلسات آنلاین و کنفرانس ویدیویی: ضبط و انتقال جریانهای صوتی و ویدیویی به صورت لحظهای برای جلسات آنلاین و کنفرانسهای ویدیویی.
- ابزارهای ویرایش ویدیو: به کاربران اجازه میدهد محتوای ویدیویی را مستقیماً در مرورگر ضبط و ویرایش کنند.
- آموزشها و نمایشهای تعاملی: ایجاد آموزشها و نمایشهای تعاملی که تعاملات کاربر را ضبط کرده و بازخورد شخصیسازی شده ارائه میدهند.
- اپلیکیشنهای ضبط صدا: ساخت اپلیکیشنهای ضبط صدا برای یادداشتبرداری، یادداشتهای صوتی و ویرایش صدا.
- سیستمهای نظارتی و دوربینهای امنیتی: پیادهسازی سیستمهای نظارتی و دوربینهای امنیتی مبتنی بر مرورگر که جریانهای ویدیویی را ضبط و ذخیره میکنند.
- ابزارهای دسترسیپذیری: توسعه ابزارهایی که میتوانند گفتار را ضبط کرده و آن را به صورت لحظهای به متن تبدیل کنند، یا فعالیت صفحه را برای بازبینی بعدی ضبط کنند.
مثال: پیادهسازی یک اپلیکیشن ساده ضبط ویدیو
در اینجا یک مثال ساده از نحوه ادغام مفاهیم مورد بحث در یک اپلیکیشن ضبط ویدیوی پایه با استفاده از HTML، CSS و جاوا اسکریپت آورده شده است:
HTML (index.html):
<!DOCTYPE html>
<html>
<head>
<title>Browser Video Recorder</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Browser Video Recorder</h1>
<video id="preview" autoplay muted></video><br>
<button id="recordButton">Record</button>
<button id="stopButton" disabled>Stop</button>
<script src="script.js"></script>
</body>
</html>
CSS (style.css):
body {
font-family: sans-serif;
text-align: center;
}
video {
width: 640px;
height: 480px;
border: 1px solid #ccc;
}
button {
padding: 10px 20px;
font-size: 16px;
margin: 10px;
}
جاوا اسکریپت (script.js):
const preview = document.getElementById('preview');
const recordButton = document.getElementById('recordButton');
const stopButton = document.getElementById('stopButton');
let mediaRecorder;
let recordedChunks = [];
recordButton.addEventListener('click', startRecording);
stopButton.addEventListener('click', stopRecording);
async function startRecording() {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
preview.srcObject = stream;
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.onstop = handleStop;
mediaRecorder.start();
recordButton.disabled = true;
stopButton.disabled = false;
} catch (err) {
console.error("Error accessing media devices.", err);
}
}
function handleDataAvailable(event) {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
}
function stopRecording() {
mediaRecorder.stop();
recordButton.disabled = false;
stopButton.disabled = true;
//Stop all video streams
preview.srcObject.getVideoTracks().forEach(track => track.stop());
}
function handleStop() {
const blob = new Blob(recordedChunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'recorded-video.webm';
document.body.appendChild(a);
a.click();
setTimeout(() => {
URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 100);
recordedChunks = []; // Reset array for the next recording
}
این مثال اصول اصلی ضبط، نمایش، ذخیره و دانلود ویدیو را مستقیماً در مرورگر نشان میدهد. برای بهبود عملکرد، اضافه کردن مدیریت خطا، گزینههای مختلف کدک، یا کیفیتهای ضبط قابل تنظیم توسط کاربر را در نظر بگیرید.
ملاحظات امنیتی
هنگام کار با ضبط MediaStream، آگاهی از ملاحظات امنیتی ضروری است:
- مجوزهای کاربر: همیشه قبل از دسترسی به میکروفون یا دوربین از کاربر اجازه بگیرید. به وضوح دلیل نیاز خود به دسترسی به این دستگاهها را مشخص کنید.
- HTTPS: از HTTPS استفاده کنید تا اطمینان حاصل شود که جریان رسانه رمزگذاری شده و از استراق سمع محافظت میشود.
getUserMedia()API معمولاً به یک زمینه امن (HTTPS) نیاز دارد. - ذخیرهسازی دادهها: اگر دادههای ضبط شده را ذخیره میکنید، اطمینان حاصل کنید که به صورت امن ذخیره شده و از دسترسی غیرمجاز محافظت میشود. استفاده از رمزگذاری و مکانیزمهای کنترل دسترسی را در نظر بگیرید. به مقررات حریم خصوصی دادهها مربوط به کاربران و موقعیت مکانی آنها (مانند GDPR, CCPA) پایبند باشید.
- حریم خصوصی: در مورد نحوه استفاده از دادههای ضبط شده شفاف باشید. به کاربران کنترل بر دادههایشان و امکان حذف آن را بدهید.
- کد مخرب: هنگام کار با محتوای تولید شده توسط کاربر مراقب باشید، زیرا ممکن است حاوی کد مخرب باشد. هرگونه ورودی کاربر را برای جلوگیری از حملات اسکریپتنویسی بین سایتی (XSS) پاکسازی کنید.
بهینهسازی عملکرد
برای اطمینان از عملکرد بهینه هنگام استفاده از ضبط MediaStream، موارد زیر را در نظر بگیرید:
- انتخاب نوع MIME: نوع MIME را انتخاب کنید که توسط مرورگر پشتیبانی شود و فشردهسازی خوبی ارائه دهد.
- بازه زمانی Timeslice: بازه زمانی
timesliceرا برای ایجاد تعادل بین در دسترس بودن داده و عملکرد تنظیم کنید. یک بازه زمانیtimesliceکوچکتر منجر به رویدادهایdataavailableمکررتر میشود، اما ممکن است سربار را نیز افزایش دهد. - مدیریت دادهها: دادههای ضبط شده را به طور کارآمد مدیریت کنید تا از نشت حافظه و تنگناهای عملکردی جلوگیری شود. از تکنیکهایی مانند بافرینگ و استریمینگ برای پردازش مقادیر زیاد داده استفاده کنید.
- رابط کاربری: یک رابط کاربری طراحی کنید که بازخورد واضحی در مورد فرآیند ضبط به کاربر ارائه دهد. یک نشانگر ضبط نمایش دهید و کنترلهایی برای مکث، ازسرگیری و توقف ضبط فراهم کنید.
نتیجهگیری
ضبط MediaStream در فرانتاند به توسعهدهندگان وب این امکان را میدهد که تجربیات رسانهای غنی و تعاملی را مستقیماً در مرورگر ایجاد کنند. با درک APIهای MediaStream و MediaRecorder، توسعهدهندگان میتوانند طیف گستردهای از اپلیکیشنها، از جلسات آنلاین و ابزارهای ویرایش ویدیو گرفته تا آموزشهای تعاملی و سیستمهای نظارتی را بسازند. با توجه به ملاحظات امنیتی و عملکردی، میتوانید راهحلهای ضبط رسانهای قوی و کاربرپسندی ایجاد کنید که عملکرد و جذابیت اپلیکیشنهای وب شما را افزایش میدهد.