Encountering issues with MediaSession.setPositionState() and seekto functionalities not functioning properly

Having trouble with MediaSession.setPositionState() not displaying the audio time and seekbar not behaving as expected.

const sound= document.querySelector('sound');

function updatePositionState() {
  if ('setPositionState' in navigator.mediaSession) {
    navigator.mediaSession.setPositionState({
      duration: sound.duration,
      playbackRate: sound.playbackRate,
      position: sound.currentTime,
    });
  }
}

await sound.play();
updatePositionState();

navigator.mediaSession.setActionHandler('seekto', (details) => {
  updatePositionState();
});

https://i.sstatic.net/HzWLo.png

Answer №1

Here is the solution that helped me:

sound = document.querySelector("audio");
navigator.mediaSession.setActionHandler('skipforward', (details) => {
        sound.currentTime = details.skipTime;
    });

Answer №2

Encountered a similar situation.

While cleaning up, I decided that the following code was unnecessary for now:

navigator.mediaSession.setActionHandler("seekbackward", (data) => {
        console.log('seekBackward: data: ', data);
        // seekBackward: data: { action: 'seekbackward' }
      });
      navigator.mediaSession.setActionHandler("seekforward", (data) => {
        console.log('seekForward: data: ', data);
        // seekForward: data:  {action: 'seekforward'}
      });

After commenting out the above code, the seek bar became visible on my Mobile Device but remained hidden on the desktop. It seems that having skip forward and backward buttons may disable the seekTo function in the MediaSession API.

Although the seekTo bar is now visible and functional, it starts at an incorrect position when a track begins playing.

Unable to locate a way to set the track's runtime in the MediaSession API for streaming purposes.

There was speculation that adding a seek bar to a stream was not feasible. 🤷‍♀️

Answer №3

function initialize_media_controls() {
    if (!("mediaSession" in navigator)) {
        recordMessage(`No mediaSession available in this browser.`,2);
    }
    const audioElement = document.querySelector('audio');
    const defaultSkipTime = 60; /* Default time to skip in seconds */

    const controlActions = [
        ['play',            () => { audioElement.play(); }],
        ['pause',           () => { audioElement.pause(); }],
        ['previoustrack',   () => { audioElement.currentTime = 0; }],
        ['nexttrack',       () => { loadSongFromIndex(); }],
        ['stop',            () => { audioElement.pause(); }],
        ['seekbackward',    (details) => {  
                                    const skipTime = details.seekOffset || defaultSkipTime; 
                                    audioElement.currentTime = Math.max(audioElement.currentTime - skipTime, 0); 
                                    navigator.mediaSession.setPositionState({duration: audioElement.duration, playbackRate: audioElement.playbackRate, position: audioElement.currentTime});
                                }],
        ['seekforward',     (details) => {  
                                    const skipTime = details.seekOffset || defaultSkipTime; 
                                    audioElement.currentTime = Math.min(audioElement.currentTime + skipTime, 0); 
                                    navigator.mediaSession.setPositionState({duration: audioElement.duration, playbackRate: audioElement.playbackRate, position: audioElement.currentTime});
                                }],
        ['seekto',          (details) => {  
                                    if (details.fastSeek && 'fastSeek' in audioElement) { 
                                        audioElement.fastSeek(details.seekTime); 
                                    } else { 
                                        audioElement.currentTime = details.seekTime; 
                                    } 
                                    navigator.mediaSession.setPositionState({duration: audioElement.duration, playbackRate: audioElement.playbackRate, position: audioElement.currentTime});
                                }]
    ];
    for (const [action, handler] of controlActions) {
        try {
            navigator.mediaSession.setActionHandler(action, handler);
        } catch (error) {
            recordMessage(`The action "${action}" is not supported by the media session yet.`,2);
        }
    }
    try {
        // Set playback event listeners
        audioElement.addEventListener('play', () => { navigator.mediaSession.playbackState = 'playing'; });
        audioElement.addEventListener('pause', () => { navigator.mediaSession.playbackState = 'paused'; });
    }
    catch (err) {
        recordMessage(`Failed to set play/pause handlers for navigator.mediaSession.playbackState`,2);
    }
}

For an example implementing the above function, refer to https://github.com/Noah-Jaffe/Mixcloud_player/blob/main/MUSICPLAYER.html. This function handles all audio media controls.

When using an Android device with Chrome, the functionality can be seen as depicted in the following image: https://i.sstatic.net/gp61W.jpg

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with minified scripts on a particular server

Apologies if this has already been addressed, but I've been searching for a solution for hours. I created a basic website that works perfectly on my own hosting. However, when I transfer it to new hosting (same company, same package, different server ...

Angular progress tracker with stages

