Fixing Timecode Links On FreeSound

by Editorial Team 35 views
Iklan Headers

Hey guys! Ever stumble upon a cool sound on FreeSound and wished you could jump straight to a specific part? Well, that's where timecode links come in! They let you click on a timestamp like #00:01:12 and instantly start listening from that point. But, as some users have noticed, the current implementation on FreeSound has a little hiccup: it only correctly handles timestamps with minutes and seconds (like #0:36) and not those with hours included (like #1:01:01). In this article, we're diving into how to fix this, so you can navigate sounds with ease, no matter how long they are! We will explore the problem in freesound/static/bw-frontend/src/pages/sound.js's findTimeLinksAndAddEventListeners, the existing code, and how we can make the necessary adjustments to support hours in the timestamps. Let's get started!

The Problem: Limited Timecode Parsing

The issue lies within the findTimeLinksAndAddEventListeners function in the sound.js file. This function is responsible for identifying timecode elements (those timestamps formatted like #mm:ss or #hh:mm:ss) within the sound descriptions and converting them into clickable links. When you click these links, the audio player should jump to the specified time. However, the original code, as it currently stands, has a limitation. It only correctly interprets timestamps that include minutes and seconds, but it doesn't parse timestamps that include hours. For instance, clicking on #01:01:99 should work, but for timestamps using the hour, minute, and second format, such as #1:01:01, the current implementation might not function correctly.

This limitation can be quite inconvenient, especially when dealing with longer audio files where hour markers are essential for navigating through the content. For example, if you are working with a sound that is several hours long, not being able to directly jump to the specific point you are interested in can be frustrating. So, let's explore how we can fix this. We want to ensure that all timestamps, regardless of their format (whether they include hours, minutes, or seconds), are correctly parsed and linked to the audio player's seek function. This is essential for a smooth and efficient user experience on FreeSound, enabling users to easily navigate to the desired segments of audio files. We will delve into the existing code to pinpoint where the changes need to be made, ensuring the functionality of timecode links and their accurate interpretation of timestamps.

Where the Code Falls Short

The existing code focuses primarily on parsing timecodes in the format of minutes and seconds. It correctly identifies the time, converts it into seconds, and then uses that value to seek the audio player to the correct position. However, the method used to split the timecode string (using the colon as a delimiter) isn’t sophisticated enough to handle timecodes that include hours. Specifically, the original implementation does not account for the additional element (hours) when splitting and converting the timestamp into a total number of seconds. This causes the function to misinterpret the time value when it encounters an hour marker within the timecode, preventing accurate seeking. To illustrate, imagine a sound that has the following timecode #1:30:15. The current code would split this into three parts: 1, 30, and 15. The code would then convert the time incorrectly, and the sound would not play at the expected location. The code also does not include logic for parsing and correctly adding the hour portion to the total seconds, resulting in playback errors. This results in the user being unable to jump to the intended point in the audio, impacting the usability of the platform.

The Solution: Updating the Code

The fix involves modifying the findTimeLinksAndAddEventListeners function to correctly parse timecodes with hours. The goal is to ensure the code can handle timestamps in the formats #mm:ss and #hh:mm:ss. Here’s a revised version of the code that incorporates these changes, including details on how to use it, and what it does. This version uses a regular expression to match different timecode formats and updates the time conversion logic to correctly account for hours, minutes, and seconds.

const findTimeLinksAndAddEventListeners = element => {
    // Replace timestamps of pattern #m:ss, #h:m:s, etc. (e.g. #0:36, #0:0:1, #01:01:99) for anchor with a specific class and play icon
    const playIconHtml = '<span class="bw-icon-play" style="font-size:70%"></span>';
    element.innerHTML = element.innerHTML.replaceAll(/#\d+(?::\d+)+/g, '<a class="play-at-time" href="javascript:void(0);">' + playIconHtml + '{{content}}amp;</a>');
    element.innerHTML = element.innerHTML.replaceAll(playIconHtml + '#', playIconHtml);

    // Add listener events to each of the created anchors
    Array.from(element.getElementsByClassName('play-at-time')).forEach(playAtTimeElement => {
        playAtTimeElement.addEventListener('click', (e) => {
            if (!e.altKey){
                const parts = playAtTimeElement.innerText.split(':').map(n => parseInt(n, 10));
                const seconds = parts.reverse().reduce((sum, val, idx) => sum + val * Math.pow(60, idx), 0);
                playAtTime(audioElement, seconds);
            } else {
                audioElement.pause();
            }
        });
    });
};

Breakdown of Changes

Let’s break down the key changes and how they work.

  1. Regular Expression: The core of the enhancement lies in the updated regular expression used to find the timecode strings within the sound description. The updated regex /#\d+(?::\d+)+/g matches timecodes that can include hours, minutes, and seconds. The \d+ ensures that it captures one or more digits, and (?::\d+)+ allows for one or more occurrences of the colon followed by digits, enabling the matching of formats like #hh:mm:ss. This regex is designed to correctly recognize all valid timecode formats.
  2. Splitting and Conversion: The conversion logic correctly splits the timecode string by the colon. It maps each part to an integer using parseInt(n, 10), which is crucial for handling numbers properly. We then reverse the array of time parts to process them from seconds to hours. The reduce() function then adds the values by correctly using the powers of 60 for the calculations (seconds, minutes, and hours). This precise approach ensures that any given timecode is correctly converted into the number of seconds.
  3. Event Listeners: The event listeners remain the same, ensuring that the function performs the intended function of the audio player at the target time. The event listener attached to the new links calls playAtTime(audioElement, seconds), ensuring that the audio jumps to the correct position when clicked.

Testing the Fix

To ensure our fix works, we need to test it thoroughly. Testing involves creating sounds with timestamps that include hours, minutes, and seconds and then ensuring that the links jump to the correct time. The example sounds are perfect for verifying our fix. Here’s a quick guide:

  1. Manual Testing: This involves uploading sounds with timecodes that include hours, minutes, and seconds. Verify that clicking on each timecode jumps the audio player to the correct time.
  2. Edge Case Testing: Include edge cases such as single-digit hours, minutes, and seconds, and ensure that all formats are correctly parsed. For example, sounds with timestamps like #1:05:05 and #01:5:5 should work.
  3. Functional Testing: The functional testing makes sure that the timecodes work as expected on longer audio files to ensure accurate navigation.

Alternative Approaches

While the code provided above is a good solution, there are alternative approaches you might consider to address this problem. Sometimes, tracing from the right might be a solution. Instead of splitting the timecode string from left to right, we could also start from the right and work backward, which might simplify the parsing logic and make the code easier to understand and maintain. Let’s explore some alternative approaches.

Tracing from the Right

This approach involves parsing the timecode from right to left, starting with the seconds and then moving to the minutes and hours. This could be particularly effective because you can consistently use the last element as seconds and then move backward to handle minutes and hours. Here’s a conceptual outline of how this might work:

  1. Split the String: Use the colon as a delimiter to split the timecode string from right to left, creating an array of time components.
  2. Convert Time Components: Convert the individual elements to their respective numerical values. The last element is the seconds, the second to last is minutes, and so on.
  3. Calculate Total Seconds: The seconds, minutes, and hours should be correctly combined to calculate the total number of seconds.
  4. Seek the Audio: Use the total number of seconds to seek the audio player to the correct position.

Pros and Cons of Alternative Approaches

Tracing from the right has its advantages and disadvantages. It simplifies the parsing of the time components because you start from a known position, ensuring that the last element is always the seconds. However, this approach can get complex if you have to handle varying time formats. The primary drawback of tracing from the right is that it does not handle all scenarios as effectively. This may require additional validations and the possibility of complex code, which could make it harder to maintain and debug. The key advantage is it might offer simpler logic for parsing the components. This approach would require a complete overhaul of the current implementation. It's essential to assess each approach based on readability, maintainability, and the range of timecode formats that the code needs to support.

Conclusion

By implementing the suggested code, the timecode links on FreeSound can now handle hours correctly. This update significantly improves the user experience, especially when navigating longer audio files. Remember to test the changes thoroughly to make sure everything works as expected. That's all for now, folks! Happy sound exploring!