Audio Player feature is slow at loading the tracks

I have an issue with the “Audio Player” feature. For some reason, it takes a minute, sometimes even more, before loading the tracks, and I don’t know why. Initially, I thought the reason was that I wasn’t subscribed to any plan and was using the free version. Then I purchased the plan, and I’m having the same issue. Could you please help me fix this? The website is not officially live since I am waiting to fix this. Thank you :slight_smile:

1 Like

Hi there @James_Franz :wave:

I am genuinely sorry for this issue!

Your request is with our devs now. I’ll get back to you once I receive a response from them :slightly_smiling_face:

Unfortunately, the size of your audio files affects the track loading speed and there is nothing we can do with it. I am really sorry :pensive:

Please let me know if this clarifies the situation or if any further questions come up. I’ll be happy to help!

1 Like

Thanks for letting me know! It was working fine in the beginning. I recently noticed the issue when I uploaded more tracks!

1 Like

You are most welcome :wink:

This is the best widget I’ve seen on the Internet, and I don’t want to cancel my subscription just because this widget in particular is not working as I expected. Is there a way to improve and fix it? I am a music producer, so this widget is essential to me, and I’m sure other people and artists are using it. I’ve seen other people complaining about this issue, and honestly, we can’t create 80 different widgets and upload ten songs each. It doesn’t make any sense! Let me/us know if the issues can be fixed, or I will have to cancel my subscription! Thank you so much for your support :pray:t2:

1 Like

I turned off the “duration” setting. It’s working now (I’m not sure for how long, though), but let me know if there is a way to fix this in the future because I would like to display the duration as well and add way more tracks to the audio player since I am a music composer and want to offer a streaming service to my clients, and not turn it off to make this widget work. Thanks again

1 Like

Hi @James_Franz :wave:

I completely understand your feelings and I am really sorry for all the inconvenience!

  1. You’re absolutely right! The widget’s loading speed is affected when Duration is enabled, as it loads all tracks at once. When Duration isn’t displayed, the widget only loads the selected track. We do realize the importance of displaying duration without compromising loading speed, and our developers are working on improving this. It’s hard to say when this enhancement will be released, but we’ll keep you updated on any progress right here.

  2. In the meantime, our devs will be happy to provide you with a custom solution to display duration while maintaining high loading speed. I’ll notify you as soon as I receive a response from them :slightly_smiling_face:

  3. One more reason why the widget takes this much time to load on your website is image size. I’ve checked your website and I see that at the moment, the size of some of them exceed 2MB:

To make it work smoothly, please optimize the pictures using any third-party tool and re-upload them to the widget, this should help. Here are links to some services that we can recommend:

2 Likes

Thank you so much! I will definitely optimize the pictures as well :slight_smile:

2 Likes

Thank you for waiting @James_Franz !

To display the duration, please add the script below to the Custom JS field on the Style tab of your widget’s settings:


const widgetId = 'd584606b-9b51-4a1c-a965-360bd110e9e5';
const initialCache = {
  'Ask, Believe, Receive': 423,
  'Heart Coherence': 423,
  'Inner Peace Elevation': 420,
  'Cosmic Dream': 426,
  'Echoes of Bliss': 420,
  'Memory Whispers': 652,
  'Heaven\'s Whispers': 423,
  'Love Resonance': 518,
  '174 Hz [Heals Physical Pain] Vol.1': 421,
  '285 Hz [Cell Repair] Vol.1': 420,
  '396 Hz [Cleanses-Negativity] Vol.1': 649,
  '417 Hz [Enhances_Creativity] Vol.1': 422,
  '528 Hz [Improves Sleep Quality] Vol.1': 421,
  '639 Hz [Pure Miracle Tone] Vol.1': 420,
  '741 Hz [Purifies Body & Mind] Vol.1': 421,
  '852 Hz [Bridge to Higher Self]': 421,
  '963 Hz [Christ Consciousness] Vol.1': 423
};
const withBoot = true;
const cacheName = "AudioPlayerDurations";
const timeoutDuration = 5000;

const fetchConfig = async () => {
  const config = (await (await fetch(`https://core.service.elfsight.com/p/boot/?page=${location.href}&w=${widgetId}`)).json()).data.widgets[widgetId].data.settings;
  
  return config;
};

function timeFormat(time) {
  if (!time || !isFinite(time) || isNaN(time)) {
    return undefined;
  }
  const hrs = ~~(time / 3600);
  const mins = ~~((time % 3600) / 60);
  const secs = ~~time % 60;
  const formatDigit = (digit) => `${digit < 10 ? "0" : ""}${digit}`;

  if (hrs > 0) {
    return `${hrs}:${formatDigit(mins)}:${formatDigit(secs)}`;
  }

  return `${mins}:${formatDigit(secs)}`;
}

const getDuration = (link) => {
  return new Promise((resolve) => {
    const audio = new Audio();
    audio.src = link;
    
    const timeout = setTimeout(() => resolve(0), timeoutDuration);
    audio.addEventListener("loadedmetadata", () => {
      clearTimeout(timeout);
      resolve(audio.duration);
    });
  });
};

const waitForElements = (selector, root = document) => new Promise(res => {
  let i = 0;

  const check = () => {
    const components = root.querySelectorAll(selector);

    if (components.length) {
      res([...components]);
    } else if (i !== 50) {
      setTimeout(check, 100);
      i++;
    }
  };

  check();
});

const addDuration = (item, duration) => {
  const durationContainer = item.querySelector("[class*='PlaylistItem__AdditionalInfoContainer-sc']");
  const durationLabel = document.createElement('div');
  durationLabel.textContent = timeFormat(duration);
  durationLabel.id = 'es-custom-duration';
  
  durationContainer.append(durationLabel);
};

const addDurations = () => {
  waitForElements("[class*='PlaylistItem__PlaylistItemInfoContainer-sc']").then(async (items) => {
    const titles = items.map(item => item.querySelector("[class*='PlaylistItem__Title-sc']").textContent.trim());
    
    const localCache = JSON.parse(localStorage.getItem(cacheName) ?? "{}");
    const fullCache = Object.assign(initialCache, localCache);
    
    let durations = titles.map(title => fullCache[title]);
    let cacheMiss = false;
    durations.forEach((duration, i) => {
      if (!duration) {
        cacheMiss = true;
        return;
      }
      
      addDuration(items[i], duration);
    });
    
    if (cacheMiss && withBoot) {
      const config = await fetchConfig();
  
      durations = await Promise.all(durations.map(async (duration, i) => {
        if (duration) {
          return duration;
        }
        
        const link = config.source.find(item => item.title.trim() === titles[i]).link.url;
        const fetchedDuration = await getDuration(link);
        fullCache[titles[i]] = fetchedDuration;
        addDuration(items[i], fetchedDuration);
        
        return fetchedDuration;
      }));
    }
    
    localStorage.setItem(cacheName, JSON.stringify(fullCache));
  });
};

addDurations();

waitForElements("[class*='Shuffle__ShuffleComponent-sc']").then(shuffle => {
  shuffle[0].addEventListener("click", () => {
    const durations = [...document.querySelectorAll("#es-custom-duration")];
    durations.forEach(duration => duration.remove());
    
    setTimeout(() => addDurations(), 100);
  });
});

And this code should be added to the Custom CSS field on the Style tab of your widget’s settings:

#es-custom-duration {
  font-size: 13px;
  line-height: 1.2;
  text-align: right;
  padding-left: 0px;
  opacity: 0.7;
  width: 50px;
  margin: auto;
}

Test it out and let me know how it worked :slightly_smiling_face: