{"id":27935,"date":"2022-08-09T10:42:18","date_gmt":"2022-08-09T10:42:18","guid":{"rendered":"http:\/\/modify-media-notifications-with-media-sessions-api"},"modified":"2022-08-09T10:42:18","modified_gmt":"2022-08-09T10:42:18","slug":"modify-media-notifications-with-media-sessions-api","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/","title":{"rendered":"Modify Media Notifications with Media Sessions API"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>The Media Sessions API provides a way to customize media notifications. Let\u2019s imagine this scenario. You have multiple tabs opened with audio and videos playing on each of them and let\u2019s say you want to pause the tab playing \u201cN.Y State of Mind by Nas\u201d, and you don\u2019t want to go to that specific tab to pause the audio. You wished you had a way to control media playback right? That\u2019s where Media Sessions API come in.<\/p>\n<p>The Media Sessions API customizes media notifications by providing metadata for display by the user agent for the media your web app is playing. The API provides us with two interfaces namely;<\/p>\n<ul>\n<li>MediaSession<\/li>\n<li>MediaMetadata<\/li>\n<\/ul>\n<p>The MediaSession interface is what allows the user to control media playback actions such as play, pause, previoustrack, nexttrack, etc.\nThe MediaMetadata interface as it name implies, allows us to add metadata of the media we want to play. It creates a MediaMetadata object that consists of the following properties;<\/p>\n<ul>\n<li>\n<code>MediaMetadata.title<\/code>\n<\/li>\n<li>\n<code>MediaMetadata.artist<\/code>\n<\/li>\n<li>\n<code>MediaMetadata.album<\/code>\n<\/li>\n<li>\n<code>MediaMetadata.artwork<\/code>\n<\/li>\n<\/ul>\n<p>In this article, we\u2019ll be building a media controller for audio tracks using the Media Sessions API and Cloudinary for the audio files.<\/p>\n<h2>Pre-requisites<\/h2>\n<p>To flow with this tutorial, you\u2019ll need the following:<\/p>\n<ul>\n<li>Knowledge of JavaScript<\/li>\n<li>A code editor (VS Code preferably)<\/li>\n<\/ul>\n<p>The complete code and demo is here on <a href=\"https:\/\/codesandbox.io\/embed\/throbbing-tree-jhck7p?fontsize=14&amp;hidenavigation=1&amp;theme=dark\">Codesandbox.<\/a><\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/throbbing-tree-jhck7p?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"throbbing-tree-jhck7p?\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><h2>Building the Media Controller<\/h2>\n<p>Firstly, if you want to follow through with the article, you should create a cloudinary account, and upload some mp3 files and images in seperate folders. This is how it looks on my end:<\/p>\n<ul>\n<li>\n<p>I have a music folder\n<img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_CE3FCAD77D761605706B97EBA01653299B47847857DC12956575779E4238D1A4_1658687152917_Screenshot+2022-07-24+at+19.25.36.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"516\"\/><\/p>\n<\/li>\n<li>\n<p>Inside the music folder, i have two more folders for individual artists\n<img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_CE3FCAD77D761605706B97EBA01653299B47847857DC12956575779E4238D1A4_1658687223151_Screenshot+2022-07-24+at+19.26.50.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1106\"\/><\/p>\n<\/li>\n<li>\n<p>Each of the folders contain an audio file and images of different sizes\n<img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_CE3FCAD77D761605706B97EBA01653299B47847857DC12956575779E4238D1A4_1658687411299_Screenshot+2022-07-24+at+19.30.00.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1097\"\/><\/p>\n<\/li>\n<\/ul>\n<p>Now we\u2019ve set up the folder structure on cloudinary, let\u2019s go ahead and build the media controller.\nCreate a folder, i\u2019ll call mine <code>media-notifications-controller<\/code>, open it with your code editor and create an <code>index.html<\/code>. Add these lines of code to the HTML file:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">\/\/index.html\n<span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span> <span class=\"hljs-attr\">lang<\/span>=<span class=\"hljs-string\">\"en\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">charset<\/span>=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">http-equiv<\/span>=<span class=\"hljs-string\">\"X-UA-Compatible\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"IE=edge\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"viewport\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>MediaSession API for Audio<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span> Media Session API for Audio <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"playButton\"<\/span>&gt;<\/span>Start Playlist<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"\/main.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Here, we have a button with an id <code>playButton<\/code>, we\u2019ll be using that id soon in the <code>main.js<\/code> JavaScript file. So let\u2019s go ahead and create a <code>main.js<\/code>. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/main.js<\/span>\n<span class=\"hljs-keyword\">let<\/span> audio = <span class=\"hljs-built_in\">document<\/span>.createElement(<span class=\"hljs-string\">'audio'<\/span>);\n<span class=\"hljs-keyword\">const<\/span> button = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'playButton'<\/span>)\nbutton.addEventListener(<span class=\"hljs-string\">'click'<\/span>, onPlayButtonClick)\n<span class=\"hljs-keyword\">let<\/span> playlist = getAwesomePlaylist();\n<span class=\"hljs-keyword\">let<\/span> index = <span class=\"hljs-number\">0<\/span>;\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">onPlayButtonClick<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    playAudio();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Firstly, we are creating an audio element (we\u2019ll get to it very soon). Then we say, whenever a user clicks the START PLAYLIST button, it should invoke the <code>onPlayButtonClick()<\/code> function. The <code>onPlayButtonClick()<\/code> calls another function called <code>playAudio()<\/code>. Let\u2019s now create the <code>playAudio()<\/code> function. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">playAudio<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    audio.src = playlist&#91;index].src;\n    audio.play()\n        .then(<span class=\"hljs-function\"><span class=\"hljs-params\">_<\/span> =&gt;<\/span> updateMetadata())\n        .catch(<span class=\"hljs-function\"><span class=\"hljs-params\">error<\/span> =&gt;<\/span> <span class=\"hljs-built_in\">console<\/span>.log(error));\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The first thing that happens here is assigning playlist audio source (we\u2019ll be creating soon) to the HTML audio element we created earlier. Next, we invoked the <code>audio.play()<\/code>  method and then we return a Promise to invoke the <code>updateMetadata()<\/code> function if successful, if not, we print the error to our browser console. Let\u2019s now create the <code>updateMetadata()<\/code>. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">updateMetadata<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">let<\/span> track = playlist&#91;index];\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Playing '<\/span> + track.title + <span class=\"hljs-string\">' track...'<\/span>);\n    navigator.mediaSession.metadata = <span class=\"hljs-keyword\">new<\/span> MediaMetadata({\n        <span class=\"hljs-attr\">title<\/span>: track.title,\n        <span class=\"hljs-attr\">artist<\/span>: track.artist,\n        <span class=\"hljs-attr\">album<\/span>: track.album,\n        <span class=\"hljs-attr\">artwork<\/span>: track.artwork\n    });\n    updatePositionState();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Here, we introduce the <code>MediaMetadata<\/code> interface of the Media Sessions API. This will enable us add information such as title, artist, album and artwork to the Media Controller. We invoke a <code>updatePositionState()<\/code> function, this enables us to set playback position. It\u2019s important to know that the position state is a combination of the media playback rate, duration, and current time. Let\u2019s go ahead and create that function. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">updatePositionState<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-string\">'setPositionState'<\/span> <span class=\"hljs-keyword\">in<\/span> navigator.mediaSession) {\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Updating position state...'<\/span>);\n        navigator.mediaSession.setPositionState({\n            <span class=\"hljs-attr\">duration<\/span>: audio.duration,\n            <span class=\"hljs-attr\">playbackRate<\/span>: audio.playbackRate,\n            <span class=\"hljs-attr\">position<\/span>: audio.currentTime\n        });\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>You will notice that <code>setPositionState<\/code> accepts duration, playbackRate and position as arguments and we are getting the values from our <code>audio<\/code> element.\nNext, we\u2019ll handle actions. To handle actions we will use the MediaSession interface method <code>setActionHandler()<\/code>.\nLet\u2019s create the action handler for playing previous track. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\nnavigator.mediaSession.setActionHandler(<span class=\"hljs-string\">'previoustrack'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'You clicked \"Previous Track\" icon.'<\/span>);\n    index = (index - <span class=\"hljs-number\">1<\/span> + playlist.length) % playlist.length;\n    playAudio();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The action handler for next track. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\nnavigator.mediaSession.setActionHandler(<span class=\"hljs-string\">'nexttrack'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'&gt; You clicked \"Next Track\" icon.'<\/span>);\n    index = (index + <span class=\"hljs-number\">1<\/span>) % playlist.length;\n    playAudio();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The action handler for when a track has ended.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">audio.addEventListener(<span class=\"hljs-string\">'ended'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n    index = (index - <span class=\"hljs-number\">1<\/span> + playlist.length) % playlist.length;\n    playAudio();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>When a track ends, this action handler enables the controller to play the next track automatically.<\/p>\n<p>Typically, a media controller will have fast forward and backwards buttons. Let\u2019s create the action handlers for each of them.\nThe action handler to go backwards. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\n<span class=\"hljs-keyword\">let<\/span> defaultSkipTime = <span class=\"hljs-number\">10<\/span>; <span class=\"hljs-comment\">\/* Time to skip in seconds by default *\/<\/span>\n    navigator.mediaSession.setActionHandler(<span class=\"hljs-string\">'seekbackward'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\">event<\/span>) <\/span>{\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'You clicked \"Seek Backward\" icon.'<\/span>);\n    <span class=\"hljs-keyword\">const<\/span> skipTime = event.seekOffset || defaultSkipTime;\n    audio.currentTime = <span class=\"hljs-built_in\">Math<\/span>.max(audio.currentTime - skipTime, <span class=\"hljs-number\">0<\/span>);\n    updatePositionState();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The action handler to fast forward. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/main.js<\/span>\nnavigator.mediaSession.setActionHandler(<span class=\"hljs-string\">'seekforward'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\">event<\/span>) <\/span>{\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'You clicked \"Seek Forward\" icon.'<\/span>);\n    <span class=\"hljs-keyword\">const<\/span> skipTime = event.seekOffset || defaultSkipTime;\n    audio.currentTime = <span class=\"hljs-built_in\">Math<\/span>.min(audio.currentTime + skipTime, audio.duration);\n    updatePositionState();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next, we\u2019ll create action handlers for play and pause buttons. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\nnavigator.mediaSession.setActionHandler(<span class=\"hljs-string\">'play'<\/span>, <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'You clicked \"Play\" icon.'<\/span>);\n    <span class=\"hljs-keyword\">await<\/span> audio.play();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\nnavigator.mediaSession.setActionHandler(<span class=\"hljs-string\">'pause'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'You clicked \"Pause\" icon.'<\/span>);\n    audio.pause();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Sometimes when fast forwarding or loading a track, the browser may consider the webpage to not be playing the audio track, we have to override this behavior. Add these lines of code to do that:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\naudio.addEventListener(<span class=\"hljs-string\">'play'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n    navigator.mediaSession.playbackState = <span class=\"hljs-string\">'playing'<\/span>;\n});\naudio.addEventListener(<span class=\"hljs-string\">'pause'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n    navigator.mediaSession.playbackState = <span class=\"hljs-string\">'paused'<\/span>;\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Let\u2019s create one last action handler. This will be for the stop action. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\n\n<span class=\"hljs-keyword\">try<\/span> {\n    navigator.mediaSession.setActionHandler(<span class=\"hljs-string\">'stop'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\"><\/span>) <\/span>{\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'&gt; User clicked \"Stop\" icon.'<\/span>);\n    });\n} <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Warning! The \"stop\" media session action is not supported.'<\/span>);\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Awesome!\nWe are almost done. Let\u2019s now go ahead and create the <code>getAwesomePlaylist<\/code> function. This function will return the track data. Add these lines of code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/main.js<\/span>\n    \n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getAwesomePlaylist<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">const<\/span> BASE_URL = <span class=\"hljs-string\">'https:\/\/res.cloudinary.com\/sammy365\/video\/upload\/v1658489677\/music\/'<\/span>;\n    <span class=\"hljs-keyword\">const<\/span> IMG_BASE_URL = <span class=\"hljs-string\">'https:\/\/res.cloudinary.com\/sammy365\/image\/upload\/v1658489645\/music\/'<\/span>;\n\n<span class=\"hljs-keyword\">return<\/span> &#91;{\n    <span class=\"hljs-attr\">src<\/span>: BASE_URL + <span class=\"hljs-string\">'Asake\/Asake-PBUY.mp3'<\/span>,\n    <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">'PBUY'<\/span>,\n    <span class=\"hljs-attr\">artist<\/span>: <span class=\"hljs-string\">'Asake'<\/span>,\n    <span class=\"hljs-attr\">album<\/span>: <span class=\"hljs-string\">'Asake Reloaded'<\/span>,\n    <span class=\"hljs-attr\">artwork<\/span>: &#91;\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'Asake\/asake-96.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'96x96'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'Asake\/asake-128.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'128x128'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'Asake\/asake-192.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'192x192'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'Asake\/asake-384.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'384x384'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'Asake\/asake-512.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'512x512'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n    ]\n    },\n    {\n    <span class=\"hljs-attr\">src<\/span>: BASE_URL + <span class=\"hljs-string\">'olamide\/Bad_Boy_Timz_-_Skelele_Official_Audio_ft._Olamide.mp3'<\/span>,\n    <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">'Skelele'<\/span>,\n    <span class=\"hljs-attr\">artist<\/span>: <span class=\"hljs-string\">'Olamide'<\/span>,\n    <span class=\"hljs-attr\">album<\/span>: <span class=\"hljs-string\">'Olamide Reloaded'<\/span>,\n    <span class=\"hljs-attr\">artwork<\/span>: &#91;\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'olamide\/olamide-96.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'96x96'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'olamide\/olamide-128.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'128x128'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'olamide\/olamide-192.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'192x192'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'olamide\/olamide-384.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'384x384'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n        { <span class=\"hljs-attr\">src<\/span>: IMG_BASE_URL + <span class=\"hljs-string\">'olamide\/olamide-512.png'<\/span>, <span class=\"hljs-attr\">sizes<\/span>: <span class=\"hljs-string\">'512x512'<\/span>, <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'image\/png'<\/span> },\n    ]\n    }\n];\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Yep! that\u2019s it. Open the website with Live Server and you should see something like this:<\/p>\n<p><a href=\"https:\/\/www.dropbox.com\/s\/202qnwf49e34dc4\/mediaSession.webm?dl=0\">https:\/\/www.dropbox.com\/s\/202qnwf49e34dc4\/mediaSession.webm?dl=0<\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>In this article, we explored the MediaSessions API. We discussed about it\u2019s two interfaces namely; MediaSession and MediaMetadata. We went ahead to build a media controller with JavaScript using the MediaSessions API. I hope you\u2019ve picked up a thing or two from this article.<\/p>\n<p>Further Reading<\/p>\n<ul>\n<li>Media Sessions API MDN (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Media_Session_API\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Media_Session_API<\/a>)<\/li>\n<li>Customize media notifications and playback controls with the Media Session API (<a href=\"https:\/\/web.dev\/media-session\/\">https:\/\/web.dev\/media-session\/<\/a>)<\/li>\n<li>Give Users Control: The Media Session API (<a href=\"https:\/\/css-tricks.com\/give-users-control-the-media-session-api\/\">https:\/\/css-tricks.com\/give-users-control-the-media-session-api\/<\/a>)<\/li>\n<\/ul>\n<p>Happy Coding!<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27936,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[389,134,145,177,371],"class_list":["post-27935","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-audio","tag-guest-post","tag-html5","tag-javascript","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Modify Media Notifications with Media Sessions API<\/title>\n<meta name=\"description\" content=\"The Media Sessions API provides a way to customize media notifications. Let\u2019s imagine this scenario. You have multiple tabs opened with audio and videos playing on each of them and let\u2019s say you want to pause the tab playing \u201cN.Y State of Mind by Nas\u201d, and you don\u2019t want to go to that specific tab to pause the audio. You wished you had a way to control media playback right? That\u2019s where Media Sessions API come in.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Modify Media Notifications with Media Sessions API\" \/>\n<meta property=\"og:description\" content=\"The Media Sessions API provides a way to customize media notifications. Let\u2019s imagine this scenario. You have multiple tabs opened with audio and videos playing on each of them and let\u2019s say you want to pause the tab playing \u201cN.Y State of Mind by Nas\u201d, and you don\u2019t want to go to that specific tab to pause the audio. You wished you had a way to control media playback right? That\u2019s where Media Sessions API come in.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-08-09T10:42:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1728\" \/>\n\t<meta property=\"og:image:height\" content=\"662\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Modify Media Notifications with Media Sessions API\",\"datePublished\":\"2022-08-09T10:42:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA\",\"keywords\":[\"Audio\",\"Guest Post\",\"HTML5\",\"Javascript\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/\",\"name\":\"Modify Media Notifications with Media Sessions API\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA\",\"datePublished\":\"2022-08-09T10:42:18+00:00\",\"description\":\"The Media Sessions API provides a way to customize media notifications. Let\u2019s imagine this scenario. You have multiple tabs opened with audio and videos playing on each of them and let\u2019s say you want to pause the tab playing \u201cN.Y State of Mind by Nas\u201d, and you don\u2019t want to go to that specific tab to pause the audio. You wished you had a way to control media playback right? That\u2019s where Media Sessions API come in.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA\",\"width\":1728,\"height\":662},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Modify Media Notifications with Media Sessions API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Modify Media Notifications with Media Sessions API","description":"The Media Sessions API provides a way to customize media notifications. Let\u2019s imagine this scenario. You have multiple tabs opened with audio and videos playing on each of them and let\u2019s say you want to pause the tab playing \u201cN.Y State of Mind by Nas\u201d, and you don\u2019t want to go to that specific tab to pause the audio. You wished you had a way to control media playback right? That\u2019s where Media Sessions API come in.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/","og_locale":"en_US","og_type":"article","og_title":"Modify Media Notifications with Media Sessions API","og_description":"The Media Sessions API provides a way to customize media notifications. Let\u2019s imagine this scenario. You have multiple tabs opened with audio and videos playing on each of them and let\u2019s say you want to pause the tab playing \u201cN.Y State of Mind by Nas\u201d, and you don\u2019t want to go to that specific tab to pause the audio. You wished you had a way to control media playback right? That\u2019s where Media Sessions API come in.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-08-09T10:42:18+00:00","og_image":[{"width":1728,"height":662,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/"},"author":{"name":"","@id":""},"headline":"Modify Media Notifications with Media Sessions API","datePublished":"2022-08-09T10:42:18+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA","keywords":["Audio","Guest Post","HTML5","Javascript","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/","name":"Modify Media Notifications with Media Sessions API","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA","datePublished":"2022-08-09T10:42:18+00:00","description":"The Media Sessions API provides a way to customize media notifications. Let\u2019s imagine this scenario. You have multiple tabs opened with audio and videos playing on each of them and let\u2019s say you want to pause the tab playing \u201cN.Y State of Mind by Nas\u201d, and you don\u2019t want to go to that specific tab to pause the audio. You wished you had a way to control media playback right? That\u2019s where Media Sessions API come in.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA","width":1728,"height":662},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/modify-media-notifications-with-media-sessions-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Modify Media Notifications with Media Sessions API"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922350\/Web_Assets\/blog\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e\/f501ff99410cc38d22ef37b4780b50e5194d6f95-1728x662-1_27936e084e.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27935","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=27935"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27935\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27936"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27935"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27935"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27935"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}