পিকচার-ইন-পিকচার (পিআইপি) ব্যবহারকারীদের একটি ভাসমান উইন্ডোতে ভিডিও দেখতে দেয় (সর্বদা অন্যান্য উইন্ডোর উপরে) যাতে তারা অন্যান্য সাইট বা অ্যাপ্লিকেশনগুলির সাথে ইন্টারঅ্যাক্ট করার সময় তারা কী দেখছে তার উপর নজর রাখতে পারে।
Picture-in-Picture Web API-এর মাধ্যমে, আপনি আপনার ওয়েবসাইটে ভিডিও উপাদানগুলির জন্য Picture-in-Picture শুরু করতে এবং নিয়ন্ত্রণ করতে পারেন। আমাদের অফিসিয়াল পিকচার-ইন-পিকচার নমুনায় এটি ব্যবহার করে দেখুন।
পটভূমি
সেপ্টেম্বর 2016-এ, Safari macOS সিয়েরাতে একটি WebKit API-এর মাধ্যমে Picture-in-Picture সমর্থন যোগ করেছে। ছয় মাস পরে, Chrome স্বয়ংক্রিয়ভাবে একটি নেটিভ অ্যান্ড্রয়েড API ব্যবহার করে Android O প্রকাশের সাথে মোবাইলে পিকচার-ইন-পিকচার ভিডিও চালায়। ছয় মাস পরে, আমরা সাফারির সাথে সামঞ্জস্যপূর্ণ একটি ওয়েব API তৈরি এবং মানসম্মত করার আমাদের অভিপ্রায় ঘোষণা করেছি , যা ওয়েব ডেভেলপারদের পিকচার-ইন-পিকচারের আশেপাশে সম্পূর্ণ অভিজ্ঞতা তৈরি এবং নিয়ন্ত্রণ করতে দেয়। এবং আমরা এখানে!
কোডে প্রবেশ করুন
পিকচার-ইন-পিকচার লিখুন
চলুন শুরু করা যাক একটি ভিডিও উপাদান দিয়ে এবং ব্যবহারকারীর জন্য এটির সাথে ইন্টারঅ্যাক্ট করার একটি উপায়, যেমন একটি বোতাম উপাদান।
<video id="videoElement" src="https://example.com/file.mp4"></video>
<button id="pipButtonElement"></button>
শুধুমাত্র একটি ব্যবহারকারীর অঙ্গভঙ্গির প্রতিক্রিয়া হিসাবে পিকচার-ইন-পিকচারের অনুরোধ করুন, এবং videoElement.play()
দ্বারা ফেরত দেওয়া প্রতিশ্রুতিতে কখনই নয়। এর কারণ প্রতিশ্রুতিগুলি এখনও ব্যবহারকারীর অঙ্গভঙ্গি প্রচার করে না। পরিবর্তে, নীচে দেখানো হিসাবে pipButtonElement
এ ক্লিক হ্যান্ডলারে requestPictureInPicture()
কল করুন। কোন ব্যবহারকারী দুবার ক্লিক করলে কি হবে তা পরিচালনা করার দায়িত্ব আপনার।
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
await videoElement.requestPictureInPicture();
pipButtonElement.disabled = false;
});
প্রতিশ্রুতি সমাধান হয়ে গেলে, ক্রোম ভিডিওটিকে একটি ছোট উইন্ডোতে সঙ্কুচিত করে যেটি ব্যবহারকারী অন্য উইন্ডোতে ঘুরে ঘুরে অবস্থান করতে পারে।
আপনার কাজ শেষ দারুণ কাজ! আপনি পড়া বন্ধ করতে পারেন এবং আপনার উপযুক্ত ছুটি নিতে যেতে পারেন। দুঃখের বিষয়, যে সবসময় ক্ষেত্রে হয় না. প্রতিশ্রুতি নিম্নলিখিত কারণে প্রত্যাখ্যান করতে পারে :
- পিকচার-ইন-পিকচার সিস্টেম দ্বারা সমর্থিত নয়।
- একটি সীমাবদ্ধ অনুমতি নীতির কারণে নথিতে ছবি-ইন-ছবি ব্যবহার করার অনুমতি নেই।
- ভিডিও মেটাডেটা এখনও লোড করা হয়নি (
videoElement.readyState === 0
)। - ভিডিও ফাইল শুধুমাত্র অডিও.
- ভিডিও এলিমেন্টে নতুন
disablePictureInPicture
অ্যাট্রিবিউট রয়েছে। - কলটি ব্যবহারকারীর অঙ্গভঙ্গি ইভেন্ট হ্যান্ডলারে করা হয়নি (যেমন একটি বোতাম ক্লিক)। ক্রোম 74 থেকে শুরু করে, এটি শুধুমাত্র তখনই প্রযোজ্য যদি আগে থেকেই পিকচার-ইন-পিকচারে কোনো উপাদান না থাকে।
নীচের বৈশিষ্ট্য সমর্থন বিভাগ দেখায় কিভাবে এই সীমাবদ্ধতার উপর ভিত্তি করে একটি বোতাম সক্ষম/অক্ষম করতে হয়।
এই সম্ভাব্য ত্রুটিগুলি ক্যাপচার try...catch
এবং ব্যবহারকারীকে কী ঘটছে তা জানতে দিন।
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
try {
await videoElement.requestPictureInPicture();
} catch (error) {
// TODO: Show error message to user.
} finally {
pipButtonElement.disabled = false;
}
});
ভিডিও এলিমেন্ট একই রকম আচরণ করে তা পিকচার-ইন-পিকচারে থাকুক বা না থাকুক: ইভেন্ট গুলি করা হয় এবং কলিং পদ্ধতি কাজ করে। এটি পিকচার-ইন-পিকচার উইন্ডোতে অবস্থার পরিবর্তনগুলিকে প্রতিফলিত করে (যেমন প্লে, পজ, সিক, ইত্যাদি) এবং জাভাস্ক্রিপ্টে প্রোগ্রাম্যাটিকভাবে স্টেট পরিবর্তন করাও সম্ভব।
পিকচার-ইন-পিকচার থেকে প্রস্থান করুন
এখন, পিকচার-ইন-পিকচারে প্রবেশ এবং প্রস্থান করার জন্য আমাদের বোতামটিকে টগল করা যাক। আমাদের প্রথমে পরীক্ষা করতে হবে যে শুধুমাত্র পঠনযোগ্য অবজেক্ট document.pictureInPictureElement
pictureInPictureElement আমাদের ভিডিও উপাদান কিনা। যদি তা না হয়, আমরা উপরের মত করে পিকচার-ইন-পিকচারে প্রবেশ করার জন্য একটি অনুরোধ পাঠাই। অন্যথায়, আমরা document.exitPictureInPicture()
কল করে চলে যেতে বলি, যার মানে ভিডিওটি আসল ট্যাবে ফিরে আসবে। মনে রাখবেন যে এই পদ্ধতিটি একটি প্রতিশ্রুতিও দেয়।
...
try {
if (videoElement !== document.pictureInPictureElement) {
await videoElement.requestPictureInPicture();
} else {
await document.exitPictureInPicture();
}
}
...
পিকচার-ইন-পিকচার ইভেন্ট শুনুন
অপারেটিং সিস্টেম সাধারণত একটি উইন্ডোতে পিকচার-ইন-পিকচার সীমাবদ্ধ করে, তাই ক্রোমের বাস্তবায়ন এই প্যাটার্ন অনুসরণ করে। এর মানে ব্যবহারকারীরা একবারে শুধুমাত্র একটি পিকচার-ইন-পিকচার ভিডিও চালাতে পারবেন। আপনি আশা করা উচিত যে ব্যবহারকারীরা পিকচার-ইন-পিকচার থেকে প্রস্থান করবে এমনকি যখন আপনি এটি না চাইতেন।
নতুন enterpictureinpicture
এবং leavepictureinpicture
ইভেন্ট হ্যান্ডলাররা আমাদের ব্যবহারকারীদের জন্য অভিজ্ঞতা তৈরি করতে দেয়। এটি ভিডিওগুলির একটি ক্যাটালগ ব্রাউজ করা থেকে শুরু করে একটি লাইভস্ট্রিম চ্যাট দেখা পর্যন্ত যেকোনো কিছু হতে পারে৷
videoElement.addEventListener('enterpictureinpicture', function (event) {
// Video entered Picture-in-Picture.
});
videoElement.addEventListener('leavepictureinpicture', function (event) {
// Video left Picture-in-Picture.
// User may have played a Picture-in-Picture video from a different page.
});
পিকচার-ইন-পিকচার উইন্ডো কাস্টমাইজ করুন
Chrome 74 পিকচার-ইন-পিকচার উইন্ডোতে প্লে/পজ, আগের ট্র্যাক এবং পরবর্তী ট্র্যাক বোতাম সমর্থন করে যা আপনি মিডিয়া সেশন API ব্যবহার করে নিয়ন্ত্রণ করতে পারেন।
ডিফল্টরূপে, একটি প্লে/পজ বোতাম সর্বদা পিকচার-ইন-পিকচার উইন্ডোতে দেখানো হয় যদি না ভিডিওটি মিডিয়াস্ট্রিম অবজেক্টে (যেমন getUserMedia()
, getDisplayMedia()
, canvas.captureStream()
) বা ভিডিওটির মিডিয়াসোর্স সময়কাল সেট না থাকে থেকে +Infinity
(যেমন লাইভ ফিড)। একটি প্লে/পজ বোতাম সর্বদা দৃশ্যমান হয় তা নিশ্চিত করতে, নীচের মত "প্লে" এবং "পজ" উভয় মিডিয়া ইভেন্টের জন্য কিছু মিডিয়া সেশন অ্যাকশন হ্যান্ডলার সেট করুন।
// Show a play/pause button in the Picture-in-Picture window
navigator.mediaSession.setActionHandler('play', function () {
// User clicked "Play" button.
});
navigator.mediaSession.setActionHandler('pause', function () {
// User clicked "Pause" button.
});
"আগের ট্র্যাক" এবং "পরবর্তী ট্র্যাক" উইন্ডো নিয়ন্ত্রণগুলি দেখানো একই রকম৷ তাদের জন্য মিডিয়া সেশন অ্যাকশন হ্যান্ডলার সেট করা সেগুলিকে পিকচার-ইন-পিকচার উইন্ডোতে দেখাবে এবং আপনি এই অ্যাকশনগুলি পরিচালনা করতে সক্ষম হবেন।
navigator.mediaSession.setActionHandler('previoustrack', function () {
// User clicked "Previous Track" button.
});
navigator.mediaSession.setActionHandler('nexttrack', function () {
// User clicked "Next Track" button.
});
এটি কার্যকরভাবে দেখতে, অফিসিয়াল মিডিয়া সেশন নমুনা চেষ্টা করে দেখুন।
পিকচার-ইন-পিকচার উইন্ডো সাইজ পান
আপনি যদি ভিডিওর গুণমান সামঞ্জস্য করতে চান যখন ভিডিওটি পিকচার-ইন-পিকচারে প্রবেশ করে এবং ছেড়ে যায়, তাহলে আপনাকে পিকচার-ইন-পিকচার উইন্ডোর আকার জানতে হবে এবং যদি কোনও ব্যবহারকারী নিজে উইন্ডোটির আকার পরিবর্তন করেন তবে আপনাকে অবহিত করতে হবে।
নীচের উদাহরণটি দেখায় কিভাবে পিকচার-ইন-পিকচার উইন্ডোর প্রস্থ এবং উচ্চতা পাওয়া যায় যখন এটি তৈরি করা হয় বা পুনরায় আকার দেওয়া হয়।
let pipWindow;
videoElement.addEventListener('enterpictureinpicture', function (event) {
pipWindow = event.pictureInPictureWindow;
console.log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
pipWindow.addEventListener('resize', onPipWindowResize);
});
videoElement.addEventListener('leavepictureinpicture', function (event) {
pipWindow.removeEventListener('resize', onPipWindowResize);
});
function onPipWindowResize(event) {
console.log(
`> Window size changed to ${pipWindow.width}x${pipWindow.height}`
);
// TODO: Change video quality based on Picture-in-Picture window size.
}
আমি পরামর্শ দিচ্ছি রিসাইজ ইভেন্টে সরাসরি হুক না করার কারণ পিকচার-ইন-পিকচার উইন্ডো সাইজে করা প্রতিটি ছোট পরিবর্তন একটি আলাদা ইভেন্ট ফায়ার করবে যা পারফরম্যান্সের সমস্যা হতে পারে যদি আপনি প্রতিটি রিসাইজ করার সময় ব্যয়বহুল অপারেশন করেন। অন্য কথায়, রিসাইজ অপারেশন খুব দ্রুত ইভেন্টগুলিকে বারবার ফায়ার করবে। আমি এই সমস্যাটি সমাধানের জন্য থ্রটলিং এবং ডিবাউন্সিংয়ের মতো সাধারণ কৌশলগুলি ব্যবহার করার পরামর্শ দেব।
বৈশিষ্ট্য সমর্থন
Picture-in-Picture Web API সমর্থিত নাও হতে পারে, তাই আপনাকে প্রগতিশীল বর্ধন প্রদান করতে এটি সনাক্ত করতে হবে। এমনকি যখন এটি সমর্থিত হয়, এটি ব্যবহারকারীর দ্বারা বন্ধ বা অনুমতি নীতি দ্বারা নিষ্ক্রিয় হতে পারে৷ ভাগ্যক্রমে, আপনি এটি নির্ধারণ করতে নতুন বুলিয়ান document.pictureInPictureEnabled
ব্যবহার করতে পারেন.pictureInPictureEnabled।
if (!('pictureInPictureEnabled' in document)) {
console.log('The Picture-in-Picture Web API is not available.');
} else if (!document.pictureInPictureEnabled) {
console.log('The Picture-in-Picture Web API is disabled.');
}
একটি ভিডিওর জন্য একটি নির্দিষ্ট বোতাম উপাদানে প্রয়োগ করা হয়েছে, এইভাবে আপনি আপনার পিকচার-ইন-পিকচার বোতামের দৃশ্যমানতা পরিচালনা করতে চাইতে পারেন।
if ('pictureInPictureEnabled' in document) {
// Set button ability depending on whether Picture-in-Picture can be used.
setPipButton();
videoElement.addEventListener('loadedmetadata', setPipButton);
videoElement.addEventListener('emptied', setPipButton);
} else {
// Hide button if Picture-in-Picture is not supported.
pipButtonElement.hidden = true;
}
function setPipButton() {
pipButtonElement.disabled =
videoElement.readyState === 0 ||
!document.pictureInPictureEnabled ||
videoElement.disablePictureInPicture;
}
মিডিয়াস্ট্রিম ভিডিও সমর্থন
মিডিয়াস্ট্রিম অবজেক্টে ভিডিও চালানো (যেমন getUserMedia()
, getDisplayMedia()
, canvas.captureStream()
) এছাড়াও Chrome 71-এ Picture-in-Picture সমর্থন করে। এর মানে হল আপনি একটি Picture-in-Picture উইন্ডো দেখাতে পারেন যাতে ব্যবহারকারীর ওয়েবক্যাম ভিডিও স্ট্রীম রয়েছে, প্রদর্শন ভিডিও স্ট্রিম, বা এমনকি একটি ক্যানভাস উপাদান. মনে রাখবেন যে ভিডিও উপাদানটি নীচে দেখানো হিসাবে Picture-in-Picture এ প্রবেশ করার জন্য DOM-এর সাথে সংযুক্ত হতে হবে না।
পিকচার-ইন-পিকচার উইন্ডোতে ব্যবহারকারীর ওয়েবক্যাম দেখান
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
পিকচার-ইন-পিকচার উইন্ডোতে ডিসপ্লে দেখান
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getDisplayMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
পিকচার-ইন-পিকচার উইন্ডোতে ক্যানভাস উপাদান দেখান
const canvas = document.createElement('canvas');
// Draw something to canvas.
canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height);
const video = document.createElement('video');
video.muted = true;
video.srcObject = canvas.captureStream();
video.play();
// Later on, video.requestPictureInPicture();
canvas.captureStream()
কে মিডিয়া সেশন API-এর সাথে একত্রিত করে, আপনি উদাহরণস্বরূপ Chrome 74-এ একটি অডিও প্লেলিস্ট উইন্ডো তৈরি করতে পারেন। অফিসিয়াল অডিও প্লেলিস্ট নমুনাটি দেখুন।
নমুনা, ডেমো এবং কোডল্যাব
Picture-in-Picture Web API ব্যবহার করে দেখতে আমাদের অফিসিয়াল Picture-in-Picture নমুনা দেখুন।
ডেমো এবং কোডল্যাব অনুসরণ করবে।
এরপর কি
প্রথমে, ক্রোম এবং অন্যান্য ব্রাউজারে বর্তমানে API-এর কোন অংশ প্রয়োগ করা হয়েছে তা জানতে বাস্তবায়নের স্থিতি পৃষ্ঠাটি দেখুন।
অদূর ভবিষ্যতে আপনি যা দেখতে পাবেন তা এখানে:
- ওয়েব ডেভেলপাররা কাস্টম পিকচার-ইন-পিকচার কন্ট্রোল যোগ করতে পারবে।
- একটি ভাসমান উইন্ডোতে নির্বিচারে
HTMLElement
বস্তু প্রদর্শনের জন্য একটি নতুন ওয়েব API প্রদান করা হবে।
ব্রাউজার সমর্থন
Picture-in-Picture Web API Chrome, Edge, Opera এবং Safari-এ সমর্থিত। বিস্তারিত জানার জন্য MDN দেখুন।
সম্পদ
- ক্রোম বৈশিষ্ট্য স্থিতি: https://www.chromestatus.com/feature/5729206566649856
- ক্রোম ইমপ্লিমেন্টেশন বাগ: https://crbug.com/?q=component:Blink>Media>PictureInPicture
- পিকচার-ইন-পিকচার ওয়েব API স্পেক: https://wicg.github.io/picture-in-picture
- বিশেষ সমস্যা: https://github.com/WICG/picture-in-picture/issues
- নমুনা: https://googlechrome.github.io/samples/picture-in-picture/
- অনানুষ্ঠানিক পিকচার-ইন-পিকচার পলিফিল: https://github.com/gbentaieb/pip-polyfill/
Picture-in-Picture-এ কাজ করার জন্য Mounir Lamouri এবং Jennifer Apacible- কে অনেক ধন্যবাদ এবং এই নিবন্ধে সাহায্য করুন। এবং প্রমিতকরণ প্রচেষ্টার সাথে জড়িত সবাইকে অনেক ধন্যবাদ।