Accessing the current playback time and setting a function to trigger upon reaching the end with THREE

I have successfully implemented a method in my Three.js app for loading, playing, and analyzing audio that is compatible with both desktop and mobile devices. I must use THREE.Audio instead of HTML5 Audio Analyser, as the latter does not work on mobile devices. However, I am encountering two issues that I cannot seem to resolve:

  • Getting the current time of the audio being played
  • Setting an onEnded function

Below is the code I am using:

function soundLoad() {
listener = new THREE.AudioListener();
audio = new THREE.Audio( listener );
audioLoader = new THREE.AudioLoader();
analyser = new THREE.AudioAnalyser( audio, 32 );
audioLoader.load( 'audio/01.mp3', function( buffer ) {
    audio.setBuffer( buffer );
    audio.setLoop( false );
    audio.setVolume( 1 );
    (function readyToGo() {
        console.log(audio.buffer.duration); // this works fine
        document.getElementById('btnPlay').addEventListener( 'click', function(){
           audio.play(); 
           setInterval(function(){
             console.log(audio.context.currentTime); // starts counting from the loading, not from the actual play
             console.log(audio.buffer.currentTime); // does not work
           }, 10);
        }, false);
        // audio.onEnded = function() { console.log(‘end’);}; 
        // audio.buffer.onEnded = function() { console.log(‘end’);};
        // audio.source.onEnded = function() { console.log(‘end’);}; // none of them work
    })();
});}

I am hopeful that there is a solution to both of these issues without needing to rely on external libraries. Thank you for any help!

Answer №1

With helpful hints from Mugen87, I have developed a concise solution to accomplish my goal - checking every frame in the render function:

Initialization

var audioPrevTime, audioCurrentTime, data;

Within the render function:

if (pause == 0){
    audioCurrentTime = audio.context.currentTime - audio.startTime + audioPrevTime;
    if (audioCurrentTime >= audio.buffer.duration){
        console.log('end song');
    }
    data = analyser.getAverageFrequency();
} else if (pause == 1){
    audioPrevTime = audioCurrentTime;
}

Overall, these few lines of code allow for the loading, playing, controlling, and analyzing of sound on both desktop and mobile devices (in my testing experience, everything works smoothly).

Answer №2

three.js does not provide access to Web Audio events, making it unadvisable to override AudioScheduledSourceNode.onended. Doing so may result in unforeseen consequences. If you require the current audio time, you will need to compute this value manually. Here is a suggested approach:

const currentTime = audio.context.currentTime - audio.startTime;

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

What methods can be utilized to reach and activate the features within the express.js module?

When creating an express app, I typically start by writing these two statements: const express = require("express"); const app = express(); The "app" object allows access to various functions within express() including get(), listen(), and use(). I' ...

What is the best way to configure Jenkins to exclude or include specific component.spec.ts files from being executed during the build

Currently, I am facing an issue while attempting to include my spec.ts files in sonarqube for code coverage analysis. However, my Jenkins build is failing due to specific spec.ts files. Is there a way to exclude these particular spec.ts files and include ...

What is the most efficient method for transforming an index into a column number that resembles that of Excel using a functional approach?

Is there a way to write a function that can produce the correct column name for a given number, like A for 1 or AA for 127? I know this question has been addressed numerous times before, however, I am interested in approaching it from a functional perspect ...

The routing feature functions properly on localhost but encounters issues on the live server

There seems to be an issue with this code. While it works perfectly on localhost, it doesn't function as expected on a live Apache server. I have already specified the homepage in the package JSON file and included an htaccess file. However, when acce ...

Pause until the existence of document.body is confirmed

Recently, I developed a Chrome extension that runs before the page fully loads by setting the attribute "run_at": "document_start". One issue I encountered is that I need to insert a div tag into the body of the webpage as soon as it is created. However, a ...

Having trouble getting Ajax to function properly with CodeIgniter

