Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ So far, it includes the following examples:
1. 🌐 URL API
1. 🗒️ Selection API
1. 📃 Page Visibility API
1. 🎛️ Media Session API

# 🤝 Open Source

Expand Down Expand Up @@ -156,6 +157,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center"><a href="https://kvarunkk.github.io/Portfolio_Official/"><img src="https://avatars.githubusercontent.com/u/98093422?v=4?s=100" width="100px;" alt="Varun"/><br /><sub><b>Varun</b></sub></a><br /><a href="https://github.com/atapas/webapis-playground/commits?author=kVarunkk" title="Code">💻</a></td>
<td align="center"><a href="https://supminn-neog.netlify.app/"><img src="https://avatars.githubusercontent.com/u/30731236?v=4?s=100" width="100px;" alt="Supriya M"/><br /><sub><b>Supriya M</b></sub></a><br /><a href="https://github.com/atapas/webapis-playground/commits?author=supminn" title="Code">💻</a></td>
<td align="center"><a href="https://williamssam.netlify.app/"><img src="https://avatars.githubusercontent.com/u/68322437?v=4?s=100" width="100px;" alt="Williams Samuel"/><br /><sub><b>Williams Samuel</b></sub></a><br /><a href="https://github.com/atapas/webapis-playground/commits?author=williamssam" title="Code">💻</a></td>
<td align="center"><a href="https://williamssam.netlify.app/"><img src="https://twitter.com/imThiyagarajan" width="100px;" alt="Thiyagarajan Ravichandran"/><br /><sub><b>Thiyagarajan Ravichandran</b></sub></a><br /><a href="https://github.com/atapas/webapis-playground/commits?author=williamssam" title="Code">💻</a></td>
</tr>
</tbody>
</table>
Expand Down
20 changes: 20 additions & 0 deletions src/modules/apis/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,5 +438,25 @@ export const data: Array<Demo> = [
'https://developer.mozilla.org/en-US/docs/Web/API/EyeDropper_API',
canIUseURL: 'https://caniuse.com/mdn-api_eyedropper',
},
},
{
id: 'media-session-api',
emoji: '🎛️',
title: 'Media Session API',
description:
'The Media Session API provides a way to customize media notifications. It does this by providing metadata for display by the user agent for the media your web app is playing.',
meta: {
author: {
name: 'Thiyagarajan Ravichandran',
social: {
email: '[email protected]',
github: 'imThiyagu',
twitter: 'imThiyagarajan',
},
},
apiDocURL:
'https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API',
canIUseURL: 'https://caniuse.com/mdn-api_mediaSession',
},
}, //replace item here
];
12 changes: 12 additions & 0 deletions src/modules/apis/media-session/data/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"Url" : "https://res.cloudinary.com/dyxp1qhsq/video/upload/v1666438226/samples/MediaSession/Imagine_Dragons_-_Believer_Official_Music_Video_fr7tec.mp4",
"Title" : "Beliver - Imagine Dragons",
"Artist" : "Dan Reynolds,Wayne Sermon,Ben McKee,Daniel Platzman,Robin Fredriksson,Mattias Larsson,Justin Tranter"
},
{
"Url" : "https://res.cloudinary.com/dyxp1qhsq/video/upload/v1666438208/samples/MediaSession/Sia_-_Unstoppable_Lyrics_uqqaix.mp4",
"Title" : "Unstoppable - Sia",
"Artist" : "Sia Furler Christopher Braide"
}
]
156 changes: 156 additions & 0 deletions src/modules/apis/media-session/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import * as getPlayList from '../media-session/data/data.json';

export const hasSupport = () : boolean =>
Boolean('mediaSession' in navigator);

var video_idx = 0;
const totalVideos = Object.keys(getPlayList).length - 2;
var idx = 0;
const defaultSkipSeconds = 10;
let videoSelector = document.querySelector('video');

export function initializingListeners() : any {
videoSelector?.addEventListener('ended', function() {
console.log("song ended");
video_idx= (video_idx - 1 + totalVideos) % totalVideos;
playVideo();
});
}

export function playVideo() : any {
console.log("Inside play video")
videoSelector = document.querySelector('video');
if(hasSupport() && videoSelector!=null){
videoSelector.src = getPlayList[video_idx].Url
console.log(getPlayList[video_idx].Url)
videoSelector?.play().then(_ => updateMetaData())
.catch( error => console.error(error.message));
}
}

function updateMetaData(): any {
if(hasSupport()){
let song = getPlayList[video_idx];

videoSelector = document.querySelector('video');
navigator.mediaSession.metadata = new MediaMetadata({
title: song.Title,
artist: song.Artist
});

if(videoSelector!=null){
videoSelector.title = song.Title;
console.log("Playing " + videoSelector.title + "song...");
}
}
updatePositionalData();
}