I have been exploring ways to create a progress bar with steps in Angular 12 that advances based on the percentage of progress rather than just moving directly from one step to another. This is specifically for displaying membership levels and indicating h ...

Tips for removing unnecessary debugging code from JavaScript when compiling or minifying your code

Back in the day, I would always include tons of debug code in my JavaScript app. However, I'm now searching for a method that will eliminate debug code during the compilation/minification phase. Does the world of JavaScript have something similar to ...

Single parallax movement determined by the position of the mouse cursor, with no margins

Recently came across this interesting code snippet [http://jsfiddle.net/X7UwG/][1]. It displays a parallax effect when moving the mouse to the left, but unfortunately shows a white space when moving to the right. Is there a way to achieve a seamless single ...

The autocomplete feature fails to properly highlight the selected value from the dropdown menu and ends up selecting duplicate values

After working on creating a multiple select search dropdown using MUI, my API data was successfully transformed into the desired format named transformedSubLocationData. https://i.stack.imgur.com/ZrbQq.png 0: {label: 'Dialed Number 1', value: &a ...

Save information in a nested object within local storage by utilizing a dynamic key

Storing the below object in localStorage to simulate server-side login/logout functionalities. Current user logic is implemented to identify the logged-in user. let defaultUsers = [ { email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" ...

What is the best way to bring in local modules within the browser environment using Playwright?

Let me illustrate what I am attempting to achieve: ../src/Foo/Bar.ts represents a local TypeScript file This particular file contains code that is designed to function within a browser environment (it utilizes WebSockets), and therefore needs to be execu ...

The location layer on my Google Maps is not appearing

For a school project, I am working on developing a mobile-first website prototype that includes Google Maps integration. I have successfully added a ground overlay using this image, but I am facing issues with enabling the "my location layer". When I tried ...

Correcting the invalid syntax due to EOF issue

How can we resolve the end of file error? The brackets appear to be valid based on ecma standards, but it's not clear what is missing. After using jsonlint, this error was found: *Error: Parse error on line 16: ...States" }] }]}{ "i ...

Baffled by the data visualization produced by Google Chart using information from

Perhaps I'm being a bit ambitious, but I managed to create a basic Chart using GoogleCharts. The problem is that I have to input the values manually, but I want to retrieve them from the Database. I know JSON can accomplish this, but I've spent f ...

Can the data cells of columns be dynamically adjusted to align them on a single vertical line?

For some time now, I have been grappling with a CSS issue. I am working with a table that has 3 columns displaying departures, times, and situational text for scenarios like delays or cancellations. However, as evident from the images, the alignment of th ...

Retrieving values from multiple Select components in Material-UI is key

I have encountered an issue with my two MUI Select components on the page. I am attempting to set values based on the id of the Select component. Initially, when I check (id === "breed-select") in the console, it returns true, but shortly after ...

Nested solution object populated with promises

Looking for a solution similar to the npm libraries p-props and p-all, but with the added functionality of recursively resolving promises. const values = { a: () => Promise.resolve(1), b: [() => Promise.resolve(2)], c: { d: () =&g ...

What is the best way to organize a json based on numerical values?

Can anyone guide me through sorting a JSON data into an array based on numeric value, and then explain how to efficiently access that information? {"362439239671087109":{"coins":19},"178538363954003968":{"coins":18},"234255082345070592":{"coins":137}} Th ...

Is there a way to reset the selected value of a specific option in Mat-Select?

Using mat-select, I need to reset the selection for a specific value of mat-select's mat-option. For instance, take a look at this example on StackBlitz In the example, the mat-select has three options; when selecting Canada, it should revert back t ...

What is the process for establishing a dependency on two distinct JavaScript files, similar to the depends-on feature found in TestNG?

I am faced with a scenario where I have two separate JS files containing test methods, namely File1 and File2. The requirement is that File2.js should only be executed if File1.js has successfully completed its execution. My current setup involves using ...

What is the best way to organize the Firebase data that is stored under the user's unique

Hey there, I'm currently working on developing a leaderboard feature for an app. The idea is that users will be able to store their "points" in a Firebase database, linked to their unique user ID. This is how the data is structured in JSON format: ...

React: State does not properly update following AJAX request

I'm currently facing a challenge in my React project where I need to make two AJAX calls and update the UI based on the data received. Below is the implementation of my render method: render() { if (this.state.examsLoaded) { return ( ...

What is the best way to showcase the output of a Perl script on a webpage

I recently came across a resource discussing the process of executing a perl script from a webpage. What is the best way to run a perl script from a webpage? However, I am facing a situation where the script I have takes more than 30 seconds to run and d ...

Google Maps does not support markers appearing on the map

I have created a basic web application that displays markers from a MySQL database on Google Maps using a table called markers_titik. In order to process this data, I have written a simple PHP script named map_process.php. Here is the code: <?php //PH ...