Here is the AJAX code snippet: $.ajax({ url: '<?php echo base_url(); ?>deleteRowUsingApiKey/index', //This is the current doc type: "POST", //dataType:'json', // add json datatype to get json data: {name ...

You cannot use voice_channel.join() to create a music bot in discord.js v13

As I was working on a new music command feature for my Discord bot, I encountered an issue. Whenever I try to use the command -play {url}, I keep getting an error message that says: voice_channel.join is not a function. I searched through various resource ...

Implement a JavaScript confirm dialog for a mailto hyperlink

Is there a way in javascript to automatically detect mailto links on the page and prompt a confirmation dialog when clicked by a user? I came across a method on this website for displaying an alert message. My knowledge of javascript is very basic. It&ap ...

Transmit variables to ajax callback function

I'm a beginner when it comes to AJAX, so I'm using 'Jquery Form' to help me out. I'm trying to pass the entry and path variables to the success callback. var optionsUpdate = { data: { entry: entry, path: path }, success: ...

The import of a package installed from git is not possible with Webpack

After forking a package in git and making my changes, I proceeded to install it using the following command in my terminal: npm install --save git+https://github.com/hayk94/ddp.js.git Once installed, I attempted to import the package in my code with this ...

Using EJS to Render a Function Expression?

Has anyone been able to successfully render a function call in express using EJS? Here's what I've tried so far: res.render("page", { test: test() }); Can someone confirm if this is possible, or provide guidance on how to call a function fr ...

Activate the popup for sharing or bookmarking by clicking on a regular link

I am currently utilizing a Share/Bookmark script: <div class="singles-right"> <a href="#" class="bookmark"></a> <script type="text/javascript" src="http://static.addinto.com/ai/ai2_bkmk.js"></script> <a href="#" clas ...

I encountered an Angular error that is preventing me from updating and uploading images to my Firebase Storage because it is unable to locate the storage bucket

Hey there fellow developers! I'm currently working on a simple Angular app that allows users to upload images to a gallery. However, I've encountered an issue while trying to upload the images to Firebase Storage. I keep getting an error mentioni ...

Verify the level of opacity in the image

I'm working on a website that allows users to upload PNG images and save them. However, before they can save the image, I need to check if it contains transparency. Is there a way to determine if an image is not 24-bit using JavaScript? <img id= ...

Leveraging PHP for populating JavaScript variables

I am currently working on populating a Drop-Down menu from a csv file stored on a network share. So far, I have successfully managed to populate the options when the file is in the wwwroot folder. However, I am now encountering an issue with referencing a ...

internet explorer causing issues with .html() method

My webpage is encountering an issue with Internet Explorer when using AJAX to retrieve data and the .html() function to change the content of a div. While Firefox, Google Chrome, Safari, and Opera work fine, IE 7, 8, and 9 do not respond to the .html() fu ...

Error Occurred while Uploading Images using Ajax HTML Editor with JSON Data

I am facing an issue with my AJAX HtmlEditorExtender, specifically when trying to upload an image. The error message I receive is as follows: JavaScript runtime error: Sys.ArgumentException: Cannot de-serialize. The data does not correspond to valid JSON. ...

Displaying random divs and subsequently animating them downwards using JavaScript

I am in the process of creating a random appearing div that then falls down. Here is the code I have so far: $(document).ready(function(){ $('#test').animate({top: 80 + '%'},900); }); <div id="test" style="background:#98bf21;heigh ...

"Interacting with the ng-keypress event causes the page to smoothly scroll

As a newcomer to angularjs, I am trying to figure out why my component (which simulates a "checkbox" using fontawesome icons) causes the page to scroll down when the user presses the space key. Here is a snippet of my component : ugoFmk.component(' ...

Determining the optimal times to utilize traditional loops instead of array helpers

After writing in Javascript for some time, I've become quite comfortable with using array helpers. However, there have been moments where traditional for loops seem more practical and easier to work with compared to array helpers. Can you provide me w ...