function deleteFirstEntry(idx : number){
let specific_tbody = <HTMLTableElement>document.getElementById('logger_events');
specific_tbody.deleteRow(idx);
idx=idx+4;
return idx;
}

function createRowInTable(capturedEvent ?: String) {
let tbl = <HTMLTableElement> document.getElementById('table_log');
tbl.style.border = '1px solid black';

let specific_tbody = <HTMLTableElement>document.getElementById('logger_events');
if(idx>=5){
idx = deleteFirstEntry(idx-5);
}
let row = specific_tbody.insertRow(idx++);

row.style.border = '1px solid black';

var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);

cell1.innerHTML = capturedEvent as string;
cell2.innerHTML = "" + videoSelector?.currentTime;
cell3.innerHTML = "" + videoSelector?.title;
cell1.style.border = cell2.style.border = cell3.style.border = '1px solid black';
}

function updatePositionalData(capturedEvent ?: String) {
if(hasSupport() && 'setPositionState' in navigator.mediaSession) {
let videoSelector = document.querySelector('video');
if(capturedEvent!=null && capturedEvent!='undefined'){
console.log("User selected >>> "+ capturedEvent + " Position updated at :" + videoSelector?.currentTime);
createRowInTable(capturedEvent);
}
navigator.mediaSession.setPositionState(
{
duration: videoSelector?.duration,
playbackRate: videoSelector?.playbackRate,
position: videoSelector?.currentTime
}
);
}
}

export const actionHandlers = [
['play', async () => {
await videoSelector?.play();
updateMetaData();
updatePositionalData('Playing');
}],

['pause' , () => {
videoSelector?.pause();
updateMetaData();
updatePositionalData('Paused');
}],

['stop' , () : any => {
updateMetaData();
updatePositionalData('Stopped');
}],

['previoustrack', () : any => {
if(videoSelector!=null)
videoSelector.currentTime = 0;

video_idx = (video_idx - 1 + totalVideos) % totalVideos;
console.log(video_idx);
updateMetaData();
updatePositionalData('Previous Track');

playVideo();
}],

['nexttrack', () : any => {
if(videoSelector!=null)
videoSelector.currentTime = 0;

video_idx = (video_idx + 1)% totalVideos;
updateMetaData();
updatePositionalData('Next track');

playVideo();
}],

['seekbackward', (event: any) => {
const skipBy = event.seekOffset || defaultSkipSeconds;
if(videoSelector!=null)
videoSelector.currentTime = Math.max(videoSelector.currentTime - skipBy , 0);
updatePositionalData('Seek backward');
}],

['seekforward', (event: any) => {
const ProceedBy = event.seekOffset || defaultSkipSeconds;
if(videoSelector!=null)
videoSelector.currentTime = Math.min(videoSelector.currentTime + ProceedBy , videoSelector.duration);
updatePositionalData('Seek Forward');
}],

['seekto', (event: any)=> {
if(videoSelector!=null)
videoSelector.currentTime = event.seekTime;
updateMetaData();
updatePositionalData('Seek To');
}]
];
61 changes: 61 additions & 0 deletions src/modules/demos/media-session-api/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useEffect } from 'react';
import { actionHandlers,hasSupport, initializingListeners, playVideo } from '@/modules/apis/media-session';
import { NotSupported } from 'components';

function mediaSession() {
useEffect(() => {
playVideo();
initializingListeners();
}, []);

for (const [action, handler] of actionHandlers) {
try {
if(hasSupport()){
navigator.mediaSession.setActionHandler(action as MediaSessionAction,handler as MediaSessionActionHandler);
}
else
return <NotSupported />
}
catch(error){
console.error("The performed action - not supported for the type" + action);
}
}
return (
<div>
<video
id="js-picture--video"
className="tw-w-full tw-mt-4 tw-rounded-lg"
src="https://res.cloudinary.com/atapas/video/upload/v1620052733/demos/earth_rotating_g1xv0f.mp4"
autoPlay
loop
title = ""
controls
/>
<br>
</br>
<div>
Event Logs:

<table id="table_log" style={{width: "108vh" , border: "solid 1px"}}>
<thead>
<tr style={{ border: "solid 1px"}}>
<th style={{ border: "solid 1px"}}>
Selected Event
</th>
<th style={{ border: "solid 1px"}}>
Positional Update
</th>
<th style={{ border: "solid 1px"}}>
Current Track
</th>
</tr>
</thead>
<tbody id = "logger_events">
</tbody>
</table>
</div>
</div>
)
}

export default mediaSession;
Loading